I built a temp alarm for my big freezer after I lost about $1k worth of meat and other frozen foods due to a failed thermostat. If the thermostat fails again, I'll build an arduino based one with a screen to set temperatures and a relay to turn it on and off.
I modified the example sketch for the temp sensor to support a buzzer and a mute button. I did this because my ESP8266 gateway doesn't seem to be very reliable, and neither do notifications on the Vera. At least this way, someone will hear it beeping if there's a problem. The device uses a button with a pulldown resistor to ensure that the pin stays LOW when the button is not pressed. When the temperature is >= to the alarmTemp, alarmState goes to true which sounds the buzzer and sets the SLEEP_TIME down to 1 second. If you press the button, it will mute the alarm. The alarmState and mute automatically resets when the temp goes below alarmReset. Note that the temps you set in the sketch will either be F or C depending on what your controller is set up for. I'm using F, and usually keep my freezer at -20F. So I set my alarmTemp to 10F and reset at 0F. If you're using C, you'll want to change this appropriately.
I'm always amazed that you can build stuff like this for like $5.
Note that drilling holes in a modern freezer can be a risky endeavor, because the hot side of the compressor lines run beneath the sides and/or back of the freezer. They aren't exposed anymore. I used my Seek thermal camera to determine exactly where the lines were before I drilled and used a dry erase marker to mark them.
Code below,
Photos here - https://goo.gl/photos/4inkTh6GVhCEupLa8
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* DESCRIPTION
*
* Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller
* http://www.mysensors.org/build/temp
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
#include <SPI.h>
#include <MySensors.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
#define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected
#define BUZZER 5
const int buttonPin = 7; // Pin where the mute button is connected
#define MAX_ATTACHED_DS18B20 16
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
float lastTemperature[MAX_ATTACHED_DS18B20];
int numSensors=0;
int buttonState = 0;
bool alarmState = false;
bool muteAlarm = false;
float alarmTemp = 10; // Temperature where our alarm goes off. Use F if your gateway is imperial, C if metric
float alarmReset = 0; // Temperature where the alarm resets automatically
bool receivedConfig = false;
bool metric = true;
// Initialize temperature message
MyMessage msg(0,V_TEMP);
void before()
{
// Startup up the OneWire library
sensors.begin();
}
void setup()
{
// requestTemperatures() will not block current thread
sensors.setWaitForConversion(false);
pinMode(BUZZER, OUTPUT);
pinMode(buttonPin, INPUT);
}
void presentation() {
// Send the sketch version information to the gateway and Controller
sendSketchInfo("Temperature Sensor", "1.1");
// Fetch the number of attached temperature sensors
numSensors = sensors.getDeviceCount();
// Present all sensors to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
present(i, S_TEMP);
}
}
void loop()
{
if (alarmState == true && muteAlarm == false) {
digitalWrite(BUZZER, HIGH);
delay(1000);
digitalWrite(BUZZER,LOW);
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH and we mute the alarm
if (buttonState == HIGH) {
muteAlarm = true;
}
}
// Fetch temperatures from Dallas sensors
sensors.requestTemperatures();
// query conversion time and sleep until conversion completed
int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
// sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
sleep(conversionTime);
// Read temperatures and send them to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
// Fetch and round temperature to one decimal
float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
if (alarmState == false && temperature >= alarmTemp) {
alarmState = true;
SLEEP_TIME = 1000; // Set our sleep from 30 seconds to 1 second to facilitate buzzer and intensive monitoring
}
if (alarmState == true && temperature <= alarmReset) {
alarmState = false;
muteAlarm = false;
SLEEP_TIME = 30000;
}
// Only send data if temperature has changed and no error
#if COMPARE_TEMP == 1
if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
#else
if (temperature != -127.00 && temperature != 85.00) {
#endif
// Send in the new temperature
send(msg.setSensor(i).set(temperature,1));
// Save new temperatures for next compare
lastTemperature[i]=temperature;
}
}
sleep(SLEEP_TIME);
}