How To Send Sync Pulse For Light Timer?

I have a simple flow using a RPi to control lights. It uses the rpi-gpio in and rpi-gpio out nodes with a time out trigger and toggle node in between.

The flow works just fine. With each input, the relay will toggle on and off as long as its not the time out trigger that turned the relay off.

However if the time out trigger does turn off the relay, then it takes two inputs cycles to turn the relay back on since the flow is out of sequence.

Since this light will be used by several people, I would like to eliminate the confusion of the light not turning back on after it has timed out without a second push of the button.

[{"id":"6c4e53bf.97148c","type":"subflow","name":"Toggle 1/0","info":"","category":"","in":[{"x":60,"y":180,"wires":[{"id":"5047f5ea.66c1ec"}]}],"out":[{"x":780,"y":160,"wires":[{"id":"82ff5a1a.efefc8","port":0},{"id":"26637948.29d256","port":0}]}],"env":[],"color":"#DDAA99"},{"id":"7347b78.8b23848","type":"switch","z":"6c4e53bf.97148c","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"0","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":390,"y":180,"wires":[["82ff5a1a.efefc8"],["26637948.29d256"]]},{"id":"82ff5a1a.efefc8","type":"change","z":"6c4e53bf.97148c","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"str"},{"t":"set","p":"next","pt":"flow","to":"0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":140,"wires":[[]]},{"id":"26637948.29d256","type":"change","z":"6c4e53bf.97148c","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"str"},{"t":"set","p":"next","pt":"flow","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":200,"wires":[[]]},{"id":"5047f5ea.66c1ec","type":"function","z":"6c4e53bf.97148c","name":"get next value","func":"msg.payload = flow.get(\"next\")||0;\nreturn msg;","outputs":1,"noerr":0,"x":200,"y":180,"wires":[["7347b78.8b23848"]]},{"id":"2000d610.24a2ca","type":"rpi-gpio in","z":"29688e2c.d40952","name":"Input 5","pin":"31","intype":"tri","debounce":"25","read":false,"x":190,"y":1300,"wires":[["b19b39b8.67a318"]]},{"id":"68f01d6b.784514","type":"rpi-gpio out","z":"29688e2c.d40952","name":"Output 6","pin":"36","set":"","level":"0","freq":"","out":"out","x":1100,"y":1300,"wires":[]},{"id":"175a97eb.fbf888","type":"timeouttrigger","z":"29688e2c.d40952","ontimeouttype":"str","ontimeoutval":"1","duration":"5","units":"s","name":"","x":870,"y":1300,"wires":[["68f01d6b.784514"]]},{"id":"b5f6c566.5af8d8","type":"subflow:6c4e53bf.97148c","z":"29688e2c.d40952","name":"","env":[],"x":670,"y":1300,"wires":[["175a97eb.fbf888"]]},{"id":"b19b39b8.67a318","type":"switch","z":"29688e2c.d40952","name":"pass only 1s block 0s","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":440,"y":1300,"wires":[["b5f6c566.5af8d8"]]}]

Hello,
I changed your flow a little bit and it should work like you want it now (detailed explanation below):


[{"id":"3e7c05a9.acc372","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"1fe52d55.d9dacb","type":"switch","z":"3e7c05a9.acc372","name":"pass only 1s block 0s","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":320,"y":100,"wires":[["a24d5f97.39bbd8"]]},{"id":"a24d5f97.39bbd8","type":"function","z":"3e7c05a9.acc372","name":"toggle 1/0","func":"let toggle = flow.get(\"toggle\") || 0;\nif(toggle === 0){\n    msg.payload = 1;\n    return [msg, null];\n} else {\n    msg.payload = 0;\n    msg.reset = true;\n    return [null, msg];\n}","outputs":2,"noerr":0,"x":520,"y":100,"wires":[["c1f04b0f.4e215"],["7e38ae2c.2b012","c1f04b0f.4e215"]]},{"id":"c1f04b0f.4e215","type":"trigger","z":"3e7c05a9.acc372","op1":"","op2":"0","op1type":"pay","op2type":"num","duration":"5","extend":true,"units":"s","reset":"0","bytopic":"all","name":"","x":700,"y":80,"wires":[["7e38ae2c.2b012"]]},{"id":"7e38ae2c.2b012","type":"change","z":"3e7c05a9.acc372","name":"","rules":[{"t":"set","p":"toggle","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":120,"wires":[["c855bbdd.2380c8"]]},{"id":"1e1c813e.537d5f","type":"inject","z":"3e7c05a9.acc372","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":100,"wires":[["1fe52d55.d9dacb"]]},{"id":"c855bbdd.2380c8","type":"debug","z":"3e7c05a9.acc372","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1070,"y":100,"wires":[]}]

(i exchanged the gpios for an inject and a debug, as i haven’t got anything connected to my pi but that shouldn’t matter)
What i did is i used a generic trigger node instead of the timeout and substituted your subflow with a single function node that checks a flow variable “toggle” and returns 1 for 0 and vice versa. The function node has two outputs. 1’s get returned on the first and 0’s on the second. Messages on the second output also include a msg.reset property.
Now comes the trigger node. It gets triggered by everything coming from the first output of the function node (1’s) and just outputs the msg that came in as is immediately.
after five seconds it returns a 0 (your timeout).
When somebody presses the button in the meantime before the five seconds are over it gets stopped and never sends anything as you can stop a trigger node with a msg.reset property in the msg object and this property gets attached to every 0 from the function node and the second output of the function node (0’s) is connected both to the trigger node and the change node at the end.
Right at the end we set the flow.toggle variable to whatever payload gets send to the gpio with this change node. So flow.toggle is always synchronized and it doesn’t matter if the payload came from a timeout or a button push.
I hope this is what you wanted.
best regards Johannes

Johannes, your flow appears to be exactly what I needed! Function nodes are beyond my ability to write and have to beg and borrow what I can find. I did spend many hours googling and trying various existing nodes without success. Maybe I need to put you on a retainer for my future applications? :smile:

1 Like

Always happy to help

JGKK, Here's something I found during further shake down after adding a second flow. It seems the addition of the second flow has caused an interaction between the two flows.

If input #1 has triggered the timer, then input #2 can not be triggered without pushing the #2 input button (or inject node) twice. If the first triggered flow is allowed to expire, then it only takes a single inject on the second flow to get it started.

If input #2 is triggered first, then the same result happens to input #1.

An idea why it appears one flow is influencing the other?

If they are on the same tab you will have to use a unique flow variable for each button.
So change the name of the flow variable toggle in the change node and change the function node to get that flow variable that is unique to the button.
here is an example:


[{"id":"57539422.5c24bc","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"43cb19ca.e08cd8","type":"switch","z":"57539422.5c24bc","name":"pass only 1s block 0s","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":320,"y":100,"wires":[["52e2f30f.a70994"]]},{"id":"52e2f30f.a70994","type":"function","z":"57539422.5c24bc","name":"toggle 1/0","func":"let toggle = flow.get(\"toggle1\") || 0;\nif(toggle === 0){\n    msg.payload = 1;\n    return [msg, null];\n} else {\n    msg.payload = 0;\n    msg.reset = true;\n    return [null, msg];\n}","outputs":2,"noerr":0,"x":520,"y":100,"wires":[["4374fc8f.e4d03c"],["7970e311.0bcc5c","4374fc8f.e4d03c"]]},{"id":"4374fc8f.e4d03c","type":"trigger","z":"57539422.5c24bc","op1":"","op2":"0","op1type":"pay","op2type":"num","duration":"5","extend":true,"units":"s","reset":"0","bytopic":"all","name":"","x":700,"y":80,"wires":[["7970e311.0bcc5c"]]},{"id":"7970e311.0bcc5c","type":"change","z":"57539422.5c24bc","name":"","rules":[{"t":"set","p":"toggle1","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":120,"wires":[["8cc3c716.7ba2b8"]]},{"id":"6ee9c597.a31d3c","type":"inject","z":"57539422.5c24bc","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":100,"wires":[["43cb19ca.e08cd8"]]},{"id":"141840e7.bbc4f7","type":"switch","z":"57539422.5c24bc","name":"pass only 1s block 0s","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":320,"y":220,"wires":[["c23c1125.8f4ce"]]},{"id":"c23c1125.8f4ce","type":"function","z":"57539422.5c24bc","name":"toggle 1/0","func":"let toggle = flow.get(\"toggle2\") || 0;\nif(toggle === 0){\n    msg.payload = 1;\n    return [msg, null];\n} else {\n    msg.payload = 0;\n    msg.reset = true;\n    return [null, msg];\n}","outputs":2,"noerr":0,"x":520,"y":220,"wires":[["804ee108.b77e18"],["804ee108.b77e18","844b522d.8408"]]},{"id":"804ee108.b77e18","type":"trigger","z":"57539422.5c24bc","op1":"","op2":"0","op1type":"pay","op2type":"num","duration":"5","extend":true,"units":"s","reset":"0","bytopic":"all","name":"","x":700,"y":200,"wires":[["844b522d.8408"]]},{"id":"cb6d3d50.b82008","type":"inject","z":"57539422.5c24bc","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":220,"wires":[["141840e7.bbc4f7"]]},{"id":"844b522d.8408","type":"change","z":"57539422.5c24bc","name":"","rules":[{"t":"set","p":"toggle2","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":240,"wires":[["d5c837a6.f6a178"]]},{"id":"8cc3c716.7ba2b8","type":"debug","z":"57539422.5c24bc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1090,"y":100,"wires":[]},{"id":"d5c837a6.f6a178","type":"debug","z":"57539422.5c24bc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1090,"y":220,"wires":[]}]

Johannes

Works perfectly!! In fact I will be adding a third flow but can use your template. Thanks for providing actual flows instead of just describing a solution. I read many solutions to others problems and still don't know how to proceed.

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