Skip to content

Example Thermostat

crxporter edited this page Apr 23, 2019 · 3 revisions

Properties

Available Properties

Characteristic Optional/Required Characteristic Properties (to enable property)
TargetHeatingCoolingState Required
CurrentHeatingCoolingState Required
TargetTemperature Required
CurrentTemperature Required
TemperatureDisplayUnits Required
CurrentRelativeHumidity Optional { "CurrentRelativeHumidity": true }
TargetRelativeHumidity Optional { "TargetRelativeHumidity": true }
CoolingThresholdTemperature Optional only relevant when HeatingCoolingState = 3
HeatingThresholdTemperature Optional only relevant when HeatingCoolingState = 3

Details

Characteristic Format Accepted Values Notes
TargetHeatingCoolingState int 0, 1, 2, 3 off = 0, heating = 1, cooling = 2, auto = 3; valid states can be defined in characteristics definition
CurrentHeatingCoolingState int 0, 1, 2, 3 off = 0, heating = 1, cooling = 2, auto = 3; valid states can be defined in characteristics definition
TargetTemperature float 10 - 38 always in Degree Celsius; in mode auto this is the average between cooling and heating thresholds
CurrentTemperature float 10 - 38 always in Degree Celsius
TemperatureDisplayUnits int 0, 1 Degree Celsius = 0, Degree Fahrenheit = 1; has no effect on displayed values, as these are controlled by regional settings in iOS
CurrentRelativeHumidity float 0 - 100
TargetRelativeHumidity float 0 - 100
CoolingThresholdTemperature float 0 - 100 defines down to which temperature the appliance will cool, only used in mode auto
HeatingThresholdTemperature float 0 - 100 defines up to which temperature the appliance will cool, only used in mode auto

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:

image

In Home.app, you will get this:

Heating thermostat

Icon view

Icon Heating

Set temperature

Set temperature

Choose mode

Choose mode

Detailed view

Detail Heating

Heating/cooling thermostat

Icon view

image

Set temperatures

image

Choose mode

image

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 of 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 your 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.

Screen Shot 2019-04-22 at 8 14 20 PM
[{"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}]
Clone this wiki locally