Yes these are older thermostats, but I managed to get hold of one for about £20 or $28 and needed a new underfloor heating thermostat anyway. This setup is based on Rules and Scripts, works fine with Openhab 2.5.x and should work with Openhab 3 fine.
Its based off work people did 3+ years ago, but that was only partially completed/working, so Ive now fully completed it… and whilst these are older devices, ebay seems to have quite a few available and Ive done so much work, I thought I should share. I also believe there are other brands/makes of WiFi Thermostats that use this protocol/communication method (have a hunt on the Openhab forums for posts from around 2015-2018).
All these features work. There are some additional features I didn’t implement (Holiday scheduler etc), but those could be built off the work Ive done.
Im running this on Ubuntu, I would think you could convert it to Windows (its just the scripts you need to convert, not the rules/sitemap) and it looks something like the following:
Front Page
Settings
Scheduling
Feature wise this offers:
- Change the current temp setting (it will change the temp back next time a scheduled change occurs).
- Boost the temperature for a period of time.
- Lock and unlock the Thermostats screen/buttons
- Turn on holiday mode, which just keeps the thermostat set at Anti-Frost (disables the schedule)
- Set the heating schedule for Monday-Friday and Saturday-Sunday (5/2 as its known).
- Get the basic system info
- Set the Anti-Frost temperature
- The time on the thermostat will sync once a day with your server (at 3am).
- The settings will be collected from the Thermostat every 3 minutes, but you can change that if needed in the Time Cron at the top of the Rules file.
To set this up, you will need to:
- Configure the IP address/username etc on your Heatmiser PRT thermostat.
- Follow this guide https://github.com/thoukydides/heatmiser-wifi/wiki/InstallationBasic from top to bottom (takes about 5 minutes and is copy/paste) NO NEED TO SETUP THE WEB INTERFACE ETC - just get as far as testing/running this line ~/heatmiser-wifi-read-only/bin/heatmiser.pl
- Once you’ve followed that guide you will need to edit your HOSTS file on your openhab server and put in a static entry called heatmiser and pointing to the IP address of your thermostat. Typically this file is /etc/hosts and an entry would look like 192.168.1.10 heatmiser
- Create a text file /etc/heatmiser.conf. In there, you will add your thermostat hostname and the PIN setup on the thermostat
nginx
HOST heatmiser
PIN 1234
-
VERY IMPORTANT NOTE. In the examples I will give below, the OpenHab server’s user account is called openhab. If you wish to or have used a different named user account, you will need to change the scripts/rules to point to the correct HOME folder location, by changing openhab to the name of the account you have used.
-
Create a folder called openhabscripts in /home/openhab/heatmiser-wifi-read-only/ so that a full path to this folder would be /home/openhab/heatmiser-wifi-read-only/openhabscripts/
-
In the openhabscripts folder you will create the following files:
hw_frostprotect.sh (contents below)
a='{"frostprotect":{"target":'
b='}}'
echo $a$1$b
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl $a$1$b
hw_hold.sh
a='{"heating":{"hold":'
b='}}'
echo $a$1$b
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl $a$1$b
hw_holidayaway.sh
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl '{"runmode":"frost"}'
hw_holidayhome.sh
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl '{"runmode":"heating"}'
hw_keylock.sh
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl {\"keylock\":$1}
hw_schedule.sh
a='{"comfort":[[{"target":'
b=',"time":"'
c=':'
d=':00"},{"target":'
f=':00"}],[{"target":'
g=':00"}]]}'
echo $a$1$b$2$c$3$d$4$b$5$c$6$d$7$b$8$c$9$d${10}$b${11}$c${12}$f${13}$b${14}$c${15}$d${16}$b${17}$c${18}$d${19}$b${20}$c${21}$d${22}$b${23}$c${24}$g
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl $a$1$b$2$c$3$d$4$b$5$c$6$d$7$b$8$c$9$d${10}$b${11}$c${12}$f${13}$b${14}$c${15}$d${16}$b${17}$c${18}$d${19}$b${20}$c${21}$d${22}$b${23}$c${24}$g
hw_setback.sh
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl {\"enabled\": $1 }
hw_settemp.sh
a='{"heating":{"target":'
b='}}'
echo $a$1$b
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl $a$1$b
hw_status.sh
/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_json.pl
As mentioned, change the word openhab in those files to match your own users home folder location.
-
For each of those files you have created, you will need to mark them as read/write/executable. So on Linux/Ubuntu you would, at a terminal window in the openhabscripts folder, perform a sudo chmod +rwx filename.sh (for each file)
-
You will need to copy the following into your Openhab Items file:
//****************
//** Heatmeiser **
//****************
//Type Item Name Name on Sitemap Icon Used Group
Group gSched "Heatmiser Scheduling Group"
String HW_TemperatureInternal "Room/Floor Temperature [%s C]" <heatmiser>
String HW_HeatingTarget "Set Temperature [%d C]" <settemp>
Switch HW_Keylock "Button/Screen Lock[]" <screenlock>
String HW_KLS "Button/Screen Lock[%s]"
//Weekdays Schedule Variables
String HW_01_WWDTemp "WAKE - Temperature [%d C]" <settemp> (gSched)
String HW_02_WWDHour "WAKE - Hour [%d]" <time> (gSched)
String HW_03_WWDMinute "WAKE - Minute [%d]" <time> (gSched)
String HW_04_LWDTemp "LEAVE - Temperature [%d C]" <settemp> (gSched)
String HW_05_LWDHour "LEAVE - Hour [%d]" <time> (gSched)
String HW_06_LWDMinute "LEAVE - Minute [%d]" <time> (gSched)
String HW_07_RWDTemp "RETURN - Temperature [%d C]" <settemp> (gSched)
String HW_08_RWDHour "RETURN - Hour [%d]" <time> (gSched)
String HW_09_RWDMinute "RETURN - Minute [%d]" <time> (gSched)
String HW_10_SWDTemp "SLEEP - Temperature [%d C]" <settemp> (gSched)
String HW_11_SWDHour "SLEEP - Hour [%d]" <time> (gSched)
String HW_12_SWDMinute "SLEEP - Minute [%d]" <time> (gSched)
//Weekend Schedule Variables
String HW_13_WWETemp "Temperature [%d C]" <settemp> (gSched)
String HW_14_WWEHour "Hour [%d]" <time> (gSched)
String HW_15_WWEMinute "Minute [%d]" <time> (gSched)
String HW_16_LWETemp "Temperature [%d C]" <settemp> (gSched)
String HW_17_LWEHour "Hour [%d]" <time> (gSched)
String HW_18_LWEMinute "Minute [%d]" <time> (gSched)
String HW_19_RWETemp "Temperature [%d C]" <settemp> (gSched)
String HW_20_RWEHour "Hour [%d]" <time> (gSched)
String HW_21_RWEMinute "Minute [%d]" <time> (gSched)
String HW_22_SWETemp "Temperature [%d C]" <settemp> (gSched)
String HW_23_SWEHour "Hour [%d]" <time> (gSched)
String HW_24_SWEMinute "Minute [%d]" <time> (gSched)
Switch HW_SetHoliday "Away/Holiday Mode" <awaymode>
Number HW_TempHoldDuration "Boost For " <time>
String HW_TempHoldTemperature "Boost Temperature [%d C]" <fire>
String HW_Heatingholdoff "Boost Remaining [%s]" <fire>
String HW_FrostprotectEnabled "Frost protection enabled [%s]" <snowflake>
String HW_FrostprotectTarget "Frost protection Temp [%d C]" <snowflake>
String HW_ProductModel "Model [%s]" <heatmiser>
String HW_ProductVendor "Vendor [%s]" <heatmiser>
String HW_ProductVersion "Firmware Version [%s]" <heatmiser>
String HW_Progmode "Day Program Mode [%s]" <heatmiser>
String HW_Sensors "Sensors in use [%s]" <heatmiser>
String HW_DegorF "Temp in C of F [%s]" <heatmiser>
String HW_MF1 "WAKE - Set Temp/Time [%s]" <calendar>
String HW_MF2 "LEAVE - Set Temp/Time [%s]" <calendar>
String HW_MF3 "RETURN - Set Temp/Time [%s]" <calendar>
String HW_MF4 "SLEEP - Set Temp/Time [%s]" <calendar>
String HW_WE1 "WAKE - Set Temp/Time [%s]" <calendar>
String HW_WE2 "LEAVE - Set Temp/Time [%s]" <calendar>
String HW_WE3 "RETURN - Set Temp/Time [%s]" <calendar>
String HW_WE4 "SLEEP - Set Temp/Time [%s]" <calendar>
- Copy the following into your Sitemap:
Frame label="Monday to Friday Schedule" {
Text item=HW_MF1 valuecolor=["blue"]
Setpoint item=HW_01_WWDTemp minValue=0 maxValue=50 step=1
Selection item=HW_02_WWDHour mappings=[00="00", 01="01", 02="02", 03="03", 04="04", 05="05", 06="06", 07="07", 08="08", 09="09", 10="10", 11="11", 12="12", 13="13", 14="14", 15="15", 16="16", 17="17", 18="18", 19="19", 20="20", 21="21", 22="22", 23="23"]
Selection item=HW_03_WWDMinute mappings=[00="00", 30="30"]
Text item=HW_MF2 valuecolor=["blue"]
Setpoint item=HW_04_LWDTemp minValue=0 maxValue=50 step=1
Selection item=HW_05_LWDHour mappings=[00="00", 01="01", 02="02", 03="03", 04="04", 05="05", 06="06", 07="07", 08="08", 09="09", 10="10", 11="11", 12="12", 13="13", 14="14", 15="15", 16="16", 17="17", 18="18", 19="19", 20="20", 21="21", 22="22", 23="23"]
Selection item=HW_06_LWDMinute mappings=[00="00", 30="30"]
Text item=HW_MF3 valuecolor=["blue"]
Setpoint item=HW_07_RWDTemp minValue=0 maxValue=50 step=1
Selection item=HW_08_RWDHour mappings=[00="00", 01="01", 02="02", 03="03", 04="04", 05="05", 06="06", 07="07", 08="08", 09="09", 10="10", 11="11", 12="12", 13="13", 14="14", 15="15", 16="16", 17="17", 18="18", 19="19", 20="20", 21="21", 22="22", 23="23"]
Selection item=HW_09_RWDMinute mappings=[00="00", 30="30"]
Text item=HW_MF4 valuecolor=["blue"]
Setpoint item=HW_10_SWDTemp minValue=0 maxValue=50 step=1
Selection item=HW_11_SWDHour mappings=[00="00", 01="01", 02="02", 03="03", 04="04", 05="05", 06="06", 07="07", 08="08", 09="09", 10="10", 11="11", 12="12", 13="13", 14="14", 15="15", 16="16", 17="17", 18="18", 19="19", 20="20", 21="21", 22="22", 23="23"]
Selection item=HW_12_SWDMinute mappings=[00="00", 30="30"]
}
Frame label="Weekend Schedule" {
Text item=HW_WE1 valuecolor=["blue"]
Setpoint item=HW_13_WWETemp minValue=0 maxValue=50 step=1
Selection item=HW_14_WWEHour mappings=[00="00", 01="01", 02="02", 03="03", 04="04", 05="05", 06="06", 07="07", 08="08", 09="09", 10="10", 11="11", 12="12", 13="13", 14="14", 15="15", 16="16", 17="17", 18="18", 19="19", 20="20", 21="21", 22="22", 23="23"]
Selection item=HW_15_WWEMinute mappings=[00="00", 30="30"]
Text item=HW_WE2 valuecolor=["blue"]
Setpoint item=HW_16_LWETemp minValue=0 maxValue=50 step=1
Selection item=HW_17_LWEHour mappings=[00="00", 01="01", 02="02", 03="03", 04="04", 05="05", 06="06", 07="07", 08="08", 09="09", 10="10", 11="11", 12="12", 13="13", 14="14", 15="15", 16="16", 17="17", 18="18", 19="19", 20="20", 21="21", 22="22", 23="23"]
Selection item=HW_18_LWEMinute mappings=[00="00", 30="30"]
Text item=HW_WE3 valuecolor=["blue"]
Setpoint item=HW_19_RWETemp minValue=0 maxValue=50 step=1
Selection item=HW_20_RWEHour mappings=[00="00", 01="01", 02="02", 03="03", 04="04", 05="05", 06="06", 07="07", 08="08", 09="09", 10="10", 11="11", 12="12", 13="13", 14="14", 15="15", 16="16", 17="17", 18="18", 19="19", 20="20", 21="21", 22="22", 23="23"]
Selection item=HW_21_RWEMinute mappings=[00="00", 30="30"]
Text item=HW_WE4 valuecolor=["blue"]
Setpoint item=HW_22_SWETemp minValue=0 maxValue=50 step=1
Selection item=HW_23_SWEHour mappings=[00="00", 01="01", 02="02", 03="03", 04="04", 05="05", 06="06", 07="07", 08="08", 09="09", 10="10", 11="11", 12="12", 13="13", 14="14", 15="15", 16="16", 17="17", 18="18", 19="19", 20="20", 21="21", 22="22", 23="23"]
Selection item=HW_24_SWEMinute mappings=[00="00", 30="30"]
}
}
Text label="System Info" icon="gears" {
Frame label="System Info" {
Text item=HW_ProductVendor
Text item=HW_ProductModel
Text item=HW_ProductVersion
}
Frame {
Text item=HW_Progmode
Text item=HW_Sensors
Text item=HW_DegorF
}
Frame {
Text item=HW_FrostprotectEnabled
Setpoint item=HW_FrostprotectTarget minValue=10 maxValue=20 step=1
}
}
}
- Copy the following into Rules file and if needed, change the word openhab for your correct user account’s home folder path.
NOTE: You may want to edit HW_TemperatureInternal.postUpdate(transform(“JSONPATH”, “$.heatmiser.temperature.internal”, HW_Status)) in the rules file, depending on what temp sensor you are using. internal will monitor the thermostats built in temp sensor, floor will monitor a floor heating sensor and remote will monitor a remote temp probe. Obviously you can build your own items/sitemap/rule to monitor 1 to all 3 as you need. The rule below is set to monitor the internal sensor.
import java.util.concurrent.locks.ReentrantLock
var String strCommand = ""
val ReentrantLock lock1 = new ReentrantLock
//****************************************
//*** Collect Data from the Thermostat ***
//****************************************
rule "Initialize Thermostat and schedule 2 min data collection"
when
System started or
Time cron "0 0/3 * * * ?"
then{
// Get Full State of thermostat periodically, every 5 minutes, and initially at system start
var String HW_Status = executeCommandLine("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_status.sh",3000)
// Collect read only settings
HW_ProductModel.postUpdate(transform("JSONPATH", "$.heatmiser.product.model", HW_Status))
HW_ProductVersion.postUpdate(transform("JSONPATH", "$.heatmiser.product.version", HW_Status))
HW_ProductVendor.postUpdate(transform("JSONPATH", "$.heatmiser.product.vendor", HW_Status))
HW_FrostprotectEnabled.postUpdate(transform("JSONPATH", "$.heatmiser.frostprotect.enabled", HW_Status))
// Collect read/write settings
HW_HeatingTarget.postUpdate(transform("JSONPATH", "$.heatmiser.heating.target", HW_Status))
HW_TemperatureInternal.postUpdate(transform("JSONPATH", "$.heatmiser.temperature.internal", HW_Status))
HW_Progmode.postUpdate(transform("JSONPATH", "$.heatmiser.config.progmode", HW_Status))
HW_Sensors.postUpdate(transform("JSONPATH", "$.heatmiser.config.sensor", HW_Status))
HW_DegorF.postUpdate(transform("JSONPATH", "$.heatmiser.config.units", HW_Status))
HW_FrostprotectTarget.postUpdate(transform("JSONPATH", "$.heatmiser.frostprotect.target", HW_Status))
HW_Heatingholdoff.postUpdate(transform("JSONPATH", "$.heatmiser.heating.hold", HW_Status))
HW_KLS.postUpdate(transform("JSONPATH", "$.heatmiser.keylock", HW_Status))
//Collect Schedule informaiton for the 5/2 setup (5=Mon-Fri and 2=Sat-Sun)
//Weekdays - Wake time
HW_01_WWDTemp.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][0].target", HW_Status))
HW_02_WWDHour.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][0].time", HW_Status).substring(0,2))
HW_03_WWDMinute.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][0].time", HW_Status).substring(3,5))
//Weekdays - Leave time
HW_04_LWDTemp.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][1].target", HW_Status))
HW_05_LWDHour.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][1].time", HW_Status).substring(0,2))
HW_06_LWDMinute.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][1].time", HW_Status).substring(3,5))
//Weekdays - Return time
HW_07_RWDTemp.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][2].target", HW_Status))
HW_08_RWDHour.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][2].time", HW_Status).substring(0,2))
HW_09_RWDMinute.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][2].time", HW_Status).substring(3,5))
//Weekdays - Sleep time
HW_10_SWDTemp.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][3].target", HW_Status))
HW_11_SWDHour.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][3].time", HW_Status).substring(0,2))
HW_12_SWDMinute.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[0][3].time", HW_Status).substring(3,5))
//Weekends - Wake time
HW_13_WWETemp.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][0].target", HW_Status))
HW_14_WWEHour.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][0].time", HW_Status).substring(0,2))
HW_15_WWEMinute.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][0].time", HW_Status).substring(3,5))
//Weekends - Leave time
HW_16_LWETemp.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][1].target", HW_Status))
HW_17_LWEHour.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][1].time", HW_Status).substring(0,2))
HW_18_LWEMinute.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][1].time", HW_Status).substring(3,5))
//Weekends - Return time
HW_19_RWETemp.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][2].target", HW_Status))
HW_20_RWEHour.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][2].time", HW_Status).substring(0,2))
HW_21_RWEMinute.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][2].time", HW_Status).substring(3,5))
//Weekends - Sleep time
HW_22_SWETemp.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][3].target", HW_Status))
HW_23_SWEHour.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][3].time", HW_Status).substring(0,2))
HW_24_SWEMinute.postUpdate(transform("JSONPATH", "$.heatmiser.comfort[1][3].time", HW_Status).substring(3,5))
}
end
//********************************************************
//*** Rules to post settings/changes to the Thermostat ***
//********************************************************
rule "Sync Thermostat time with Server time"
when
System started or
Time cron "0 0 3 1/1 * ? *"
then
Thread::sleep(300)
{executeCommandLine("/home/openhab/heatmiser-wifi-read-only/bin/heatmiser_time.pl")}
end
rule "Set the temperature manually until next scheduled time change"
when
Item HW_HeatingTarget changed
then
lock1.lock()
try { executeCommandLine("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_settemp.sh "+HW_HeatingTarget.state) Thread::sleep(400) }
finally {lock1.unlock()}
end
rule "Lock Thermostat Screen Input"
when
Item HW_Keylock received command
then
lock1.lock()
try {
val cmd = if(receivedCommand == ON) "1" else "0" {
executeCommandLine("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_keylock.sh " + cmd)
}}
finally {lock1.unlock()}
end
rule "Detect Keylock set at Pad"
when
Item HW_KLS changed
then
if (HW_KLS.state==('0')) {HW_Keylock.postUpdate(OFF)}
if (HW_KLS.state==('1')) {HW_Keylock.postUpdate(ON)}
end
rule "Frost Protect set Temperature"
when
Item HW_FrostprotectTarget received command
then
lock1.lock()
try { executeCommandLine("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_frostprotect.sh "+HW_FrostprotectTarget.state) Thread::sleep(400)}
finally {lock1.unlock() }
end
rule "Turn on/off holiday Mode"
when
Item HW_SetHoliday received command
then
lock1.lock()
try { switch (receivedCommand) {
case ON : { executeCommandLine("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_holidayaway.sh") Thread::sleep(400)}
case OFF : { executeCommandLine("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_holidayhome.sh") Thread::sleep(400)}
}}
finally {lock1.unlock()}
end
rule "Boost the temperature for X minutes to Boost Temp value"
when
Item HW_TempHoldDuration received command
then
if(!(receivedCommand instanceof Number)) return;
lock1.lock()
try {
if(receivedCommand > 0) {
executeCommandLine("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_hold.sh " + receivedCommand.toString)
Thread::sleep(500)
executeCommandLine=("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_settemp.sh " + HW_TempHoldTemperature.state.toString)
}
else {executeCommandLine=("/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_hold.sh " + receivedCommand.toString)}
HW_Heatingholdoff.postUpdate(receivedCommand.toString)
Thread::sleep(300)
}
finally {lock1.unlock()}
end
rule "Turn off boost in Sitemap if boost is off"
when
Item HW_Heatingholdoff changed to "0"
then
HW_TempHoldDuration.postUpdate("0")
end
rule "Update schedules and temps"
when
Member of gSched changed
then
lock1.lock()
try {
strCommand = "/home/openhab/heatmiser-wifi-read-only/openhabscripts/hw_schedule.sh "
gSched.members.sortBy[name].forEach[i | strCommand = strCommand + i.state.toString + " "]
executeCommandLine(strCommand)
HW_MF1.postUpdate(HW_01_WWDTemp.state + " Deg C at " + HW_02_WWDHour.state + ":" + HW_03_WWDMinute.state)
HW_MF2.postUpdate(HW_04_LWDTemp.state + " Deg C at " + HW_05_LWDHour.state + ":" + HW_06_LWDMinute.state)
HW_MF3.postUpdate(HW_07_RWDTemp.state + " Deg C at " + HW_08_RWDHour.state + ":" + HW_09_RWDMinute.state)
HW_MF4.postUpdate(HW_10_SWDTemp.state + " Deg C at " + HW_11_SWDHour.state + ":" + HW_12_SWDMinute.state)
HW_WE1.postUpdate(HW_13_WWETemp.state + " Deg C at " + HW_14_WWEHour.state + ":" + HW_15_WWEMinute.state)
HW_WE2.postUpdate(HW_16_LWETemp.state + " Deg C at " + HW_17_LWEHour.state + ":" + HW_18_LWEMinute.state)
HW_WE3.postUpdate(HW_19_RWETemp.state + " Deg C at " + HW_20_RWEHour.state + ":" + HW_21_RWEMinute.state)
HW_WE4.postUpdate(HW_22_SWETemp.state + " Deg C at " + HW_23_SWEHour.state + ":" + HW_24_SWEMinute.state)
Thread::sleep(400)
}
finally {lock1.unlock()}
end
- The only thing left to do now, will be to setup the icons you wish to use, by changing the names in your Items file… these are the ones from step 9 and the icon names are those in the <>'s
IMPORTANT NOTE: If your thermostat is factory settings, log into it and set something in the blank/empty “Weekend” schedule times/temp, otherwise you will get a bad output on the Openhab web interface.
The reason there are thread delays in the rules, is so that we arent firing too many requests at the same time to the thermostat… which ensures it gets each command processed correctly/in a timely manner.
If you wish to read up further or try to develop any other features in these, this work is based off these:
and this