Finite State Machine - example traffic light

1,222 views
Skip to first unread message

Julian Knight

unread,
May 20, 2017, 4:35:17 PM5/20/17
to Node-RED
Hi all, I had a quick go with KarstenJ's new node-red-contrib-fsm node.

I was able to create a simple single UK traffic light simulator quite easily. Might have some useful implications for IoT and home automation. I'd be interested to see if anyone can come up with an alternative flow not using the FSM node and that is as simple.





[{"id":"be9b26ff.594728","type":"FSM","z":"106ba95c.ff91e7","name":"Traffic Lights","topic":"TRAFFIC_LIGHTS","initstate":"RED","rules":[{"n":"Red to Red+Amber","c":"CHANGE","s":"RED","d":"RED_AMBER"},{"n":"Red+Amber to Green","c":"CHANGE","s":"RED_AMBER","d":"GREEN"},{"n":"Green to Amber","c":"CHANGE","s":"GREEN","d":"AMBER"},{"n":"Amber to Red","c":"CHANGE","s":"AMBER","d":"RED"}],"x":350,"y":940,"wires":[["82bcbf25.19329","5b8f5b6a.173fa4"]]},{"id":"202f52c2.6935be","type":"inject","z":"106ba95c.ff91e7","name":"","topic":"CHANGE","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"x":170,"y":940,"wires":[["be9b26ff.594728"]]},{"id":"82bcbf25.19329","type":"debug","z":"106ba95c.ff91e7","name":"","active":false,"console":"false","complete":"true","x":510,"y":900,"wires":[]},{"id":"25b66579.d5d4ba","type":"delay","z":"106ba95c.ff91e7","name":"Show Green for 20s","pauseType":"delay","timeout":"20","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1000,"y":1020,"wires":[["dbdf3ad8.496cd8"]]},{"id":"dbdf3ad8.496cd8","type":"change","z":"106ba95c.ff91e7","name":"CHANGE","rules":[{"t":"set","p":"topic","pt":"msg","to":"CHANGE","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":1200,"wires":[["be9b26ff.594728"]]},{"id":"5b8f5b6a.173fa4","type":"switch","z":"106ba95c.ff91e7","name":"entry\\exit\\transition","property":"topic","propertyType":"msg","rules":[{"t":"cont","v":"_entry","vt":"str"},{"t":"cont","v":"_exit","vt":"str"},{"t":"cont","v":"_transition","vt":"str"}],"checkall":"false","outputs":3,"x":550,"y":980,"wires":[["98f3ed88.16aa5"],[],["640cd93a.dc8278","143a5c37.2c2c24","37998186.0166ae","5fb0bfbe.fb63d"]]},{"id":"98f3ed88.16aa5","type":"debug","z":"106ba95c.ff91e7","name":"","active":true,"console":"false","complete":"true","x":730,"y":900,"wires":[]},{"id":"640cd93a.dc8278","type":"switch","z":"106ba95c.ff91e7","name":"Red to Red+Amber","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"Red to Red+Amber","vt":"str"}],"checkall":"true","outputs":1,"x":770,"y":980,"wires":[["c72f3452.ecb788"]]},{"id":"143a5c37.2c2c24","type":"switch","z":"106ba95c.ff91e7","name":"Red+Amber to Green","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"Red+Amber to Green","vt":"str"}],"checkall":"true","outputs":1,"x":780,"y":1020,"wires":[["25b66579.d5d4ba"]]},{"id":"37998186.0166ae","type":"switch","z":"106ba95c.ff91e7","name":"Green to Amber","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"Green to Amber","vt":"str"}],"checkall":"true","outputs":1,"x":760,"y":1060,"wires":[["9165befa.f926a"]]},{"id":"5fb0bfbe.fb63d","type":"switch","z":"106ba95c.ff91e7","name":"Amber to Red","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"Amber to Red","vt":"str"}],"checkall":"true","outputs":1,"x":760,"y":1100,"wires":[["27b18f60.43063"]]},{"id":"27b18f60.43063","type":"delay","z":"106ba95c.ff91e7","name":"Show Red for 20s","pauseType":"delay","timeout":"20","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":990,"y":1100,"wires":[["dbdf3ad8.496cd8"]]},{"id":"9165befa.f926a","type":"delay","z":"106ba95c.ff91e7","name":"Show Amber for 3s","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":990,"y":1060,"wires":[["dbdf3ad8.496cd8"]]},{"id":"c72f3452.ecb788","type":"delay","z":"106ba95c.ff91e7","name":"Show Red+Amber for 3s","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1010,"y":980,"wires":[["dbdf3ad8.496cd8"]]},{"id":"8039d917.97c6a8","type":"comment","z":"106ba95c.ff91e7","name":"UK Traffic Light Simulator","info":"Note that under UK law, the amber light must\nbe showing for 3 seconds.\n\nSequence is:\n\n- RED\n- RED+AMBER\n- GREEN\n- AMBER\n- RED\n\nIn this finite state machine, we only need\none transition, called `CHANGE` since we only\nneed to rotate through each state in turn.\n\nIn this flow example, we use the transition\noutput to control the sequence and take the\nentry output as the actual light(s) showing.","x":190,"y":895,"wires":[]}]


Zenofmud

unread,
May 21, 2017, 7:43:46 AM5/21/17
to node...@googlegroups.com
Hi Julian
Ok, here is my version. If you could use sleep() in the function node it could be just the function node connected back to itself.

 [{"id":"5947d1eb.fd7da8","type":"function","z":"a25e6174.3659a","name":"Process light changes","func":"switch (msg.next) {\n    case \"START\":\n        msg.sleep = 1;\n        msg.topic = 'START';\n        msg.next = \"RED\";\n        break;\n    case \"RED\":\n        msg.sleep = 20;\n        msg.topic = \"RED\";\n        msg.next = \"RED+AMBER\";\n        break;\n    case \"RED+AMBER\":\n        msg.sleep = 3;\n        msg.topic = \"RED+AMBER\";\n        msg.next = \"GREEN\";\n        break;\n    case \"GREEN\":\n        msg.sleep = 20;\n        msg.topic = \"GREEN\";\n        msg.next = \"AMBER\";\n        break;\n    case \"AMBER\":\n        msg.sleep = 3;\n        msg.topic = \"AMBER\";\n        msg.next = \"RED\";\n        break;\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":418,"y":611,"wires":[["154c188d.ac63b7","433eac47.180e1c"]]},{"id":"edbf7dba.4619","type":"inject","z":"a25e6174.3659a","name":"","topic":"START","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"x":161,"y":538,"wires":[["1fc78e78.7558a2"]]},{"id":"154c188d.ac63b7","type":"debug","z":"a25e6174.3659a","name":"","active":true,"console":"false","complete":"true","x":606,"y":642,"wires":[]},{"id":"dd1a56c9.5dcdb","type":"delay","z":"a25e6174.3659a","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":515,"y":527,"wires":[["5947d1eb.fd7da8"]]},{"id":"75fd0503.e7097c","type":"delay","z":"a25e6174.3659a","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":540,"y":781,"wires":[["5947d1eb.fd7da8"]]},{"id":"433eac47.180e1c","type":"switch","z":"a25e6174.3659a","name":"check for sleep length","property":"sleep","propertyType":"msg","rules":[{"t":"eq","v":"20","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"eq","v":"1","vt":"num"}],"checkall":"true","outputs":3,"x":849,"y":614,"wires":[["dd1a56c9.5dcdb"],["75fd0503.e7097c"],["341e8fc8.c816a8"]]},{"id":"341e8fc8.c816a8","type":"delay","z":"a25e6174.3659a","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":521,"y":696,"wires":[["5947d1eb.fd7da8"]]},{"id":"1fc78e78.7558a2","type":"change","z":"a25e6174.3659a","name":"","rules":[{"t":"set","p":"next","pt":"msg","to":"START","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":138,"y":605,"wires":[["5947d1eb.fd7da8"]]}]

Paul

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/d0eb0282-309d-4236-aef7-183d3e78f48b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Julian Knight

unread,
May 21, 2017, 10:40:49 AM5/21/17
to Node-RED
Thanks Paul, nice. I think I would simply use a setTimeout() function if I were to use a function node. :)

I guess the benefit of the FSM node is that there is no coding required.

Interested to get other views.

Dave C-J

unread,
May 21, 2017, 12:28:22 PM5/21/17
to node...@googlegroups.com
Here's my effort.... no function nodes or FSM...

[{"id":"6fcdba8b.903244","type":"inject","z":"65fdffc0.d60e3","name":"","topic":"","payload":"1","payloadType":"none","repeat":"","crontab":"","once":true,"x":110,"y":80,"wires":[["ccc4c1c6.333b4","2999b3f6.d6664c"]]},{"id":"ccc4c1c6.333b4","type":"trigger","z":"65fdffc0.d60e3","op1":"red","op2":"off-r","op1type":"str","op2type":"str","duration":"13","extend":false,"units":"s","reset":"","name":"","x":490,"y":80,"wires":[["5b81a4f4.10639c"]]},{"id":"2999b3f6.d6664c","type":"delay","z":"65fdffc0.d60e3","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":270,"y":140,"wires":[["dce93e7c.2316c","10b47167.ef4b8f"]]},{"id":"933ca73a.6cc358","type":"delay","z":"65fdffc0.d60e3","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":260,"y":320,"wires":[["ccc4c1c6.333b4","2999b3f6.d6664c"]]},{"id":"5b81a4f4.10639c","type":"debug","z":"65fdffc0.d60e3","name":"","active":true,"console":"false","complete":"false","x":710,"y":80,"wires":[]},{"id":"dce93e7c.2316c","type":"trigger","z":"65fdffc0.d60e3","op1":"amber","op2":"off-a","op1type":"str","op2type":"str","duration":"3","extend":false,"units":"s","reset":"","name":"","x":500,"y":140,"wires":[["b0e46c96.4001"]]},{"id":"10b47167.ef4b8f","type":"delay","z":"65fdffc0.d60e3","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":260,"y":200,"wires":[["51fa908e.ae057","6b3f26b.f94c0d8"]]},{"id":"6b3f26b.f94c0d8","type":"delay","z":"65fdffc0.d60e3","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":270,"y":260,"wires":[["933ca73a.6cc358","dce93e7c.2316c"]]},{"id":"b0e46c96.4001","type":"debug","z":"65fdffc0.d60e3","name":"","active":true,"console":"false","complete":"false","x":710,"y":140,"wires":[]},{"id":"51fa908e.ae057","type":"trigger","z":"65fdffc0.d60e3","op1":"green","op2":"off-g","op1type":"str","op2type":"str","duration":"10","extend":false,"units":"s","reset":"","name":"","x":490,"y":200,"wires":[["60139211.4c8e3c"]]},{"id":"60139211.4c8e3c","type":"debug","z":"65fdffc0.d60e3","name":"","active":true,"console":"false","complete":"false","x":710,"y":200,"wires":[]}]
Reply all
Reply to author
Forward
0 new messages