Better way to do this flow?

I'm trying to cycle through 4 different lights from sunset to sunrise.
I'm sure there is a better/cleaner approach to this, looking for someone to point me in the right direction.

I think you need to give a bit more detail. Just took a quick look at your flow... are you trying to turn just one of the four lights on for 5 seconds every hour in a sequence, or ALL the lights on together??

Last question... what are the name of the nodes shown in your flow??

I am trying to turn on 1 of the 4 lights for 1 hour , after 1 hr, turn off the light,5 sec delay and then turn on the 2nd one. the 5s delay isn't required, I just used it for debugging manually.
I'm using the Home assistant service call nodes (SVC). State nodes to check the state of the sun.


Sorry I'm not familiar with Home Assistant - but I'm sure someone else will jump in to help.

Just thinking off the top of my head... I would do something like using BigTimer or Cron-Plus to determine the period between sunset and sunrise and use this fact to set a variable to act as a 'gate'. Then trigger a counter every hour that counts 0,1,2,3 and resets. Then decode the value of the counter to determine which light to operate.

I'm busy at the moment, but as soon as I get some spare time I'll cobble a flow together.

Can I ask what is the purpose of this flow? Are the lights embedded in some kind of display? Also should the sequence cycle all day until the sun is below_horizon?

There are 4 lights in my patio, which I want them on from sunset to sunrise. Didnt need all 4 to be on as it would be too bright, so came up with the idea of cycling through them to keep the usage of them equal.

Are they on dimmer control or just a binary relay (on/off)?

They are on a binary relay - On/Off

Just had a few spare minutes to knock-up a flow for you to try. You will need to edit the function nodes so the flow 'talks' to Home Assistant and enter your Lat/Lon values so sunset/sunrise are correct for your locality. It's not the most efficient flow as I wrote it so it would be easy to understand what's going on.


four_lights.json (11.2 KB)

[{"id":"2d6215b8.ac8242","type":"function","z":"77ce1e39d14f8570","name":"Pass on if Timer is ON","func":"var timer = flow.get(\"timer\");\n\nif (timer == \"on\") {\n   msg.payload = 1;\n  node.status({ fill: \"green\", shape: \"dot\", text: \"Pass is ON\" });\n   return msg;\n}\nelse {\n  node.status({ fill: \"red\", shape: \"dot\", text: \"Pass is OFF\" });\n  return null;\n}\n","outputs":"1","noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":300,"wires":[["a21c12f206b98026"]]},{"id":"d6b184e3.01de58","type":"function","z":"77ce1e39d14f8570","name":"Timer On/Off","func":"if (msg.payload == 1)\n    {\n     flow.set(\"timer\",\"on\");\n     node.status({fill:\"green\",shape:\"dot\",text:\"Timer is ON\"});\n    }\nelse if (msg.payload === 0)\n    {\n     flow.set(\"timer\",\"off\");\n     flow.set(\"counter\",0);\n     node.status({fill:\"red\",shape:\"dot\",text:\"Timer is OFF\"});\n    }","outputs":"0","noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":200,"wires":[]},{"id":"9c07f928.96aca8","type":"bigtimer","z":"77ce1e39d14f8570","outtopic":"","outpayload1":"","outpayload2":"","name":"Main Timer","comment":"","lat":"51.35","lon":"-0.87","starttime":"5004","endtime":"5003","startoff":"0","endoff":0,"startoff2":"","endoff2":"","offs":0,"outtext1":"","outtext2":"","timeout":" ","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"day6":"","month6":"","day7":"","month7":"","day8":"","month8":"","day9":"","month9":"","day10":"","month10":"","day11":"","month11":"","day12":"","month12":"","d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"d6":"","w6":"","xday1":"","xmonth1":"","xday2":"","xmonth2":"","xday3":"","xmonth3":"","xday4":"","xmonth4":"","xday5":"","xmonth5":"","xday6":"","xmonth6":"","xday7":"","xmonth7":"","xday8":"","xmonth8":"","xday9":"","xmonth9":"","xday10":"","xmonth10":"","xday11":"","xmonth11":"","xday12":"","xmonth12":"","xd1":"","xw1":"","xd2":"","xw2":"","xd3":"","xw3":"","xd4":"","xw4":"","xd5":"","xw5":"","xd6":"","xw6":"","suspend":false,"random":false,"randon1":false,"randoff1":false,"randon2":false,"randoff2":false,"repeat":true,"atstart":true,"odd":false,"even":false,"x":150,"y":200,"wires":[[],["d6b184e3.01de58"],[]]},{"id":"f96c64d6c1127f02","type":"inject","z":"77ce1e39d14f8570","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"1","payloadType":"num","x":150,"y":80,"wires":[["d7b9b40635550468"]]},{"id":"d7b9b40635550468","type":"change","z":"77ce1e39d14f8570","name":"Reset counter to ZERO at start-up","rules":[{"t":"set","p":"counter","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":80,"wires":[[]]},{"id":"543a79b51818bc87","type":"inject","z":"77ce1e39d14f8570","name":"","props":[{"p":"payload"}],"repeat":"5","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":150,"y":300,"wires":[["2d6215b8.ac8242"]]},{"id":"a21c12f206b98026","type":"function","z":"77ce1e39d14f8570","name":"Increment the counter","func":"let counter = flow.get(\"counter\") || 0\n\nif (counter < 3) {\n    counter = counter + 1;\n}\nelse {\n    counter = 0\n}\n\nnode.status({ fill: \"red\", shape: \"ring\", text: \"Counter = \"+counter });\n\nflow.set(\"counter\", counter);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":300,"wires":[["ffec11c50d660888","47179848709b368f","0bd994fa22b552f9","1689d8b90a2952a8"]]},{"id":"ffec11c50d660888","type":"function","z":"77ce1e39d14f8570","name":"Decode light-0","func":"let counter = flow.get(\"counter\") || 0\n\nif (counter == 0) {\n    node.status({ fill: \"green\", shape: \"dot\", text: \"Light is ON\" });\n    msg.payload = 1;\n}\nelse {\n    node.status({ fill: \"red\", shape: \"dot\", text: \"Light is OFF\" });\n    msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":300,"wires":[["7ac732e436b4bbbb"]]},{"id":"47179848709b368f","type":"function","z":"77ce1e39d14f8570","name":"Decode light-1","func":"let counter = flow.get(\"counter\") || 0\n\nif (counter == 1) {\n    node.status({ fill: \"green\", shape: \"dot\", text: \"Light is ON\" });\n    msg.payload = 1;\n}\nelse {\n    node.status({ fill: \"red\", shape: \"dot\", text: \"Light is OFF\" });\n    msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":380,"wires":[["5c8efed0c3bdc0c5"]]},{"id":"0bd994fa22b552f9","type":"function","z":"77ce1e39d14f8570","name":"Decode light-2","func":"let counter = flow.get(\"counter\") || 0\n\nif (counter == 2) {\n    node.status({ fill: \"green\", shape: \"dot\", text: \"Light is ON\" });\n    msg.payload = 1;\n}\nelse {\n    node.status({ fill: \"red\", shape: \"dot\", text: \"Light is OFF\" });\n    msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":460,"wires":[["142888aea163b5a9"]]},{"id":"1689d8b90a2952a8","type":"function","z":"77ce1e39d14f8570","name":"Decode light-3","func":"let counter = flow.get(\"counter\") || 0\n\nif (counter == 3) {\n    node.status({ fill: \"green\", shape: \"dot\", text: \"Light is ON\" });\n    msg.payload = 1;\n}\nelse {\n    node.status({ fill: \"red\", shape: \"dot\", text: \"Light is OFF\" });\n    msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":540,"wires":[["d054669d3a7e3f95"]]},{"id":"197f0e9d7a72573a","type":"comment","z":"77ce1e39d14f8570","name":"Change this to 1 hr after you have tested it","info":"","x":240,"y":360,"wires":[]},{"id":"7ac732e436b4bbbb","type":"debug","z":"77ce1e39d14f8570","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":300,"wires":[]},{"id":"5c8efed0c3bdc0c5","type":"debug","z":"77ce1e39d14f8570","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":380,"wires":[]},{"id":"142888aea163b5a9","type":"debug","z":"77ce1e39d14f8570","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":460,"wires":[]},{"id":"d054669d3a7e3f95","type":"debug","z":"77ce1e39d14f8570","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":540,"wires":[]},{"id":"b325213ad5a97e0b","type":"comment","z":"77ce1e39d14f8570","name":"Need to edit these function nodes to talk to Home Assistant","info":"","x":980,"y":260,"wires":[]},{"id":"106a671b5c7ed4c8","type":"comment","z":"77ce1e39d14f8570","name":"Put YOUR Lat/Lon values in BigTimer","info":"","x":230,"y":140,"wires":[]}]

It's amazing what a few hours sleep will do to refresh the brain!!
The previous flow had some shortcomings which I think are addressed by this new and improved version.

[{"id":"c62f0b4e734bc6ec","type":"function","z":"7c7ea5f95ec78845","name":"Pass on if Timer is ON","func":"var timer = flow.get(\"timer\");\n\nif (timer == \"on\") {\n   msg.payload = 1;\n  node.status({ fill: \"green\", shape: \"dot\", text: \"Pass is ON\" });\n   return msg;\n}\nelse {\n  node.status({ fill: \"red\", shape: \"dot\", text: \"Pass is OFF\" });\n  return null;\n}\n","outputs":"1","noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":340,"wires":[["a4c1a128402682fe"]]},{"id":"e42bc3cb603110e9","type":"function","z":"7c7ea5f95ec78845","name":"Timer On/Off","func":"if (msg.payload == 1)\n    {\n     flow.set(\"timer\",\"on\");\n     node.status({fill:\"green\",shape:\"dot\",text:\"Timer is ON\"});\n    }\nelse if (msg.payload === 0)\n    {\n     flow.set(\"timer\",\"off\");\n     flow.set(\"counter\",0);\n     node.status({fill:\"red\",shape:\"dot\",text:\"Timer is OFF\"});\n    }","outputs":"0","noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":280,"wires":[]},{"id":"8ed7c0fe3ca85a9f","type":"bigtimer","z":"7c7ea5f95ec78845","outtopic":"","outpayload1":"","outpayload2":"","name":"Main Timer","comment":"","lat":"51.35","lon":"0.0","starttime":"5004","endtime":"5003","startoff":"0","endoff":0,"startoff2":"","endoff2":"","offs":0,"outtext1":"","outtext2":"","timeout":" ","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"day6":"","month6":"","day7":"","month7":"","day8":"","month8":"","day9":"","month9":"","day10":"","month10":"","day11":"","month11":"","day12":"","month12":"","d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"d6":"","w6":"","xday1":"","xmonth1":"","xday2":"","xmonth2":"","xday3":"","xmonth3":"","xday4":"","xmonth4":"","xday5":"","xmonth5":"","xday6":"","xmonth6":"","xday7":"","xmonth7":"","xday8":"","xmonth8":"","xday9":"","xmonth9":"","xday10":"","xmonth10":"","xday11":"","xmonth11":"","xday12":"","xmonth12":"","xd1":"","xw1":"","xd2":"","xw2":"","xd3":"","xw3":"","xd4":"","xw4":"","xd5":"","xw5":"","xd6":"","xw6":"","suspend":false,"random":false,"randon1":false,"randoff1":false,"randon2":false,"randoff2":false,"repeat":true,"atstart":true,"odd":false,"even":false,"x":130,"y":240,"wires":[[],["2782e1a93614e5fb","e42bc3cb603110e9"],[]]},{"id":"5192017706220311","type":"inject","z":"7c7ea5f95ec78845","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"reset","payload":"1","payloadType":"num","x":140,"y":120,"wires":[["52153ea8188aa56b","a4c1a128402682fe"]]},{"id":"52153ea8188aa56b","type":"change","z":"7c7ea5f95ec78845","name":"Reset counter to ZERO at start-up","rules":[{"t":"set","p":"counter","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":120,"wires":[[]]},{"id":"b94989a9a664bc14","type":"inject","z":"7c7ea5f95ec78845","name":"","props":[{"p":"payload"}],"repeat":"5","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":130,"y":340,"wires":[["c62f0b4e734bc6ec"]]},{"id":"a4c1a128402682fe","type":"function","z":"7c7ea5f95ec78845","name":"Increment the counter","func":"let counter = flow.get(\"counter\") || 0\n\nif (msg.topic == \"reset\") {\n    counter = 0\n}\n\nelse if (counter < 3) {\n    counter = counter + 1;\n}\nelse {\n    counter = 0\n}\n\nnode.status({ fill: \"red\", shape: \"dot\", text: \"Counter = \" + counter });\n\nflow.set(\"counter\", counter);\n\nreturn null;","outputs":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":340,"wires":[]},{"id":"4e20148836494f6d","type":"function","z":"7c7ea5f95ec78845","name":"Decode light-0","func":"let timer = flow.get(\"timer\") || \"off\";\nlet counter = flow.get(\"counter\") || 0\n\nif ((timer == \"on\") && (counter == 0)) {\n    node.status({ fill: \"green\", shape: \"dot\", text: \"Light is ON\" });\n    msg.payload = 1;\n}\nelse {\n    node.status({ fill: \"red\", shape: \"dot\", text: \"Light is OFF\" });\n    msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":240,"wires":[["588ec8aa0e6ee801"]]},{"id":"47b711902ab2816c","type":"function","z":"7c7ea5f95ec78845","name":"Decode light-1","func":"let timer = flow.get(\"timer\") || \"off\";\nlet counter = flow.get(\"counter\") || 0\n\nif ((timer = \"on\") && (counter == 1)) {\n    node.status({ fill: \"green\", shape: \"dot\", text: \"Light is ON\" });\n    msg.payload = 1;\n}\nelse {\n    node.status({ fill: \"red\", shape: \"dot\", text: \"Light is OFF\" });\n    msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":300,"wires":[["477fd5273c7fc2e5"]]},{"id":"b7a55c3511d252bb","type":"function","z":"7c7ea5f95ec78845","name":"Decode light-2","func":"let timer = flow.get(\"timer\") || \"off\";\nlet counter = flow.get(\"counter\") || 0\n\nif ((timer == \"on\") && (counter == 2)) {\n    node.status({ fill: \"green\", shape: \"dot\", text: \"Light is ON\" });\n    msg.payload = 1;\n}\nelse {\n    node.status({ fill: \"red\", shape: \"dot\", text: \"Light is OFF\" });\n    msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":360,"wires":[["e4ea84e1bd622b7d"]]},{"id":"787f1f6e9d5a7a80","type":"function","z":"7c7ea5f95ec78845","name":"Decode light-3","func":"let timer = flow.get(\"timer\") || \"off\";\nlet counter = flow.get(\"counter\") || 0\n\nif ((timer == \"on\") && (counter == 3)) {\n    node.status({ fill: \"green\", shape: \"dot\", text: \"Light is ON\" });\n    msg.payload = 1;\n}\nelse {\n    node.status({ fill: \"red\", shape: \"dot\", text: \"Light is OFF\" });\n    msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":420,"wires":[["05a440d2ad0cf391"]]},{"id":"24e18aa74574188e","type":"comment","z":"7c7ea5f95ec78845","name":"Change this to 1 hr after you have tested it","info":"","x":220,"y":440,"wires":[]},{"id":"588ec8aa0e6ee801","type":"debug","z":"7c7ea5f95ec78845","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1030,"y":240,"wires":[]},{"id":"477fd5273c7fc2e5","type":"debug","z":"7c7ea5f95ec78845","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1030,"y":300,"wires":[]},{"id":"e4ea84e1bd622b7d","type":"debug","z":"7c7ea5f95ec78845","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1030,"y":360,"wires":[]},{"id":"05a440d2ad0cf391","type":"debug","z":"7c7ea5f95ec78845","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1030,"y":420,"wires":[]},{"id":"dae9429f16cb1d5f","type":"comment","z":"7c7ea5f95ec78845","name":"Need to edit these function nodes to talk to Home Assistant","info":"","x":880,"y":200,"wires":[]},{"id":"a6c0ddbf54892119","type":"comment","z":"7c7ea5f95ec78845","name":"Put YOUR Lat/Lon values in BigTimer","info":"","x":210,"y":180,"wires":[]},{"id":"2782e1a93614e5fb","type":"link out","z":"7c7ea5f95ec78845","name":"Main_Clock_OUT","links":["aa8b532d2facc42f"],"x":255,"y":240,"wires":[]},{"id":"aa8b532d2facc42f","type":"link in","z":"7c7ea5f95ec78845","name":"Clk_IN","links":["2782e1a93614e5fb"],"x":675,"y":240,"wires":[["4e20148836494f6d","47b711902ab2816c","b7a55c3511d252bb","787f1f6e9d5a7a80"]]},{"id":"3a153091578c3e34","type":"comment","z":"7c7ea5f95ec78845","name":"For testing, you'll probably need to set this to every 2 minutes","info":"For testing, you'll probably need to set this to every 2 minutes","x":280,"y":400,"wires":[]}]

In the original flow the lights would change every hour - which is what you wanted. The shortcoming was it could take up-to an hour for a light to go off after sunrise - not very nice.

In this version I'm using the 1-minute output from BigTimer to act as a sort of 'system clock'. This is used by the four decode nodes so they perform a check every minute, which means it would only take a minute after sunrise to turn the lights off - neat eh? Also saves electricity, money and the planet.

The other improvement is all lights are forced OFF when the Timer is "off". I think in the original version there may have been a chance that a light remained "on" at sunrise.

You will need to do some tests and see if there are any edge-cases I've missed. I suggest you set the Inject node, below BigTimer, to repeat every 2-minutes during your initial tests.

2 Likes

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.