Thermostat
Updated July 19, 2022 by luwol03 and ShaquuUUID: 0000004A-0000-1000-8000-0026BB765291
Characteristics
Examples
These examples are meant to be copied into your Node-RED system and adapted to your setup.
Thermostats with only Heating and with Heating/Cooling
This flow contains two thermostats. One is only for heating and can be switched on/off, the other has all 4 operating modes.
The flow looks like this:
In Home.app, you will get this:
Heating thermostat
Icon view
Set temperature
Choose mode
Detailed view
Heating/cooling thermostat
Icon view
Set temperatures
Choose mode
Copyable Node-RED flow:
[{"id":"71bb32de.e0b0ac","type":"inject","z":"aacd89c2.2cf708","name":"CurrentHeatingCoolingState off","topic":"","payload":"{\"CurrentHeatingCoolingState\":0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":620,"wires":[["eb3f7f35.275ed"]]},{"id":"120a8ce.c6a3373","type":"debug","z":"aacd89c2.2cf708","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":870,"y":960,"wires":[]},{"id":"f42d56a1.db50d8","type":"inject","z":"aacd89c2.2cf708","name":"TargetHeatingCoolingState off","topic":"","payload":"{\"TargetHeatingCoolingState\":0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":460,"y":620,"wires":[["eb3f7f35.275ed"]]},{"id":"7349e2ee.759fac","type":"inject","z":"aacd89c2.2cf708","name":"CurrentTemperature 10","topic":"","payload":"{\"CurrentTemperature\":10}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":800,"wires":[["eb3f7f35.275ed"]]},{"id":"8f22babf.1332a8","type":"inject","z":"aacd89c2.2cf708","name":"TargetTemperature 10","topic":"","payload":"{\"TargetTemperature\":10}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":420,"y":800,"wires":[["eb3f7f35.275ed"]]},{"id":"9c3496bd.fe8328","type":"inject","z":"aacd89c2.2cf708","name":"CurrentHeatingCoolingState heat","topic":"","payload":"{\"CurrentHeatingCoolingState\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":660,"wires":[["eb3f7f35.275ed"]]},{"id":"17b83efb.5df391","type":"inject","z":"aacd89c2.2cf708","name":"TargetHeatingCoolingState heat","topic":"","payload":"{\"TargetHeatingCoolingState\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":660,"wires":[["eb3f7f35.275ed"]]},{"id":"2e02c54b.ee4eca","type":"inject","z":"aacd89c2.2cf708","name":"CurrentHeatingCoolingState cool","topic":"","payload":"{\"CurrentHeatingCoolingState\":2}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":700,"wires":[["eb3f7f35.275ed"]]},{"id":"bdf35b08.d58578","type":"inject","z":"aacd89c2.2cf708","name":"TargetHeatingCoolingState cool","topic":"","payload":"{\"TargetHeatingCoolingState\":2}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":700,"wires":[["eb3f7f35.275ed"]]},{"id":"9f1612bb.200ea","type":"inject","z":"aacd89c2.2cf708","name":"CurrentTemperature 20","topic":"","payload":"{\"CurrentTemperature\":20}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":840,"wires":[["eb3f7f35.275ed"]]},{"id":"5ceff715.5df388","type":"inject","z":"aacd89c2.2cf708","name":"TargetTemperature 20","topic":"","payload":"{\"TargetTemperature\":20}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":420,"y":840,"wires":[["eb3f7f35.275ed"]]},{"id":"7e073e90.31c72","type":"inject","z":"aacd89c2.2cf708","name":"CurrentTemperature 30","topic":"","payload":"{\"CurrentTemperature\":30}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":880,"wires":[["eb3f7f35.275ed"]]},{"id":"89402a3d.d581a8","type":"inject","z":"aacd89c2.2cf708","name":"TargetTemperature 30","topic":"","payload":"{\"TargetTemperature\":30}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":420,"y":880,"wires":[["eb3f7f35.275ed"]]},{"id":"f00041a2.ce66e","type":"inject","z":"aacd89c2.2cf708","name":"TemperatureDisplayUnits Celsius","topic":"","payload":"{\"TemperatureDisplayUnits\":0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":940,"wires":[["eb3f7f35.275ed"]]},{"id":"73c1a173.df287","type":"inject","z":"aacd89c2.2cf708","name":"TemperatureDisplayUnits Fahrenheit","topic":"","payload":"{\"TemperatureDisplayUnits\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":980,"wires":[["eb3f7f35.275ed"]]},{"id":"9975b2ea.252e5","type":"inject","z":"aacd89c2.2cf708","name":"CurrentRelativeHumidity 20","topic":"","payload":"{\"CurrentRelativeHumidity\":20}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":1040,"wires":[["eb3f7f35.275ed"]]},{"id":"e0b641c8.151a7","type":"inject","z":"aacd89c2.2cf708","name":"TargetRelativeHumidity 20","topic":"","payload":"{\"TargetRelativeHumidity\":20}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":1040,"wires":[["eb3f7f35.275ed"]]},{"id":"173f83f.569c57c","type":"inject","z":"aacd89c2.2cf708","name":"CurrentRelativeHumidity 30","topic":"","payload":"{\"CurrentRelativeHumidity\":30}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":1080,"wires":[["eb3f7f35.275ed"]]},{"id":"261af724.7d14e8","type":"inject","z":"aacd89c2.2cf708","name":"TargetRelativeHumidity 30","topic":"","payload":"{\"TargetRelativeHumidity\":30}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":1080,"wires":[["eb3f7f35.275ed"]]},{"id":"f63235a2.c01fc8","type":"inject","z":"aacd89c2.2cf708","name":"CurrentRelativeHumidity 40","topic":"","payload":"{\"CurrentRelativeHumidity\":40}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":1120,"wires":[["eb3f7f35.275ed"]]},{"id":"bc0b38d8.8b19a8","type":"inject","z":"aacd89c2.2cf708","name":"TargetRelativeHumidity 40","topic":"","payload":"{\"TargetRelativeHumidity\":40}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":1120,"wires":[["eb3f7f35.275ed"]]},{"id":"e36bdcc9.32c29","type":"inject","z":"aacd89c2.2cf708","name":"CoolingThresholdTemperature 23","topic":"","payload":"{\"CoolingThresholdTemperature\":23}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":1220,"wires":[["eb3f7f35.275ed"]]},{"id":"91b5fbc2.81d1f8","type":"inject","z":"aacd89c2.2cf708","name":"HeatingThresholdTemperature 21","topic":"","payload":"{\"HeatingThresholdTemperature\":21}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":1220,"wires":[["eb3f7f35.275ed"]]},{"id":"b52ecac9.c3f698","type":"inject","z":"aacd89c2.2cf708","name":"CoolingThresholdTemperature 25","topic":"","payload":"{\"CoolingThresholdTemperature\":25}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":1260,"wires":[["eb3f7f35.275ed"]]},{"id":"67476ce3.ae9c54","type":"inject","z":"aacd89c2.2cf708","name":"HeatingThresholdTemperature 22","topic":"","payload":"{\"HeatingThresholdTemperature\":22}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":1260,"wires":[["eb3f7f35.275ed"]]},{"id":"7716264a.e09b98","type":"inject","z":"aacd89c2.2cf708","name":"HeatingThresholdTemperature 18","topic":"","payload":"{\"HeatingThresholdTemperature\":18}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":1180,"wires":[["eb3f7f35.275ed"]]},{"id":"b60f3788.4adb68","type":"inject","z":"aacd89c2.2cf708","name":"CoolingThresholdTemperature 20","topic":"","payload":"{\"CoolingThresholdTemperature\":20}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":1180,"wires":[["eb3f7f35.275ed"]]},{"id":"29c352ee.0f465e","type":"inject","z":"aacd89c2.2cf708","name":"CurrentHeatingCoolingState auto","topic":"","payload":"{\"CurrentHeatingCoolingState\":3}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":740,"wires":[["eb3f7f35.275ed"]]},{"id":"9102b724.964998","type":"inject","z":"aacd89c2.2cf708","name":"TargetHeatingCoolingState auto","topic":"","payload":"{\"TargetHeatingCoolingState\":3}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":740,"wires":[["eb3f7f35.275ed"]]},{"id":"eb3f7f35.275ed","type":"function","z":"aacd89c2.2cf708","name":"","func":"\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":960,"wires":[["a523fb3e.497ea8","f50c12fc.0eeeb"]]},{"id":"a523fb3e.497ea8","type":"homekit-service","z":"aacd89c2.2cf708","bridge":"27eae9d3.b636b6","name":"Heating/Cooling Thermostat","serviceName":"Thermostat","topic":"","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{\n}","x":660,"y":1000,"wires":[["120a8ce.c6a3373"]]},{"id":"f50c12fc.0eeeb","type":"homekit-service","z":"aacd89c2.2cf708","bridge":"27eae9d3.b636b6","name":"Heating Thermostat","serviceName":"Thermostat","topic":"","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{\n \"TargetHeatingCoolingState\": {\n \"validValues\": [0, 1]\n },\n \"CurrentHeatingCoolingState\": {\n \"validValues\": [0, 1]\n }\n}","x":630,"y":940,"wires":[["120a8ce.c6a3373"]]},{"id":"27eae9d3.b636b6","type":"homekit-bridge","z":"","bridgeName":"4","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number"}]
Heating thermostat with auto ON/OFF
Example of thermostat (Heating only) logic below. It turns on ({"CurrentHeatingCoolingState":1}
) and off ({"CurrentHeatingCoolingState":0}
) depending on CurrentTemperature
. This example would be applicable to radiator heater valves, plug-in heaters, and other similar equipment.
You should save T1.target_temperature
somehow (DB is a good choice) to store it after NodeRED restart, or you can face serious troubles in real environment. At the very least it is recommended to have the default value for T1.target_temperature
(line 2 in the function node) be a nice temperature for your house in case the system restarts and sets the temperature back to default.
Generally the current temperature and humidity will be determined by a sensor in your automation setup. The target temperature will be determined by your thermostat and/or you’re setting in the Home app. Put simply, this flow will send a payload to Output
of {"CurrentHeatingCoolingState":0}
or {"CurrentHeatingCoolingState":1}
depending on if current temperature or target temperature is a higher number.
[{"id":"dcf59f2.d7469e","type":"inject","z":"e639a8b0.423e8","name":"Request off","topic":"","payload":"{\"TargetHeatingCoolingState\":0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":180,"wires":[["a99fd29a.401ce8"]]},{"id":"a99fd29a.401ce8","type":"homekit-service","z":"e639a8b0.423e8","isParent":true,"bridge":"6a8d3ef1.88061","parentService":"","name":"CleverThermostat","serviceName":"Thermostat","topic":"","filter":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{\n \"TargetHeatingCoolingState\": {\n \"validValues\": [0, 1]\n },\n \"CurrentHeatingCoolingState\": {\n \"validValues\": [0, 1]\n }\n}","x":510,"y":380,"wires":[["912314ac.d24818","4c937b1c.5ee9cc"]]},{"id":"b1ec7a7e.af4b","type":"inject","z":"e639a8b0.423e8","name":"Current 68 F (20 C)","topic":"","payload":"{\"CurrentTemperature\": 20}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":300,"wires":[["a99fd29a.401ce8"]]},{"id":"ca31c1b0.a9716","type":"inject","z":"e639a8b0.423e8","name":"Target 73 F (23 C)","topic":"","payload":"{\"TargetTemperature\": 23}","payloadType":"json","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":230,"y":420,"wires":[["a99fd29a.401ce8"]]},{"id":"ff94240f.bb096","type":"inject","z":"e639a8b0.423e8","name":"Target 50 F (10 C)","topic":"","payload":"{\"TargetTemperature\": 10}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":460,"wires":[["a99fd29a.401ce8"]]},{"id":"c790acf0.96924","type":"inject","z":"e639a8b0.423e8","name":"Current 59 F (15 C)","topic":"","payload":"{\"CurrentTemperature\": 15}","payloadType":"json","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":230,"y":340,"wires":[["a99fd29a.401ce8"]]},{"id":"912314ac.d24818","type":"function","z":"e639a8b0.423e8","name":"Save TEMP/HUM/TT","func":"var T1 = context.get(\"T1\")||{\n \"target_temperature\": 12,\n \"temperature\": 10,\n \"humidity\": 11,\n \"targetHeatCoolState\": 0\n};\n\nvar OutMsg = {};\n\nif (msg.payload.TargetHeatingCoolingState !== undefined){\n T1.targetHeatCoolState = msg.payload.TargetHeatingCoolingState;\n}\n\nif (msg.payload.CurrentTemperature !== undefined) {\n T1.temperature = msg.payload.CurrentTemperature;\n}\n\nif (msg.payload.CurrentRelativeHumidity !== undefined) {\n T1.humidity = msg.payload.CurrentRelativeHumidity;\n}\n\nif (msg.payload.TargetTemperature !== undefined) {\n T1.target_temperature = msg.payload.TargetTemperature;\n}\n\nif (T1.targetHeatCoolState == 1){\n if (T1.temperature >= T1.target_temperature) {\n OutMsg.payload = { \n CurrentHeatingCoolingState: 0\n };\n } else {\n OutMsg.payload = { \n CurrentHeatingCoolingState: 1\n };\n }\n} else if (T1.targetHeatCoolState === 0){\n OutMsg.payload = {\n CurrentHeatingCoolingState: 0\n };\n}\n\ncontext.set(\"T1\",T1);\n\nreturn OutMsg;\n","outputs":1,"noerr":0,"x":500,"y":540,"wires":[["a99fd29a.401ce8"]]},{"id":"4c937b1c.5ee9cc","type":"debug","z":"e639a8b0.423e8","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":750,"y":380,"wires":[]},{"id":"fcd747b4.f92588","type":"inject","z":"e639a8b0.423e8","name":"Current 77 F (25 C)","topic":"","payload":"{\"CurrentTemperature\": 25}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":260,"wires":[["a99fd29a.401ce8"]]},{"id":"70eb57cd.8d1cb","type":"inject","z":"e639a8b0.423e8","name":"Request heat","topic":"","payload":"{\"TargetHeatingCoolingState\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":140,"wires":[["a99fd29a.401ce8"]]},{"id":"e59b81d7.0473e8","type":"inject","z":"e639a8b0.423e8","name":"Check every 5 sec","topic":"","payload":"","payloadType":"date","repeat":"5","crontab":"","once":true,"onceDelay":0.1,"x":240,"y":540,"wires":[["912314ac.d24818"]]},{"id":"6a8d3ef1.88061","type":"homekit-bridge","z":"","bridgeName":"Garage","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"Garrett","model":"Pi HAT","serialNo":"3","customMdnsConfig":false,"mdnsMulticast":true,"mdnsInterface":"","mdnsPort":"","mdnsIp":"","mdnsTtl":"","mdnsLoopback":true,"mdnsReuseAddr":true}]