I have discussed build up of my flow in another post, where I got a lot of good help. However I could not completely understand that flow, particularly how function code works and was afraid to put it to control real greenhouse door. So I built my own function code and it seems to work with my inhouse testing. I have one week to put it in place and would really appreciate if someone could verify my thinking
The idea is based on temp reading that I save into "Temp-Air1" flow context via another flow. I have then check it vs context "position" value and calculate "tm" (time to move) value, which is also save to flow context. It can be either negative or positive, which allows me to use switch and call either "Open" or "Close" action within Home Assistant. I then use delay node to wait for x amount of seconds saved in context "tm". After that, I send "Stop" action within Home Assistant to stop door opener.
[{"id":"88de674f.e0ed78","type":"function","z":"123bd5e5.5a9a9a","name":"","func":"var current = flow.get(\"Temp-Air1\") || 0;\nvar position = flow.get(\"position\") || 0;\nnode.warn([\"current=\",current]);\nnode.warn([\"position=\",position]);\nif(current < 20 ){\n tm=0-position\n flow.set('position',0);\n}else if(current > 26){\n tm=48-position\n flow.set('position',48);\n}else if(current <= 22){\n tm=12-position\n flow.set('position',12);\n}else if(current <= 24){\n tm=24-position\n flow.set('position',24);\n}else if(current <= 26){\n tm=36-position\n flow.set('position',36);\n}\n\nif (tm === 0) { return null; }\nif (tm<0){\n msg.payload = \"close_cover\";\n} else if (tm>0){\n msg.payload = \"open_cover\";\n}\n\n\nflow.set(\"tm\", tm)\nnode.warn([\"tm=\",tm]);\n\nmsg.payload=tm\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":280,"y":1400,"wires":[["7adb187b.c32098"]]},{"id":"d99dbe66.4b9fb","type":"inject","z":"123bd5e5.5a9a9a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":1400,"wires":[["88de674f.e0ed78"]]},{"id":"7adb187b.c32098","type":"switch","z":"123bd5e5.5a9a9a","name":"","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"0","vt":"str"},{"t":"lt","v":"0","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":1400,"wires":[["2a40cc86.3f3af4"],["672d3423.7827cc"]]},{"id":"672d3423.7827cc","type":"api-call-service","z":"123bd5e5.5a9a9a","name":"Close","server":"bbbd4030.fdb23","version":1,"debugenabled":false,"service_domain":"cover","service":"close_cover","entityId":"cover.bf9767fbce7a507ed4xp8g","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":590,"y":1440,"wires":[["79213eb.18dacc"]]},{"id":"2a40cc86.3f3af4","type":"api-call-service","z":"123bd5e5.5a9a9a","name":"Open","server":"bbbd4030.fdb23","version":1,"debugenabled":false,"service_domain":"cover","service":"open_cover","entityId":"cover.bf9767fbce7a507ed4xp8g","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":590,"y":1360,"wires":[["79213eb.18dacc"]]},{"id":"79213eb.18dacc","type":"function","z":"123bd5e5.5a9a9a","name":"","func":"var tm = flow.get(\"tm\") || 0;\nif (tm<0){\n tm=tm*(-1)\n}\nmsg.delay=tm*1000\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":740,"y":1420,"wires":[["e28387ff.3664d8"]]},{"id":"a396b36a.30e59","type":"api-call-service","z":"123bd5e5.5a9a9a","name":"Stop","server":"bbbd4030.fdb23","version":1,"debugenabled":false,"service_domain":"cover","service":"Stop_cover","entityId":"cover.bf9767fbce7a507ed4xp8g","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1050,"y":1420,"wires":[[]]},{"id":"e28387ff.3664d8","type":"delay","z":"123bd5e5.5a9a9a","name":"","pauseType":"delayv","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":900,"y":1420,"wires":[["a396b36a.30e59"]]},{"id":"39264bd4.fc5374","type":"group","z":"123bd5e5.5a9a9a","name":"This part for manual \"Temp-Air\" entry, for test purposes","style":{"label":true,"color":"#000000","stroke":"#7fb7df","fill":"#bfdbef"},"nodes":["c7538224.afc3a","cf2b35ab.a4d0c8","8533f7cc.1f1578","72409071.3eade","ff2f5a10.b95cb8","c12bec98.c794f"],"x":54,"y":1459,"w":392,"h":242},{"id":"c7538224.afc3a","type":"function","z":"123bd5e5.5a9a9a","g":"39264bd4.fc5374","name":"","func":"var output = msg.payload\nif (output>0)\n {flow.set('Temp-Air1',output);}\n\n\n\nnode.warn([\"position=\",output]);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":1500,"wires":[["88de674f.e0ed78"]]},{"id":"cf2b35ab.a4d0c8","type":"inject","z":"123bd5e5.5a9a9a","g":"39264bd4.fc5374","name":"19C - Position 0","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"19","payloadType":"num","x":180,"y":1500,"wires":[["c7538224.afc3a"]]},{"id":"8533f7cc.1f1578","type":"inject","z":"123bd5e5.5a9a9a","g":"39264bd4.fc5374","name":"21C - Position 12","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"21","payloadType":"num","x":180,"y":1540,"wires":[["c7538224.afc3a"]]},{"id":"72409071.3eade","type":"inject","z":"123bd5e5.5a9a9a","g":"39264bd4.fc5374","name":"23C - Position 24","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"23","payloadType":"num","x":180,"y":1580,"wires":[["c7538224.afc3a"]]},{"id":"ff2f5a10.b95cb8","type":"inject","z":"123bd5e5.5a9a9a","g":"39264bd4.fc5374","name":"25C - Position 36","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"25","payloadType":"num","x":180,"y":1620,"wires":[["c7538224.afc3a"]]},{"id":"c12bec98.c794f","type":"inject","z":"123bd5e5.5a9a9a","g":"39264bd4.fc5374","name":"28C - Position 48","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"28","payloadType":"num","x":180,"y":1660,"wires":[["c7538224.afc3a"]]},{"id":"bbbd4030.fdb23","type":"server","name":"Home Assistant","legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]
By the way, if you do not have Home Assistant nodes, those are very simple just issue one of three commands to the device (Open, Close or Stop). Those are tested, working fine and there is not complex code or variables there. My concern is mainly about first function, believe rest is correct even with my limited knowledge.
Concerns:
- Due to some code malfunction door will not completely close at cold temp, or will not completely open when it is hot. I think the function that I wrote should work fine. If, for example, door does not close completely when temp drops below 20C (in my case), then it will keep closing when next recurring timestamp will be called.
- Door will not move if RaspberryPi will hang, or HomeAssistant will hang, or Tuya service (needed to control device) will become irresponsive, or Wifi will fail, or electricity will fail. Do not have answer... But thinking of installing second temp readed, second RPI to cover those, also set some kind of warning system when some critical item from above list is down. To be continued...