Node-red-contrib-homekit-bridged: Thermostat logic

Created on 3 Apr 2019  ·  20Comments  ·  Source: NRCHKB/node-red-contrib-homekit-bridged

For example heating thermostat (real case, gas boiler), when I change TargetTemperature I'm expecting for TargetHeatingCoolingState to change =) But when CurrentTemperature became equal to TargetTemperature, nothing happens.

Should I run a function for this? Here is a cool sample, but nothing about thermostat logic =)

All 20 comments

This would be a great question for @oliverrahner to comment on - he put together that example and I believe uses thermostat(s) in his setup.

This would be a great question for @oliverrahner to comment on - he put together that example and I believe uses thermostat(s) in his setup.

My next step is a garage door, I fear to even ask about samples =)

Garage door seems easier... the tables in the wiki

CurrentDoorState: Open=0, closed=1, opening=2, closing=3, stopped=4
TargetDoorState: Open=0, closed=1

PS - if you're controlling only a heater you'll want to have this characteristic property:

{"TargetHeatingCoolingState":
    {
        "validValues":[0,1]
    }
}

Which should limit homekit to only display "Off" and "Heat"

PS - if you're controlling only a heater you'll want to have this characteristic property:
Which should limit homekit to only display "Off" and "Heat"

I've done this, but the problem with logic persists )

Well it is what node-red is about :)
You are provided with tools to create homekit ready accessories but logic is up to you.

If you share with us full specification of your problem and requirements then maybe someone will find some time to make a logical flow for you.

I’m trying to do this myself right now, but faced a big problem. I need to store thermostat state and settings after nodered restart, cause else it reset any status to heating to 10C )

How to manage this? Database (SQLite or smth), file and so on, but it is tricky and non-appleway %)

You can write to text files on your - I assume raspberry pi?

Whichever computer you're using, you can write as many text files from within node red as you like, and read them whenever you like. If there is persistence built into node-red then I don't know how to use it. I have been successful writing a few important things to text files and reading them on boot.

Try out the "write file" and "read file" nodes!

PS - check here for a description of how to use files to store and pull persistent values using function nodes!

The discussion on the forum is better, but this is also mentioned in the node red docs

If you share with us full specification of your problem and requirements then maybe someone will find some time to make a logical flow for you.

Here it is. I'll be glad if someone can help, thermostat is useless without basic logic:

[{"id":"3609d299.26b05e","type":"mqtt in","z":"e30f7e41.5db1f8","name":"","topic":"tele/nodemcu3/SENSOR","qos":"1","broker":"8ffaf78f.89bdb","x":130,"y":30,"wires":[["ab38bd31.515bf"]]},{"id":"ab38bd31.515bf","type":"json","z":"e30f7e41.5db1f8","name":"","property":"payload","action":"","pretty":true,"x":310,"y":30,"wires":[["6f10bc33.07b8fc","c94c3964.719798"]]},{"id":"6f10bc33.07b8fc","type":"template","z":"e30f7e41.5db1f8","name":"Temp","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{payload.DHT11.Temperature}}","output":"str","x":110,"y":140,"wires":[["4ce50a37.d60d14"]]},{"id":"c94c3964.719798","type":"template","z":"e30f7e41.5db1f8","name":"Hum","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{payload.DHT11.Humidity}}","output":"str","x":110,"y":190,"wires":[["b5466621.6cb0d"]]},{"id":"b5466621.6cb0d","type":"change","z":"e30f7e41.5db1f8","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.CurrentRelativeHumidity","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":190,"wires":[["d64ce61d.69c8e8","8f38232e.80b1"]]},{"id":"d64ce61d.69c8e8","type":"homekit-service","z":"e30f7e41.5db1f8","bridge":"1f4da0a9.4023c7","name":"HUM1","serviceName":"HumiditySensor","topic":"","manufacturer":"ptath","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":506,"y":88,"wires":[[]]},{"id":"4ce50a37.d60d14","type":"change","z":"e30f7e41.5db1f8","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.CurrentTemperature","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":282,"y":144,"wires":[["7c5c5ca5.d4a694","8f38232e.80b1"]]},{"id":"7c5c5ca5.d4a694","type":"homekit-service","z":"e30f7e41.5db1f8","bridge":"1f4da0a9.4023c7","name":"TEMP1","serviceName":"TemperatureSensor","topic":"","manufacturer":"ptath","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":516,"y":48,"wires":[[]]},{"id":"4ad25156.dee63","type":"debug","z":"e30f7e41.5db1f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":686,"y":160,"wires":[]},{"id":"8f38232e.80b1","type":"homekit-service","z":"e30f7e41.5db1f8","isParent":true,"bridge":"1f4da0a9.4023c7","parentService":"","name":"DumbThermostat","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":546,"y":272,"wires":[["4ad25156.dee63"]]},{"id":"9c376881.dc4d8","type":"inject","z":"e30f7e41.5db1f8","name":"On","topic":"","payload":"{\"TargetHeatingCoolingState\": 1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":322,"y":272,"wires":[["8f38232e.80b1"]]},{"id":"73cc54ff.1a1954","type":"inject","z":"e30f7e41.5db1f8","name":"Off","topic":"","payload":"{\"TargetHeatingCoolingState\": 0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":322,"y":320,"wires":[["8f38232e.80b1"]]},{"id":"8ffaf78f.89bdb","type":"mqtt-broker","z":"","name":"dragon","broker":"192.168.1.10","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""},{"id":"1f4da0a9.4023c7","type":"homekit-bridge","z":"","bridgeName":"villa-test","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"ptath","model":"raspberry pi zeroW","serialNo":"12345678"}]

Try out the "write file" and "read file" nodes!

It is no problem, I can even use DB (already do this for temp/hum stats).

On node start we should poll all available accessories, check its state, check stored values (target temp for example and so on). But it is very complex solution )

For example heating thermostat (real case, gas boiler), when I change TargetTemperature I'm expecting for TargetHeatingCoolingState to change =) But when CurrentTemperature became equal to TargetTemperature, nothing happens.

Should I run a function for this? Here is a cool sample, but nothing about thermostat logic =)

The answer is that Homekit itself does not implement such kind of logic.
This logic is supposed to live inside the appliance you are controlling.

For example, when CurrentTemperature == TargetTemperature, the appliance should recognize this and report CurrentHeatingCoolingState = off (and probably also TargetHeatingCoolingState) back to Homekit.

If this would be otherwise, you would be putting more logic in Homekit than belongs there (and thus, limiting the flexibility of use cases).

Oh I'm total noob in nodered and javascript, but:

[{"id":"a4cdb4ee.5a6a98","type":"inject","z":"a8398f00.b6f78","name":"20 C","topic":"","payload":"{\"CurrentTemperature\": 20}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":200,"wires":[["3a835329.ea1704"]]},{"id":"f863c75c.17e4d8","type":"inject","z":"a8398f00.b6f78","name":"TT 23","topic":"","payload":"{\"TargetTemperature\": 23}","payloadType":"json","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":280,"wires":[["3a835329.ea1704"]]},{"id":"7c6ec8.da050138","type":"inject","z":"a8398f00.b6f78","name":"TT 10","topic":"","payload":"{\"TargetTemperature\": 10}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":320,"wires":[["3a835329.ea1704"]]},{"id":"14d4aa9a.65a4fd","type":"inject","z":"a8398f00.b6f78","name":"15 C","topic":"","payload":"{\"CurrentTemperature\": 15}","payloadType":"json","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":240,"wires":[["3a835329.ea1704"]]},{"id":"3a835329.ea1704","type":"homekit-service","z":"a8398f00.b6f78","isParent":true,"bridge":"1f4da0a9.4023c7","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":338,"y":176,"wires":[["d8356840.dc236","e4d5b6db.db8a2"]]},{"id":"d8356840.dc236","type":"function","z":"a8398f00.b6f78","name":"Save TEMP/HUM/TT","func":"var T1 = global.get(\"T1\");\n\nif (msg.payload.CurrentTemperature !== undefined) {\n    global.set(\"T1.temperature\", msg.payload.CurrentTemperature);\n}\n\nif (msg.payload.CurrentRelativeHumidity !== undefined) {\n    global.set(\"T1.humidity\", msg.payload.CurrentRelativeHumidity);\n}\n\nif (msg.payload.TargetTemperature !== undefined) {\n    global.set(\"T1.target_temperature\", msg.payload.TargetTemperature);\n}\n\n//node.warn(T1);\n\nif (T1.temperature >= T1.target_temperature) {\n    //node.warn(\"Stop cooling\");\n    var msg = { \n        TargetHeatingCoolingState: 0\n    }\n} else {\n    //node.warn(\"Too cold\");\n    var msg = { \n        TargetHeatingCoolingState: 1\n    }\n}\n\nvar msg = { payload: msg };\n\n//node.warn(msg);\nreturn msg;","outputs":1,"noerr":0,"x":484,"y":296,"wires":[["3a835329.ea1704"]]},{"id":"9557b65a.18e018","type":"function","z":"a8398f00.b6f78","name":"Thermostat logic","func":"var T1 = global.get(\"T1\");\nnode.warn(T1);\n\nif (T1.temperature >= T1.target_temperature) {\n    //node.warn(\"Stop cooling\");\n    var msg = { \n        TargetHeatingCoolingState: 0\n    }\n} else {\n    //node.warn(\"Too cold\");\n    var msg = { \n        TargetHeatingCoolingState: 1\n    }\n}\n\nvar msg = { payload: msg };\n\n//node.warn(msg);\nreturn msg;","outputs":1,"noerr":0,"x":442,"y":448,"wires":[[]]},{"id":"9c2c5079.b16b","type":"inject","z":"a8398f00.b6f78","name":"Check every 5 sec","topic":"","payload":"T1","payloadType":"global","repeat":"5","crontab":"","once":true,"onceDelay":0.1,"x":170,"y":392,"wires":[["d8356840.dc236"]]},{"id":"e4d5b6db.db8a2","type":"debug","z":"a8398f00.b6f78","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":814,"y":40,"wires":[]},{"id":"a5ee55e0.d63038","type":"function","z":"a8398f00.b6f78","name":"Default variables","func":"var T1 = {\n    target_temperature: 12,\n    temperature: 10,\n    humidity: 11\n}\nglobal.set(\"T1\", T1);\n\nnode.warn(T1);\n\nreturn [T1];","outputs":1,"noerr":0,"x":338,"y":56,"wires":[[]]},{"id":"4f709d78.afb93c","type":"inject","z":"a8398f00.b6f78","name":"","topic":"Setting T1 values on boot","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":142,"y":56,"wires":[["a5ee55e0.d63038"]]},{"id":"1f4da0a9.4023c7","type":"homekit-bridge","z":"","bridgeName":"villa-test","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"ptath","model":"raspberry pi zeroW","serialNo":"12345678"}]

Please review it and add to examples

The wiki page is open to all! Feel free to add this example under the other on the thermostat page.

I review the wiki pages regularly and will likely update or clarify a few things, leave this thread open for that discussion.

@crxporter You could review anyway as our wiki master :)

Yes yes. I am sure I will but I’ve been busy lately.

If it’s on the wiki before I get to it I’ll review there. Otherwise I’ll review here then add to the wiki!!

Maybe it will be useful in some cases: to set the minimum and maximum thermostat temperature, use the following characteristics properties:

{"TargetTemperature": {
         "minValue": 5,
         "maxValue": 35
         }
}

@fearraiser - one correction those are labeled “characteristic properties” ... we don’t (yet) have initial characteristics.

But yes this is good information. I have plans to add many more examples using characteristic properties- this will be a great one for the thermostat service!

@crxporter of cause, sorry, I corrected the definition.

Not a big deal! There has been a lot of confusion on what those properties are for... It took me a long time to figure it out - I'd been using the plugin over a year before I understood. Between the confusion and the coming initial values I just want to try to keep things clear!

Thanks again for the idea!

@ptath - I finally have some time to look at your example today!

I noticed that you're only sending TargetHeatingCoolingState and never CurrentHeatingCoolingState. This will cause some interesting results. The Home app won't ever actually show "heating".

The Home app looks for 4 things at a minimum with this service:
1- TargetHeatingCoolingState (whether the user wants to heat or not)
2- CurrentHeatingCoolingState (whether the heater is heating or not)
3- CurrentTemperature (what temperature the room actually is)
4- TargetTemperature (what temperature the room should be)

I added some of my own personal flair to your example... First I moved your global variables to context variables. I set them to restore to default states like:

{
    "target_temperature": 12,
    "temperature": 10,
    "humidity": 11,
    "targetHeatCoolState": 0
}

These are stored in as context.set and context.get and will be updated each time the function runs (every 5 seconds).

Then I changed your logic to CurrentHeatingCoolingState and added some functionality for TargetHeatingCoolingState. It works better for me. I also added degrees F to the inject nodes so I could keep track of what was what during testing...

Now the functionality should be the same as yours was - it injects {"CurrentHeatingCoolingState":0} if CurrentTemp>TargetTemp and {"CurrentHeatingCoolingState":1} otherwise. I added a check for TargetHeatingCoolingState so that it will only send the current state if the target state is 1. This way the user will have control over whether it heats based on your logic program

With these changes, the Home app icon should show one of 3 items: Off, heating to xx with a green circle (means heater is not on), and heating to xx with an orange circle (means heater is on).

Have a look!

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}]

I also updated the wiki page. Feel free to comment with more changes or ideas! If you're happy with how the example turned out, feel free to close the issue.

Thanks for the answer! Actually I got it to work, even in real (but now boiler is off, spring came to Motherland =)

Here is final version, sorry for Cyrillic names:

[{"id":"a8398f00.b6f78","type":"tab","label":"Термостат","disabled":false,"info":""},{"id":"3a835329.ea1704","type":"homekit-service","z":"a8398f00.b6f78","isParent":true,"bridge":"1f4da0a9.4023c7","parentService":"","name":"Термостат","serviceName":"Thermostat","topic":"","filter":false,"manufacturer":"ptath","model":"Sonoff and NodeMCU","serialNo":"0001","characteristicProperties":"{\n    \"TargetHeatingCoolingState\": {\n        \"validValues\": [0, 1]\n    },\n    \"CurrentHeatingCoolingState\": {\n        \"validValues\": [0, 1]\n    }\n}","x":550,"y":216,"wires":[["d8356840.dc236","e4d5b6db.db8a2","f273f04d.fc895","8d622a65.0db188"]]},{"id":"d8356840.dc236","type":"function","z":"a8398f00.b6f78","name":"ТЕМП/ВЛАЖ/ЦЕЛЬ","func":"//var SQLQuery;\nvar newMsg;\nvar Thermostat1 = global.get(\"Thermostat1\");\n\nif (msg.payload.CurrentTemperature !== undefined) {\n    global.set(\"Thermostat1.CurrentTemperature\", msg.payload.CurrentTemperature);\n}\n\nif (msg.payload.CurrentRelativeHumidity !== undefined) {\n    global.set(\"Thermostat1.CurrentRelativeHumidity\", msg.payload.CurrentRelativeHumidity);\n}\n\nif (msg.payload.TargetTemperature !== undefined) {\n    global.set(\"Thermostat1.TargetTemperature\", msg.payload.TargetTemperature);\n//    SQLQuery = {\n//        \"topic\": \"UPDATE THERMOSTATS SET TARGET_TEMP=\"+ Thermostat1.TargetTemperature +\" WHERE THERMOSTAT_NO=1;\"\n//    }\n}\n\nnewMsg = { \"payload\": Thermostat1}\nreturn newMsg;","outputs":1,"noerr":0,"x":628,"y":160,"wires":[["e4d5b6db.db8a2","10a224dd.3c6dcb","b7536669.a21a48"]]},{"id":"e4d5b6db.db8a2","type":"debug","z":"a8398f00.b6f78","name":"Дебаг msg.payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":876,"y":544,"wires":[]},{"id":"a5ee55e0.d63038","type":"function","z":"a8398f00.b6f78","name":"Целевая температура из БД","func":"var Thermostat1 = {\n    \"TargetTemperature\": msg.payload[0].TARGET_TEMP\n}\n\nglobal.set(\"Thermostat1\", Thermostat1);\n//node.warn(T1);\n\nreturn Thermostat1;","outputs":1,"noerr":0,"x":434,"y":656,"wires":[[]]},{"id":"4f709d78.afb93c","type":"inject","z":"a8398f00.b6f78","name":"Запуск","topic":"SELECT TARGET_TEMP FROM THERMOSTATS WHERE THERMOSTAT_NO=1;","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":656,"wires":[[]]},{"id":"24cf8d77.e6c132","type":"mqtt in","z":"a8398f00.b6f78","name":"","topic":"tele/thermostat_ext_sensor/SENSOR","qos":"0","datatype":"json","broker":"943c23bf.fcecb","x":166,"y":88,"wires":[["b776ba9c.bb332"]]},{"id":"b776ba9c.bb332","type":"function","z":"a8398f00.b6f78","name":"Темп/Влаж в HomeKit","func":"var newMsg, newpayload = {};\n\nif (msg.payload.DHT11.Temperature !== undefined) {\n    newpayload.CurrentTemperature = msg.payload.DHT11.Temperature\n        } else {\n            node.warn(\"Temperature Sensor offline and: \" + msg.payload.DHT11.Temperature);\n}\n\nif (msg.payload.DHT11.Humidity !== undefined) {\n    newpayload.CurrentRelativeHumidity = msg.payload.DHT11.Humidity\n        } else {\n            node.warn(\"Humidity Sensor offline and: \" + msg.payload.DHT11.Temperature);\n}\n\nnewMsg = { \"payload\": newpayload }\nreturn newMsg;","outputs":1,"noerr":0,"x":300,"y":136,"wires":[["3a835329.ea1704"]]},{"id":"761f20e6.51472","type":"mqtt out","z":"a8398f00.b6f78","name":"cmnd/thermostat/POWER","topic":"cmnd/thermostat/POWER","qos":"1","retain":"","broker":"943c23bf.fcecb","x":590,"y":256,"wires":[]},{"id":"10a224dd.3c6dcb","type":"debug","z":"a8398f00.b6f78","name":"Дебаг msg.topic","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"topic","targetType":"msg","x":866,"y":504,"wires":[]},{"id":"247df378.420354","type":"function","z":"a8398f00.b6f78","name":"В Реле","func":"var Thermostat1 = global.get(\"Thermostat1\");\nvar newpayload, newMsg;\n\nif ((Thermostat1.CurrentTemperature >= Thermostat1.TargetTemperature) && (Thermostat1.State == \"ON\")) {\n    //node.warn(\"Too warm\");\n    newpayload = \"OFF\"\n} else if ((Thermostat1.CurrentTemperature < Thermostat1.TargetTemperature) && (Thermostat1.State == \"OFF\")) {\n    //node.warn(\"Too cold\");\n    newpayload = \"ON\"\n}\n\nnode.warn(\"Current is: \" + Thermostat1.CurrentTemperature + \" / Target is: \" + Thermostat1.TargetTemperature);\n\nnewMsg = { \"payload\": newpayload }\nreturn newMsg;","outputs":1,"noerr":0,"x":260,"y":224,"wires":[["761f20e6.51472","e4d5b6db.db8a2"]]},{"id":"93a543e5.7e3118","type":"inject","z":"a8398f00.b6f78","name":"Проверка","topic":"","payload":"","payloadType":"date","repeat":"10","crontab":"","once":true,"onceDelay":0.1,"x":86,"y":184,"wires":[["247df378.420354","a42eeb72.feb288","e217f56c.3c60a8"]]},{"id":"8826beba.b5f98","type":"sqlite","z":"a8398f00.b6f78","mydb":"d9900ef1.fcb278","sqlquery":"msg.topic","sql":"","name":"Thermostat DB","x":288,"y":760,"wires":[[]]},{"id":"dfc12f5d.f9139","type":"sqlite","z":"a8398f00.b6f78","mydb":"d9900ef1.fcb278","sqlquery":"msg.topic","sql":"","name":"Thermostat DB","x":264,"y":704,"wires":[[]]},{"id":"a42eeb72.feb288","type":"function","z":"a8398f00.b6f78","name":"В HomeKit","func":"var Thermostat1 = global.get(\"Thermostat1\");\nvar newMsg, newpayload = {};\n\nnewpayload.TargetTemperature = Thermostat1.TargetTemperature;\n\nif (Thermostat1.CurrentTemperature >= Thermostat1.TargetTemperature) {\n    //node.warn(\"Too warm\");\n    newpayload.TargetHeatingCoolingState = 0;\n    newpayload.CurrentHeatingCoolingState = 0\n} else {\n    //node.warn(\"Too cold\");\n    newpayload.TargetHeatingCoolingState = 1;\n    newpayload.CurrentHeatingCoolingState = 1\n}\n\n//node.warn(newpayload.TargetHeatingCoolingState);\n\nnewMsg = { \"payload\": newpayload }\nreturn newMsg;","outputs":1,"noerr":0,"x":270,"y":184,"wires":[["3a835329.ea1704"]]},{"id":"307a85bd.74e6c2","type":"mqtt in","z":"a8398f00.b6f78","name":"tele/thermostat/STATE","topic":"tele/thermostat/STATE","qos":"1","datatype":"json","broker":"943c23bf.fcecb","x":116,"y":32,"wires":[["e446147a.65ae88"]]},{"id":"e446147a.65ae88","type":"function","z":"a8398f00.b6f78","name":"Состояние Реле в HomeKit","func":"var Thermostat1 = global.get(\"Thermostat1\");\nvar newMsg, newpayload = {};\n\nif (msg.payload.POWER == \"ON\") {\n    newpayload.CurrentHeatingCoolingState = 1;\n    global.set(\"Thermostat1.State\", \"ON\")\n        } else if (msg.payload.POWER == \"OFF\") {\n            newpayload.CurrentHeatingCoolingState = 0;\n            global.set(\"Thermostat1.State\", \"OFF\")\n}\n\nnewMsg = { \"payload\": newpayload }\nreturn newMsg;","outputs":1,"noerr":0,"x":360,"y":32,"wires":[["3a835329.ea1704"]]},{"id":"e217f56c.3c60a8","type":"function","z":"a8398f00.b6f78","name":"Ошибколовка","func":"var Thermostat1 = global.get(\"Thermostat1\");\nvar newMsg, newpayload = {};\n\n//node.warn(\"Thermostat1.CurrentTemperature is: \" + Thermostat1.CurrentTemperature)\n\nif (!Thermostat1.CurrentTemperature) {\n    node.warn(\"FAILED Current Temperature: \" + Thermostat1.CurrentTemperature)\n}\n\nnewMsg = { \"payload\": newpayload }\nreturn newMsg;","outputs":1,"noerr":0,"x":280,"y":264,"wires":[[]]},{"id":"2cc9c5e1.8277ba","type":"debug","z":"a8398f00.b6f78","name":"Дебаг HAP","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":846,"y":464,"wires":[]},{"id":"d25a5d54.3ef16","type":"file","z":"a8398f00.b6f78","name":"save TH settings","filename":"/home/pi/settings/Thermostat1.json","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":898,"y":736,"wires":[[]]},{"id":"7368819.1ac238","type":"function","z":"a8398f00.b6f78","name":"","func":"var Thermostat1 = global.get(\"Thermostat1\");\nvar newMsg;\n\nnewMsg = { \"payload\": Thermostat1}\n\nreturn newMsg;","outputs":1,"noerr":0,"x":738,"y":736,"wires":[["d25a5d54.3ef16"]]},{"id":"9cd0f808.02f108","type":"inject","z":"a8398f00.b6f78","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":592,"y":736,"wires":[["7368819.1ac238"]]},{"id":"6057a20b.0faa24","type":"file in","z":"a8398f00.b6f78","name":"Получаем настройки","filename":"/home/pi/settings/Thermostat1.json","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":668,"y":80,"wires":[["4d6a78a7.4e419"]]},{"id":"5bc3e9b.a917518","type":"function","z":"a8398f00.b6f78","name":"Устанавливаем глобальные переменные","func":"var Thermostat1 = msg.payload;\nglobal.set(\"Thermostat1\", Thermostat1);\n\nreturn Thermostat1;","outputs":1,"noerr":0,"x":994,"y":80,"wires":[[]]},{"id":"a0c3d783.0d8e6","type":"inject","z":"a8398f00.b6f78","name":"Запуск","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":612,"y":32,"wires":[["6057a20b.0faa24"]]},{"id":"4d6a78a7.4e419","type":"json","z":"a8398f00.b6f78","name":"","property":"payload","action":"","pretty":true,"x":794,"y":32,"wires":[["5bc3e9b.a917518"]]},{"id":"b7536669.a21a48","type":"file","z":"a8398f00.b6f78","name":"Данные в файл","filename":"/home/pi/settings/Thermostat1.json","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":864,"y":160,"wires":[[]]},{"id":"f273f04d.fc895","type":"homekit-service","z":"a8398f00.b6f78","isParent":false,"bridge":"","parentService":"3a835329.ea1704","name":"Температура","serviceName":"TemperatureSensor","topic":"","filter":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":904,"y":240,"wires":[[]]},{"id":"8d622a65.0db188","type":"homekit-service","z":"a8398f00.b6f78","isParent":false,"bridge":"","parentService":"3a835329.ea1704","name":"Влажность","serviceName":"HumiditySensor","topic":"","filter":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":890,"y":280,"wires":[[]]},{"id":"1f4da0a9.4023c7","type":"homekit-bridge","z":"","bridgeName":"villa-test","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"ptath","model":"raspberry pi zeroW","serialNo":"12345678"},{"id":"943c23bf.fcecb","type":"mqtt-broker","z":"","name":"villa","broker":"192.168.100.10","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""},{"id":"d9900ef1.fcb278","type":"sqlitedb","z":"","db":"/home/pi/sqlite/thermostat.db","mode":"RWC"}]

Снимок экрана 2019-04-25 в 0 34 34

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mtjoernelund picture mtjoernelund  ·  8Comments

Delphius7 picture Delphius7  ·  3Comments

sjorge picture sjorge  ·  7Comments

Barabba11 picture Barabba11  ·  3Comments

thomasssso picture thomasssso  ·  10Comments