(No offence @dynamicdave but seeing his flow, I thought I would submit mine.)
As in his post/thread I have a few RPIs running and need to be able to remote control them.
And by that I mean:
Shut them down,
Reboot them,
Back up the node-red settings,
Test them for error detection (two ways)
and update/upgrade them. This part is work-in-progress.
This is the basic flow layout:
The structure is pretty much as the flow posted by @dynamicdave but also slightly different.
Starting top left:
MQTT node receives the command. It is then converted from JSON
format and the switch
node filters out other commands for other machines.
It is then sent to logging with a time stamp. I'll get back to that soon.
Then the command is delayed
1 second and sent to another switch
node.
This one routes the command depending on what it is: Shutdown, reboot, etc.
There are a couple more delay
nodes which allow replies to be sent before the actual command happens. Useful for acknowledgement.
Next you see the group of exec
nodes which do their commands.
Another delay
node and all these messages are sent along to a function
node and then sent out of an MQTT
node, acknowledging the command's receipt.
I did have an option where it echoed the command back, but that was a bit problematic so I stopped doing that. Though the node is still there to allow that.
You will also see there are two command received
nodes. That is because the flow acknowledges the receipt of the command and if it is a shutdown or reboot command, it sends back a message to the sender so things can be done there. (That's me being me about messages and sequences.)
I have debug
nodes along the way - which shouldn't see much use - but are handy all the same.
The test1
and test2
parts are where a local script/command is run and one works and the other generates an error. This checks that the machine is sending back correct status messages when commands are done. (Not really useful but there for central monitoring of all machines and all states so if a machine has an error, it is correctly reported back.)
I have skipped one node. A link
node above the two delay
nodes.
That sends a signal to other parts of the flow stopping them as the machine is about to be shut down or rebooted.
Now the logging part:
This is way overkill for most people but again: I like to log things.
There are a few buttons to allow logging and displaying of the data.
You can edit the respective function
nodes (setup) to set the default state of the button.
Then you see a list of command received - with date - and a log file is also created.
I included an extra queue only to save me having to read the log files. Mostly during design/set up of the flow. That is in the bottom right of the flow.
extra nodes needed:
node-red-contrib-ui-led
node-red-contrib-simple-gate
node-red-contrib-simple-message-queue
Message/command format:
{"DEVICE":"<device name>", "COMMAND":"<command>","state":1}
device_name: Text determining the computer's name. Used in the first switch
node.
command: Text either: Shutdown
Reboot
Backup
Test1
Test2
Update
or Upgrade
state, used to check sequence of messages. Probably not needed for most people.
Now the flow:
[{"id":"52bb799a.59cbb","type":"mqtt in","z":"bf66eea1.cd99d","name":"COMMAND","topic":"DO_THIS/#","qos":"2","datatype":"auto","broker":"2d7fe08c.3d8c6","x":90,"y":270,"wires":[["6acc5b2b.3ab6c4"]]},{"id":"6acc5b2b.3ab6c4","type":"json","z":"bf66eea1.cd99d","name":"","property":"payload","action":"","pretty":false,"x":230,"y":270,"wires":[["e820bc50.e988b"]]},{"id":"e820bc50.e988b","type":"switch","z":"bf66eea1.cd99d","name":"","property":"payload.DEVICE","propertyType":"msg","rules":[{"t":"eq","v":"MUSICPI","vt":"str"},{"t":"eq","v":"BEDPI","vt":"str"},{"t":"eq","v":"PIFACE","vt":"str"},{"t":"eq","v":"CAMERAPI","vt":"str"},{"t":"eq","v":"PORTAPI","vt":"str"},{"t":"eq","v":"TelePi","vt":"str"},{"t":"eq","v":"BEEFPI","vt":"str"}],"checkall":"true","repair":false,"outputs":7,"x":350,"y":270,"wires":[[],[],[],[],[],["e3145860.227448","358d5b09.719924","5017c95a.e350c"],[]]},{"id":"15eb299c.11bdc6","type":"debug","z":"bf66eea1.cd99d","name":"Final command","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":485,"y":210,"wires":[]},{"id":"60147ec.1e3d7","type":"switch","z":"bf66eea1.cd99d","name":"","property":"payload.COMMAND","propertyType":"msg","rules":[{"t":"eq","v":"Shutdown","vt":"str"},{"t":"eq","v":"Reboot","vt":"str"},{"t":"eq","v":"Backup","vt":"str"},{"t":"eq","v":"Update","vt":"str"},{"t":"eq","v":"Upgrade","vt":"str"},{"t":"eq","v":"Test1","vt":"str"},{"t":"eq","v":"Test2","vt":"str"}],"checkall":"true","repair":false,"outputs":7,"x":630,"y":260,"wires":[["c661b884.39269","65ee48e3.88f68","94cd03b0.b0e15"],["f17604f2.dc80f","65ee48e3.88f68","94cd03b0.b0e15"],["dd1ee7ca.460238"],["862b9d38.55fb08"],["b29a395e.305608"],["9ad3b375.e16318"],["6b5bfc46.abc8ac"]]},{"id":"2c83c765.67e608","type":"comment","z":"bf66eea1.cd99d","name":"Allow remote shutdown","info":"","x":280,"y":180,"wires":[]},{"id":"dd1ee7ca.460238","type":"exec","z":"bf66eea1.cd99d","command":"bash /home/pi/Mine/NR_Backup.sh","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Backup","x":940,"y":320,"wires":[[],[],["e5c6398a.c09c8"]]},{"id":"436ab820.4a052","type":"comment","z":"bf66eea1.cd99d","name":"Command response reply","info":"","x":155,"y":380,"wires":[]},{"id":"ee286.1a157d7b","type":"debug","z":"bf66eea1.cd99d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":345,"y":540,"wires":[]},{"id":"b01bc6d1.08ba88","type":"function","z":"bf66eea1.cd99d","name":"","func":"var prefix = 'COMMAND_REPLY/';\nmsg.topic = global.get('myDeviceName');\nmsg.topic = prefix + msg.topic;\nreturn msg;","outputs":1,"noerr":0,"x":175,"y":440,"wires":[["9430eebb.e5fbf","ee286.1a157d7b","ee242c91.d29e"]]},{"id":"ee242c91.d29e","type":"debug","z":"bf66eea1.cd99d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"topic","x":335,"y":500,"wires":[]},{"id":"9430eebb.e5fbf","type":"mqtt out","z":"bf66eea1.cd99d","name":"Results from commands issued.","topic":"","qos":"2","retain":"","broker":"2d7fe08c.3d8c6","x":405,"y":440,"wires":[]},{"id":"ef02182c.8dfaa8","type":"exec","z":"bf66eea1.cd99d","command":"sudo shutdown -h now","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Shut down","x":950,"y":220,"wires":[[],[],["e5c6398a.c09c8"]]},{"id":"fc6a851a.ba85b","type":"exec","z":"bf66eea1.cd99d","command":"sudo reboot","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Reboot","x":940,"y":270,"wires":[[],[],["e5c6398a.c09c8"]]},{"id":"e5c6398a.c09c8","type":"delay","z":"bf66eea1.cd99d","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1160,"y":340,"wires":[["b01bc6d1.08ba88"]]},{"id":"65ee48e3.88f68","type":"function","z":"bf66eea1.cd99d","name":"CMD received","func":"if (msg.payload.length !== 0 ) \n{\n msg = {payload: \"Shutdown/Restart Command received\"};\n}\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":170,"wires":[["b01bc6d1.08ba88"]]},{"id":"c661b884.39269","type":"delay","z":"bf66eea1.cd99d","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":760,"y":230,"wires":[["ef02182c.8dfaa8"]]},{"id":"f17604f2.dc80f","type":"delay","z":"bf66eea1.cd99d","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":760,"y":260,"wires":[["fc6a851a.ba85b"]]},{"id":"6b5bfc46.abc8ac","type":"exec","z":"bf66eea1.cd99d","command":"dirfdgdfg","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Test2","x":930,"y":517,"wires":[[],[],["e5c6398a.c09c8"]]},{"id":"e3145860.227448","type":"function","z":"bf66eea1.cd99d","name":"Time Stamp","func":"var a = msg.payload;\nvar b = new Date().toString();\nmsg = {payload: b + \" >> \" + a + \" << \"};\nreturn msg;\n","outputs":1,"noerr":0,"x":530,"y":500,"wires":[["af8cf4da.b922"]]},{"id":"9ad3b375.e16318","type":"exec","z":"bf66eea1.cd99d","command":"dir","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Test1","x":930,"y":467,"wires":[[],[],["e5c6398a.c09c8"]]},{"id":"862b9d38.55fb08","type":"exec","z":"bf66eea1.cd99d","command":"sudo apt update","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Update","x":940,"y":370,"wires":[[],[],["e5c6398a.c09c8"]]},{"id":"21ce64a9.ab1394","type":"function","z":"bf66eea1.cd99d","name":"Echo command","func":"var c = msg.payload.COMMAND;\nif (msg.payload.length !== 0 ) \n{\n msg = {payload: c};\n}\nreturn msg;","outputs":1,"noerr":0,"x":661,"y":359,"wires":[["b01bc6d1.08ba88"]]},{"id":"358d5b09.719924","type":"delay","z":"bf66eea1.cd99d","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":485,"y":260,"wires":[["15eb299c.11bdc6","60147ec.1e3d7"]]},{"id":"5017c95a.e350c","type":"function","z":"bf66eea1.cd99d","name":"CMD received","func":"var c = msg.payload;\nif (msg.payload.length !== 0 ) \n{\n msg = {payload: \"Command received\"};\n}\nreturn msg;","outputs":1,"noerr":0,"x":661,"y":329,"wires":[["b01bc6d1.08ba88"]]},{"id":"94cd03b0.b0e15","type":"link out","z":"bf66eea1.cd99d","name":"STOP","links":["79b7a172.22a23"],"x":715,"y":200,"wires":[]},{"id":"b29a395e.305608","type":"exec","z":"bf66eea1.cd99d","command":"sudo apt update","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Upgrade","x":940,"y":419,"wires":[[],[],["e5c6398a.c09c8"]]},{"id":"a6b22c78.fbf3b8","type":"link in","z":"bf66eea1.cd99d","name":"Received commands log","links":["af8cf4da.b922"],"x":170,"y":970,"wires":[["eb7b85c3.166df8","10d4b561.200853"]],"l":true},{"id":"eb7b85c3.166df8","type":"gate","z":"bf66eea1.cd99d","name":"","controlTopic":"control","defaultState":"open","openCmd":"GO","closeCmd":"STOP","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":460,"y":970,"wires":[["66379bb.ffaa264"]]},{"id":"10d4b561.200853","type":"gate","z":"bf66eea1.cd99d","name":"","controlTopic":"control","defaultState":"open","openCmd":"GO","closeCmd":"STOP","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":460,"y":1140,"wires":[["eada4d73.4b00c"]]},{"id":"66379bb.ffaa264","type":"function","z":"bf66eea1.cd99d","name":"name","func":"var path = global.get(\"event_paths\");\nmsg.filename = path + \"commands_received.txt\";\n\nvar time = new Date().toLocaleString();\nmsg.date = time;\nmsg.payload = time + \" \" + msg.payload;\nreturn msg;\n","outputs":1,"noerr":0,"x":650,"y":970,"wires":[["a3327beb.30191","fbc14ad5.b6458"]]},{"id":"443c9c7d.fdcbc4","type":"fan","z":"bf66eea1.cd99d","x":1210,"y":920,"wires":[["eb7b85c3.166df8"]]},{"id":"ec3563eb.269a08","type":"fan","z":"bf66eea1.cd99d","x":650,"y":920,"wires":[["7fbe1dff.688fa4","eb7b85c3.166df8"]]},{"id":"62991004.a73a38","type":"link in","z":"bf66eea1.cd99d","name":"Mark log","links":["7183b790.8f0af8"],"x":265,"y":920,"wires":[["eb7b85c3.166df8"]]},{"id":"4b85f3f9.c1142c","type":"fan","z":"bf66eea1.cd99d","x":760,"y":1100,"wires":[["10d4b561.200853","97ae3de8.dc9b78"]]},{"id":"eada4d73.4b00c","type":"ring-buffer","z":"bf66eea1.cd99d","name":"CMDs","capacity":16,"order":"new-to-old","sendOnlyIfFull":false,"pushAfterClear":false,"extra":false,"perTopic":false,"x":610,"y":1140,"wires":[["4128f2ad.f02f6c"]]},{"id":"a3327beb.30191","type":"file","z":"bf66eea1.cd99d","name":"Commands received","filename":"","appendNewline":true,"createDir":true,"overwriteFile":"false","x":890,"y":970,"wires":[[]]},{"id":"fbc14ad5.b6458","type":"function","z":"bf66eea1.cd99d","name":"Time stamp","func":"msg.time = new Date().toLocaleString();\nreturn msg;","outputs":1,"noerr":0,"x":1285,"y":1020,"wires":[["20247c00.c0e05c"]]},{"id":"522c1d42.8cd2ec","type":"inject","z":"bf66eea1.cd99d","name":"STOP","topic":"CONTROL","payload":"STOP","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":460,"y":880,"wires":[["ec3563eb.269a08"]],"icon":"node-red/alert.png"},{"id":"135ee29c.488bad","type":"inject","z":"bf66eea1.cd99d","name":"GO","topic":"CONTROL","payload":"GO","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"2","x":460,"y":920,"wires":[["ec3563eb.269a08"]]},{"id":"1eace28d.94aa4d","type":"switch","z":"bf66eea1.cd99d","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"CONTROL","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":650,"y":880,"wires":[["271dbaca.9c6566","ec3563eb.269a08"]]},{"id":"7fbe1dff.688fa4","type":"ui_led","z":"bf66eea1.cd99d","group":"43459bd7.7150a4","order":4,"width":"1","height":"1","label":"","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"red","value":"STOP","valueType":"str"},{"color":"green","value":"GO","valueType":"str"}],"name":"Commands Logging LED","x":900,"y":920,"wires":[]},{"id":"1c3a939a.2d7064","type":"switch","z":"bf66eea1.cd99d","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"CONTROL","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":760,"y":1060,"wires":[["5a138d7c.e9c7f4","4b85f3f9.c1142c"]]},{"id":"97ae3de8.dc9b78","type":"ui_led","z":"bf66eea1.cd99d","group":"43459bd7.7150a4","order":2,"width":"1","height":"1","label":"","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"red","value":"STOP","valueType":"str"},{"color":"green","value":"GO","valueType":"str"}],"name":"Commands List LED","x":950,"y":1100,"wires":[]},{"id":"ce53ed99.6a5028","type":"inject","z":"bf66eea1.cd99d","name":"GO","topic":"CONTROL","payload":"GO","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"5","x":620,"y":1100,"wires":[["4b85f3f9.c1142c"]]},{"id":"4128f2ad.f02f6c","type":"ui_template","z":"bf66eea1.cd99d","group":"43459bd7.7150a4","name":"Commands RX log","order":5,"width":"6","height":"6","format":"<table id=\"table\" border=\"1\">\n <tr>\n <th>Commands RX log</th> \n </tr>\n <tbody>\n <tr ng-repeat=\"row in msg.payload track by $index\">\n <td class=\"text\" >{{row}}</td>\n </tr>\n </tbody>\n</table>\n","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":800,"y":1140,"wires":[[]]},{"id":"20247c00.c0e05c","type":"simple-queue","z":"bf66eea1.cd99d","name":"queue1","firstMessageBypass":false,"bypassInterval":"0","x":1480,"y":1021,"wires":[["bca0c12.5c4b1c"]]},{"id":"4761869b.81dbd8","type":"function","z":"bf66eea1.cd99d","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\nvar enabled = context.get(\"ENABLED\")||0;\n\n// Look for a message with topic set to SETUP to set values.\nif (msg.topic == \"SETUP\") //Do this if the message is NOT \"X\"\n{\n //\n // Background colours first.\n //\n context.set(\"ABGC\", msg.colourA);\n context.set(\"BBGC\", msg.colourB);\n //\n // Disabled button background colour.\n //\n context.set(\"DISABLEDCLR\",msg.disabledColour);\n //\n // Now do text.\n //\n context.set(\"Atxt\", msg.txtA);\n context.set(\"Btxt\", msg.txtB);\n //\n // Font colours.\n //\n context.set(\"AFC\",msg.txtclrA);\n context.set(\"BFC\",msg.txtclrB);\n //\n // Payloads.\n //\n context.set(\"PayloadA\", msg.payloadA);\n context.set(\"PayloadB\", msg.payloadB);\n //\n // Topic.\n //\n if (msg.topicSET !== null)\n {\n context.set(\"Topic\",msg.topicSET);\n } else\n {\n context.set(\"Topic\",\"~\");\n }\n msg.txt = msg.txtA;\n msg.colour = msg.disabledColour;\n msg.fontclr = msg.txtclrA;\n return msg;\n}\n\n// Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n //node.warn(\"X detected\");\n // Insert here code to enable other stuff.\n// if (context.get(\"ENABLED\") === 0)\n if (enabled === 0)\n {\n //\n // Old code.\n //\n //node.warn(\"Setting enable\");\n// context.set(\"ENABLED\",1);\n// msg.txt = context.get(\"Atxt\");\n// msg.colour = context.get(\"ABGC\");\n// msg.fontclr = context.get(\"AFC\");\n\n // New code.\n \n //node.warn(\"State = \" + state);\n\n if (state === 0)\n {\n //\n // Set things for state 0\n //\n //node.warn(\"State 0 detected\");\n msg.payload = context.get(\"PayloadA\");\n msg.colour = context.get(\"ABGC\");\n msg.txt = context.get(\"Atxt\");\n msg.fontclr = context.get(\"AFC\");\n }\n else if (state === 1)\n {\n //\n // Set things for state 1\n //\n //node.warn(\"State 1 detected\");\n msg.payload = context.get(\"PayloadB\");\n msg.colour = context.get(\"BBGC\");\n msg.txt = context.get(\"Btxt\");\n msg.fontclr = context.get(\"BFC\");\n }\n context.set(\"ENABLED\",1);\n return msg;\n }\n\n// if (context.get(\"ENABLED\") === 1)\n state = (state + 1)% 2;\n //node.warn(state);\n context.set(\"STATE\",state);\n if (enabled === 1)\n {\n if (state === 0)\n {\n // Condition A\n msg.payload = context.get(\"PayloadA\");\n msg.colour = context.get(\"ABGC\");\n msg.txt = context.get(\"Atxt\");\n msg.fontclr = context.get(\"AFC\");\n } else\n if (state === 1)\n {\n // Condition B\n msg.payload = context.get(\"PayloadB\");\n msg.colour = context.get(\"BBGC\");\n msg.txt = context.get(\"Btxt\");\n msg.fontclr = context.get(\"BFC\");\n }\n }\n \n if (context.get(\"Topic\") == \"~\")\n {\n msg.topic = \"\";\n } else\n {\n msg.topic = context.get(\"Topic\");\n }\n return msg;\n}\nif (msg.payload == \"Z\")\n{\n //\n ////node.warn(\"Timed out\");\n //\n context.set(\"ENABLED\",0);\n if (state === 0)\n {\n //\n // Set things for state 1\n //\n msg.payload = context.get(\"PayloadA\");\n msg.colour = context.get(\"DISABLEDCLR\");\n msg.txt = context.get(\"Atxt\");\n msg.fontclr = context.get(\"AFC\");\n }\n else if (state === 1)\n {\n //\n // Set things for state 2\n //\n msg.payload = context.get(\"PayloadB\");\n msg.colour = context.get(\"DISABLEDCLR\");\n msg.txt = context.get(\"Btxt\");\n msg.fontclr = context.get(\"BFC\");\n }\n return msg;\n}\n","outputs":1,"noerr":0,"x":480,"y":800,"wires":[["b941b592.355d7","1eace28d.94aa4d"]]},{"id":"271dbaca.9c6566","type":"debug","z":"bf66eea1.cd99d","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":650,"y":840,"wires":[]},{"id":"ab7514b9.7b3438","type":"function","z":"bf66eea1.cd99d","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\nvar enabled = context.get(\"ENABLED\")||0;\n\n// Look for a message with topic set to SETUP to set values.\nif (msg.topic == \"SETUP\") //Do this if the message is NOT \"X\"\n{\n //\n // Background colours first.\n //\n context.set(\"ABGC\", msg.colourA);\n context.set(\"BBGC\", msg.colourB);\n //\n // Disabled button background colour.\n //\n context.set(\"DISABLEDCLR\",msg.disabledColour);\n //\n // Now do text.\n //\n context.set(\"Atxt\", msg.txtA);\n context.set(\"Btxt\", msg.txtB);\n //\n // Font colours.\n //\n context.set(\"AFC\",msg.txtclrA);\n context.set(\"BFC\",msg.txtclrB);\n //\n // Payloads.\n //\n context.set(\"PayloadA\", msg.payloadA);\n context.set(\"PayloadB\", msg.payloadB);\n //\n // Topic.\n //\n if (msg.topicSET !== null)\n {\n context.set(\"Topic\",msg.topicSET);\n } else\n {\n context.set(\"Topic\",\"~\");\n }\n msg.txt = msg.txtA;\n msg.colour = msg.disabledColour;\n msg.fontclr = msg.txtclrA;\n return msg;\n}\n\n// Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n //node.warn(\"X detected\");\n // Insert here code to enable other stuff.\n// if (context.get(\"ENABLED\") === 0)\n if (enabled === 0)\n {\n //\n // Old code.\n //\n //node.warn(\"Setting enable\");\n// context.set(\"ENABLED\",1);\n// msg.txt = context.get(\"Atxt\");\n// msg.colour = context.get(\"ABGC\");\n// msg.fontclr = context.get(\"AFC\");\n\n // New code.\n \n //node.warn(\"State = \" + state);\n\n if (state === 0)\n {\n //\n // Set things for state 0\n //\n //node.warn(\"State 0 detected\");\n msg.payload = context.get(\"PayloadA\");\n msg.colour = context.get(\"ABGC\");\n msg.txt = context.get(\"Atxt\");\n msg.fontclr = context.get(\"AFC\");\n }\n else if (state === 1)\n {\n //\n // Set things for state 1\n //\n //node.warn(\"State 1 detected\");\n msg.payload = context.get(\"PayloadB\");\n msg.colour = context.get(\"BBGC\");\n msg.txt = context.get(\"Btxt\");\n msg.fontclr = context.get(\"BFC\");\n }\n context.set(\"ENABLED\",1);\n return msg;\n }\n\n// if (context.get(\"ENABLED\") === 1)\n state = (state + 1)% 2;\n //node.warn(state);\n context.set(\"STATE\",state);\n if (enabled === 1)\n {\n if (state === 0)\n {\n // Condition A\n msg.payload = context.get(\"PayloadA\");\n msg.colour = context.get(\"ABGC\");\n msg.txt = context.get(\"Atxt\");\n msg.fontclr = context.get(\"AFC\");\n } else\n if (state === 1)\n {\n // Condition B\n msg.payload = context.get(\"PayloadB\");\n msg.colour = context.get(\"BBGC\");\n msg.txt = context.get(\"Btxt\");\n msg.fontclr = context.get(\"BFC\");\n }\n }\n \n if (context.get(\"Topic\") == \"~\")\n {\n msg.topic = \"\";\n } else\n {\n msg.topic = context.get(\"Topic\");\n }\n return msg;\n}\nif (msg.payload == \"Z\")\n{\n //\n ////node.warn(\"Timed out\");\n //\n context.set(\"ENABLED\",0);\n if (state === 0)\n {\n //\n // Set things for state 1\n //\n msg.payload = context.get(\"PayloadA\");\n msg.colour = context.get(\"DISABLEDCLR\");\n msg.txt = context.get(\"Atxt\");\n msg.fontclr = context.get(\"AFC\");\n }\n else if (state === 1)\n {\n //\n // Set things for state 2\n //\n msg.payload = context.get(\"PayloadB\");\n msg.colour = context.get(\"DISABLEDCLR\");\n msg.txt = context.get(\"Btxt\");\n msg.fontclr = context.get(\"BFC\");\n }\n return msg;\n}\n","outputs":1,"noerr":0,"x":480,"y":1060,"wires":[["c02127a5.268b7","1c3a939a.2d7064"]]},{"id":"5a138d7c.e9c7f4","type":"debug","z":"bf66eea1.cd99d","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":760,"y":1020,"wires":[]},{"id":"bca0c12.5c4b1c","type":"debug","z":"bf66eea1.cd99d","name":"Commands received","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1510,"y":1061,"wires":[]},{"id":"eb98df69.e6039","type":"change","z":"bf66eea1.cd99d","name":"Read","rules":[{"t":"set","p":"trigger","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1270,"y":1060,"wires":[["20247c00.c0e05c"]]},{"id":"d92379cc.41683","type":"change","z":"bf66eea1.cd99d","name":"Wipe","rules":[{"t":"set","p":"reset","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1270,"y":1100,"wires":[["20247c00.c0e05c"]]},{"id":"780313ac.31733c","type":"function","z":"bf66eea1.cd99d","name":"Setup","func":"msg = {\n \"topic\":\"SETUP\",\n \"disabledColour\":\"brown\",\n \"colourA\": \"lime\",\n \"colourB\": \"green\",\n \"txtA\": \"Log\",\n \"txtB\": \"Log Stop\",\n \"txtclrA\": \"black\",\n \"txtclrB\": \"black\",\n \"payloadA\": \"GO\",\n \"payloadB\": \"STOP\",\n \"topicSET\": \"CONTROL\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":800,"wires":[["4761869b.81dbd8"]]},{"id":"b941b592.355d7","type":"ui_button","z":"bf66eea1.cd99d","name":"Commands RX Logging","group":"43459bd7.7150a4","order":3,"width":"2","height":"1","passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":520,"y":760,"wires":[["4761869b.81dbd8","f67a9584.cefc28"]]},{"id":"f67a9584.cefc28","type":"trigger","z":"bf66eea1.cd99d","op1":"","op2":"Z","op1type":"nul","op2type":"str","duration":"3","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":470,"y":840,"wires":[["4761869b.81dbd8"]]},{"id":"824bbb91.23f2d","type":"function","z":"bf66eea1.cd99d","name":"Setup","func":"msg = {\n \"topic\":\"SETUP\",\n \"disabledColour\":\"brown\",\n \"colourA\": \"lime\",\n \"colourB\": \"green\",\n \"txtA\": \"Display\",\n \"txtB\": \"Display Stop\",\n \"txtclrA\": \"black\",\n \"txtclrB\": \"black\",\n \"payloadA\": \"GO\",\n \"payloadB\": \"STOP\",\n \"topicSET\": \"CONTROL\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":1060,"wires":[["ab7514b9.7b3438"]]},{"id":"c02127a5.268b7","type":"ui_button","z":"bf66eea1.cd99d","name":"Commands RX List","group":"43459bd7.7150a4","order":1,"width":"2","height":"1","passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":500,"y":1020,"wires":[["ab7514b9.7b3438","f6c03f7f.70e3f"]]},{"id":"f6c03f7f.70e3f","type":"trigger","z":"bf66eea1.cd99d","op1":"","op2":"Z","op1type":"nul","op2type":"str","duration":"3","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":470,"y":1100,"wires":[["ab7514b9.7b3438"]]},{"id":"843b64d0.d43238","type":"inject","z":"bf66eea1.cd99d","name":"Read","topic":"","payload":" ","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":1140,"y":1060,"wires":[["eb98df69.e6039"]]},{"id":"cd99ac04.6034e","type":"inject","z":"bf66eea1.cd99d","name":"Wipe","topic":"","payload":" ","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":1140,"y":1100,"wires":[["d92379cc.41683"]]},{"id":"c0c3b487.3cd558","type":"inject","z":"bf66eea1.cd99d","name":"Inject","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"3","x":280,"y":760,"wires":[["780313ac.31733c"]]},{"id":"f08a2462.1698b","type":"inject","z":"bf66eea1.cd99d","name":"Inject","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"3","x":280,"y":1020,"wires":[["824bbb91.23f2d"]]},{"id":"af8cf4da.b922","type":"link out","z":"bf66eea1.cd99d","name":"LOGGING","links":["a6b22c78.fbf3b8"],"x":690,"y":500,"wires":[],"l":true},{"id":"887fda2c.675b38","type":"comment","z":"bf66eea1.cd99d","name":"Logging","info":"","x":520,"y":710,"wires":[]},{"id":"2d7fe08c.3d8c6","type":"mqtt-broker","z":"","name":"MQTT host","broker":"192.168.0.99","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"SOM","birthQos":"0","birthPayload":"TelePi comms up","closeTopic":"EOM","closePayload":"TelePi shutting down","willTopic":"EOM","willQos":"0","willPayload":"TelePi Comms Failure"},{"id":"43459bd7.7150a4","type":"ui_group","z":"","name":"Cmds Received","tab":"fb960b7a.961008","order":3,"disp":true,"width":"6","collapse":false},{"id":"fb960b7a.961008","type":"ui_tab","z":"","name":"Logging","icon":"list","order":3,"disabled":false,"hidden":false}]