简体   繁体   中英

State Machine in Node-Red, how to?

Has anyone come across an elegant solution for this?

User has a BLE Puck.js Button that sends MQTT messages into Node-Red when the button is pressed.

The Node-Red scenario will receive the button-press event from the puck and will start a 30 second timer. [First Pass Works] After the timer expires and SMS message is sent out to specified users.

This works fine with the standard trigger. On press message receipt I start an LED flashing and wait 30 secs then send stop the flashing LED and send the SMS.

BUT... The whole idea of the 30 sec delay is that we give the user a chance to cancel their request by pressing again while the delay is active. In this case we need to turn off the flashing LED and just go back to waiting.

It is this part I am having some trouble with. It is basically a state machine where the action performed when a message is received is dependent on the current state of the machine.

I'm trying to gin this up with context variables but it isn't coming out clean.

I already have it working with the state machine coded into the Puck.js button but I am trying an alternative design with it coded into the Node-Red flow instead.

Any ideas? Thanks

The simplest way is to use a couple of change nodes to flip the state in the context variable and a switch node to act on it. I've used a inject node in place of a MQTT in node just to make the example self contained.

在此处输入图像描述

[{"id":"71ea94637b60dd2c","type":"inject","z":"e8d5f4c1515e1039","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":180,"wires":[["bdf84eb23b897f7d"]]},{"id":"f2b5bc7d60926ed7","type":"trigger","z":"e8d5f4c1515e1039","name":"","op1":"","op2":"send sms","op1type":"nul","op2type":"str","duration":"30","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":670,"y":120,"wires":[["cf353e3bf59d6027"]]},{"id":"bdf84eb23b897f7d","type":"switch","z":"e8d5f4c1515e1039","name":"","property":"running","propertyType":"global","rules":[{"t":"false"},{"t":"true"}],"checkall":"true","repair":false,"outputs":2,"x":250,"y":140,"wires":[["f4a049fdc943889e","2d7e39b07c89783c"],["f4923cda32b3ea13","ce7e2c9cb4923215"]]},{"id":"f4a049fdc943889e","type":"change","z":"e8d5f4c1515e1039","name":"","rules":[{"t":"set","p":"running","pt":"global","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":120,"wires":[["f2b5bc7d60926ed7","3a7b67d8c03d6483"]]},{"id":"f4923cda32b3ea13","type":"change","z":"e8d5f4c1515e1039","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":160,"wires":[["f2b5bc7d60926ed7"]]},{"id":"cf353e3bf59d6027","type":"change","z":"e8d5f4c1515e1039","name":"","rules":[{"t":"set","p":"running","pt":"global","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":870,"y":120,"wires":[["871ed613768c8cba"]]},{"id":"871ed613768c8cba","type":"debug","z":"e8d5f4c1515e1039","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":990,"y":200,"wires":[]},{"id":"3a7b67d8c03d6483","type":"debug","z":"e8d5f4c1515e1039","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":670,"y":80,"wires":[]},{"id":"2d7e39b07c89783c","type":"debug","z":"e8d5f4c1515e1039","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":430,"y":80,"wires":[]},{"id":"ce7e2c9cb4923215","type":"debug","z":"e8d5f4c1515e1039","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":430,"y":200,"wires":[]},{"id":"5ba1151ce4153c8d","type":"inject","z":"e8d5f4c1515e1039","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":300,"wires":[["8fa0194926bdeaec"]]},{"id":"8fa0194926bdeaec","type":"change","z":"e8d5f4c1515e1039","name":"","rules":[{"t":"set","p":"running","pt":"global","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":210,"y":360,"wires":[[]]},{"id":"ae00864cf5a5a222","type":"comment","z":"e8d5f4c1515e1039","name":"","info":"Set up global.running context var","x":260,"y":300,"wires":[]}]

A simple join (manual) requiring 2 messages, with 30 sec timeout.

Then check if the payload array contains 1 value (timeout) or 2 (second press):

here's an image - not allowed to embed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM