Requires a Nest thermostat, a wireless thermometer and a Domoticz-controllable plug/socket for your heater.
The user constants should be self explanatory...
Caveats:
1) Your electric heater needs to be powerful enough - eg. if your Nest switches to 20deg at 6:15 in order to get the main house upto temperature by 7:00 and your heater isn't very powerful then the room may not reach 20deg by 7:00.
2)You can override the setpoint at any time by creating a file /tmp/HEATER_OVERRIDE containing the new setpoint (must be one decimal place, eg. 20.5). I added this as a workaround for (1) until I buy a more powerful heater

3) default behaviour is if the thermostat has stopped transmitting then we turn off the heater and wait until it's back. This beahviour may not suit everyone.
4) the check_temp_sensor function is a standalone script on my system (it's used for other things too); I've added it as a function to the script without testing but it should just work.
Hope somebody finds this useful

Code: Select all
#!/bin/bash
#version 2 - uses the nest setpoint and relies on the master switch being on
#a timer to determine when it's running. Does not heat when nest is in away mode
###################################################################################
###################################################################################
#user constants
#domoticz login
muser="XXXX"
mpass="XXXX"
#masterswitch - dummy switch in domoticz, switches off heater and pauses this script when set to Off
maswitch=157
#thermometer device ID in domoticz
thermdev=153
#heater device ID
heaterid=65
#nest temperature setpoint device id
nestpoint=15
#nest away device id
nestdev=17
#honour nest away - 1 for keep running with the nest away temperature setting,
#0 for shutdown heater and pause until nest says home
honournestaway=0
###################################################################################
###################################################################################
function check_temp_sensor {
#args: <deviceID> [allowed age]
failrc=1
if [ $# -ne 1 ] && [ $# -ne 2 ]
then
exit $failrc
fi
if [ $# -eq 2 ]
then
allowedage=$2
else
allowedage=3600
fi
returnme=UNTRUSTED
wget "http://$muser:$mpass@localhost/json.htm?type=devices&rid=$1" -q -O /tmp/tempscript.out 2> /dev/null > /dev/null
if [ $? -eq 0 ]
then
therval=`cat /tmp/tempscript.out | grep "\"Data\"" | sed -e "s/^.*: \"//" -e "s/ .*//"`
lastupdate=`cat /tmp/tempscript.out | grep "\"LastUpdate\"" | sed -e "s/^.*: \"//" -e "s/\",$//"`
updateepoch=`date --date="$lastupdate" +%s`
interval=$((`date +%s` - $updateepoch))
if [ $interval -lt $allowedage ]
then
returnme=$therval
failrc=0
fi
fi
echo $returnme
exit $failrc
}
function getswstatus {
wget "http://$muser:$mpass@localhost/json.htm?type=devices&rid=$1" -q -O - 2> /dev/null | grep "\"Status\"" | sed -e "s/^.*: \"//" -e "s/\",//"
}
function setswitch {
#args devID On/Off
wget "http://$muser:$mpass@localhost/json.htm?type=command¶m=switchlight&idx=$1&switchcmd=$2" -q -O - 2> /dev/null > /dev/null
#resend command after 7s to make sure it gets through
sleep 7
wget "http://$muser:$mpass@localhost/json.htm?type=command¶m=switchlight&idx=$1&switchcmd=$2" -q -O - 2> /dev/null > /dev/null
#always sleep 40s after switching to avoid rapid on/off
sleep 40
}
#get initial state of heater
if [ "`getswstatus $heaterid`" == "On" ]
then
currentstate=1
else
currentstate=0
fi
sleepintervals=300
setvar=0
prev1temp=0
onoverride=0
echo "======================================="
echo "`date +"%d%m%y %H:%M"` `echo $0 | sed -e "s/^.*\///"` is starting"
echo "======================================="
echo "`date +"%d%m%y %H:%M"` Initial state HEATER: `echo $currentstate | sed -e "s/1/On/" -e "s/0/Off/"` NESTAWAY: `getswstatus $nestdev` HONOURNESTAWAY: `echo $honournestaway | sed -e "s/1/On/" -e "s/0/Off/"`"
while true
do
if [ "`getswstatus $maswitch`" == "Off" ]
then
#explicitly send an off instead of checking where were at so the switch acts as a master shutdown
#regarless of if someone has been manually changing the heater in domoticz
currentstate=0
echo "`date +"%d%m%y %H:%M"` Master switch is off, sleeping"
setswitch $heaterid Off
sleep $sleepintervals
while [ "`getswstatus $maswitch`" == "Off" ]
do
sleep $sleepintervals
done
echo "`date +"%d%m%y %H:%M"` Master switch is back ON, resuming"
fi
#chose to shutdown the heat and wait if nest in away mode, or carry
#on with heating using the nest-away temperature
if [ $honournestaway -eq 0 ]
then
if [ "`getswstatus $nestdev`" == "On" ]
then
echo -n "`date +"%d%m%y %H:%M"` Detected Nest Away mode - "
#shut everything down until nestaway is Off
if [ $currentstate -eq 1 ]
then
echo -n "shutting down heater and "
currentstate=0
#send off command
setswitch $heaterid Off
fi
echo "sleeping"
#sleep and wait until nestaway is Off
sleep $sleepintervals
while [ "`getswstatus $nestdev`" == "On" ]
do
sleep $sleepintervals
done
echo "`date +"%d%m%y %H:%M"` Detected Nest Home mode - resuming"
fi
fi
oldsetvar=$setvar
if [ -r /tmp/HEATER_OVERRIDE ]
then
setpoint=`cat /tmp/HEATER_OVERRIDE`
onoverride=1
else
setpoint=`wget "http://$muser:$mpass@localhost/json.htm?type=devices&rid=$nestpoint" -q -O - 2> /dev/null | grep "^ *\"SetPoint\"" | sed -e "s/^.*: \"//" -e "s/\",//"`
if [ $onoverride -eq 1 ]
then
echo "`date +"%d%m%y %H:%M"` OVERRIDE removed, going back to Nest setpoint"
onoverride=0
fi
fi
setvar=`echo $setpoint | sed -e "s/\.//"`
if [ $setvar -ne $oldsetvar ]
then
if [ $onoverride -eq 1 ]
then
echo "`date +"%d%m%y %H:%M"` OVERRIDE Setpoint set to $setpoint"
else
echo "`date +"%d%m%y %H:%M"` Setpoint set to $setpoint"
fi
fi
currtemp=`/home/pi/check_temp_sensor $thermdev 1800`
if [ "$currtemp" != "UNTRUSTED" ]
then
if [ "`echo $currtemp | sed -e 's/\.//'`" -lt $setvar ]
then
if [ $currentstate -eq 0 ]
then
echo "`date +"%d%m%y %H:%M"` under temp, switching ON - setpoint $setpoint currenttemp $currtemp"
currentstate=1
#send on command
setswitch $heaterid On
prev1temp=$currtemp
onitercount=0
fi
else
if [ $currentstate -eq 1 ]
then
echo "`date +"%d%m%y %H:%M"` over temp, switching off - setpoint $setpoint currenttemp $currtemp"
currentstate=0
#send off command
setswitch $heaterid Off
fi
fi
else
#untrusted thermometer - shutdown?
if [ $currentstate -eq 1 ]
then
echo "`date +"%d%m%y %H:%M"` UNTRUSTED thermometer - shutting down heater until it recovers"
currentstate=0
#send off command
setswitch $heaterid Off
while [ "`/home/pi/check_temp_sensor $thermdev 1800`" == "UNTRUSTED" ]
do
sleep $sleepintervals
done
echo "`date +"%d%m%y %H:%M"` thermometer is now transmitting, resuming"
fi
fi
sleep $sleepintervals
#check state var reflects reality
if [ "`getswstatus $heaterid`" == "On" ]
then
if [ $currentstate -eq 0 ]
then
echo "`date +"%d%m%y %H:%M"` Heater unexpectedly ON in Domoticz, switching off"
setswitch $heaterid Off
fi
else
if [ $currentstate -eq 1 ]
then
echo "`date +"%d%m%y %H:%M"` Heater unexpectedly OFF in Domoticz, switching on"
setswitch $heaterid On
fi
fi
done