This is one of my babies.
I've worked on it for a long time and it is getting better - I hope - than it was.
This is a bit more strict in it's inputs, but offers a lot of handy stuff if you are dealing with devices that may or not be available all the time.
It can also be used to control gate
nodes (foreign) but they are handy sometimes, so the output topic
is in the subflow's settings.
NO FOREIGN NODES IN THIS SUBFLOW.
Just to declare that.
Give the docs a once over too.
See if I haven't left anything important out.
(I say that because I just spent a lot of time to put something in I had already done and forgotten I did it.)
Walk through of what it is all about:
You have a standard button
node.
You want to use it to TOGGLE something on/off.
Originally that was a gate
node, but things have evolved to now include more stuff.
Node properties:
start mode
- determines if the output (upon deployment) is OFF or ON
Off text
- is what is shown in/on the button when the OFF mode is active.
OffCLR
- is what colour you want to use in/on the button. Font/background. Your choice.
I would nearly include two colours, but.....
On text
- is what is shown on the button when the ON mode is active.
OnCLR
- as above but for ON condition.
OFF
- the payload sent out when OFF condition active.
ON
- the payload send out when ON condition active.
CTOPIC
- if using the gate
node set the topic
to identify to that node it is a control message.
Yeah, I know you could just stick a change
node.... but as I did use this a LOT of controlling the gate
node, it seemed beneficial to put it in there.
I hope the docs are sufficient to explain the rest of the workings for messages accepted.
And how to configure the button
node to display the right stuff.
There is the option with the msg.enabled
to change between true
and false
.
That is if you want to DISABLE the button for any reason.
If it idisabled
is shown on the button
node.
Work maybe could be done there.
There are also options to RELOAD and RESEND.
RELOAD loads the DEFAULT condition.
RESEND forces the node to output the existing condition - in case you redeployed the dashboard and it's state got wiped.
[{"id":"402169a8.8a791","type":"subflow","name":"B Toggle 2","info":"2024 02 06\n==\nFurther update:\n`msg.enabled = true` and `msg.payload = X` will ENABLE the button node.\n`msg.enabled = false` and `msg.payload = X` will DISABLE the button node.\nbut please noted `msg.payload` has to be `X` also!\n\n2023 12 20\n==\nRe-write code to allow force reloading of desired state.\n\nToggle output at receipt of message.\nConfigurable output and message to send back to button node.\n(2022 12 16)\n\nIf `msg.payload == 0` (number) the output is forced to the OFF condition.\n\nIf `msg.payload == 1` (number) the output is forced to the ON condition.\n\nIf `msg.payload == \"RELOAD\"` (text) the output is set to what you determined in the\n `StartMode` value.\n\nIf `msg.payload == \"RESEND\"` the current condition is resent to the output.\n(Handy if button mode is wiped with deploy)\n\nAny other input toggles the output.\n\n## ENV variables:\n```\nStartMode - set start condition (`0` off `1` on).\nOnCLR - the colour when ON condition active.\nOnTXT - the text when ON condition active.\nOffCLR - the colour when OFF condition active.\nOffTXT - the text when OFF conditin active.\nON - payload when ON condition active.\nOFF - payload when OFF condition active.\nCTOPIC - the topic of the output message.\n```\n\nOutputs:\n - 1 $OFF for OFF and $ON for ON.\n - 2 $ON for OFF and $OFF for ON. (Opposite of 1)\n - 3 to be sent back to button with `msg.colour` to set buttons colour and `msg.txt` for the text to be displayed.\n","category":"","in":[{"x":140,"y":190,"wires":[{"id":"69ae694095adea75"}]}],"out":[{"x":860,"y":180,"wires":[{"id":"5a9848b4303ef8d2","port":0},{"id":"8c41e6c213bcdefe","port":0}]},{"x":860,"y":280,"wires":[{"id":"3a564786d2308bdd","port":0},{"id":"a2ec504194f78107","port":0}]},{"x":860,"y":380,"wires":[{"id":"f14d0daf4ad33691","port":0},{"id":"aff48be4199bcfab","port":0},{"id":"69ae694095adea75","port":1}]}],"env":[{"name":"StartMode","type":"num","value":"","ui":{"label":{"en-US":"Start Mode (0/1) (off/on)"},"type":"input","opts":{"types":["num"]}}},{"name":"OffTXT","type":"str","value":"","ui":{"type":"input","opts":{"types":["str","num"]}}},{"name":"OffCLR","type":"str","value":"","ui":{"type":"input","opts":{"types":["str"]}}},{"name":"OnTXT","type":"str","value":"","ui":{"type":"input","opts":{"types":["str","num"]}}},{"name":"OnCLR","type":"str","value":"","ui":{"type":"input","opts":{"types":["str"]}}},{"name":"OFF","type":"str","value":""},{"name":"ON","type":"str","value":""},{"name":"CTOPIC","type":"str","value":""}],"meta":{"desc":"Button toggle node with feedback to button"},"color":"#D8BFD8","outputLabels":["Normal output","Inverted output","To button"],"icon":"node-red-dashboard/ui_switch.png","status":{"x":860,"y":490,"wires":[{"id":"4cca89516db73bd2","port":0}]}},{"id":"69ae694095adea75","type":"function","z":"402169a8.8a791","name":"toggle","func":"let a = msg.payload;\nlet msg1 = {};\nlet x = context.get(\"counter\") || 0;\n\nif (msg.enabled != undefined)\n{\n // Work to be done here.\n const en = msg.enabled;\n if (en == true)\n {\n // ENABLE\n node.warn(\"Enabled = true\");\n context.set(\"disabled\",0);\n a = context.get(\"counter\") || 0;\n }\n else\n if (en == false)\n {\n // DISABLE\n node.warn(\"Enabled = false\");\n context.set(\"disabled\",1);\n msg1.txt = \"disabled\";\n msg1.colour = env.get(\"OffCLR\");\n node.status({text:\"DISABLED\"});\n return [null,msg1];\n }\n}\n\nif (context.get(\"disabled\") == 1)\n{\n // Can't do anything.\n node.status({text:\"skipped\"});\n return;\n}\n\nif (a == \"RELOAD\")\n{\n a = env.get(\"StartMode\");\n}\n\nif (a == \"RESEND\")\n{\n a = context.get(\"counter\");\n}\n\nif (a == 0)\n{\n context.set(\"counter\",0);\n msg.payload = 0;\n node.status({text:\"Force OFF\"});\n return [msg,null];\n}\nif (a == 1)\n{\n context.set(\"counter\",1);\n msg.payload = 1;\n node.status({ text: \"Force ON\" });\n return [msg,null];\n}\n\nif (x === 0)\n{\n msg.payload = 1;\n node.status({ text: \"ON\" });\n} else\nif (x === 1)\n{\n msg.payload = 0;\n node.status({ text: \"OFF\" });\n}\n\nx = (x + 1) % 2;\n\ncontext.set(\"counter\",x);\n\nreturn [msg,null];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":190,"wires":[["0db7c2da3958ea2c"],[]],"info":"## Outputs `1` or `0` for ON/OFF and `msg.colour` to send to button."},{"id":"f14d0daf4ad33691","type":"change","z":"402169a8.8a791","name":"OFF","rules":[{"t":"set","p":"colour","pt":"msg","to":"OffCLR","tot":"env"},{"t":"set","p":"txt","pt":"msg","to":"OffTXT","tot":"env","dc":true}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":350,"wires":[[]]},{"id":"aff48be4199bcfab","type":"change","z":"402169a8.8a791","name":"ON","rules":[{"t":"set","p":"colour","pt":"msg","to":"OnCLR","tot":"env"},{"t":"set","p":"txt","pt":"msg","to":"OnTXT","tot":"env","dc":true}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":410,"wires":[[]]},{"id":"0db7c2da3958ea2c","type":"switch","z":"402169a8.8a791","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":540,"y":190,"wires":[["5a9848b4303ef8d2","3a564786d2308bdd","f14d0daf4ad33691"],["8c41e6c213bcdefe","a2ec504194f78107","aff48be4199bcfab"]]},{"id":"5a9848b4303ef8d2","type":"change","z":"402169a8.8a791","name":"OFF","rules":[{"t":"set","p":"payload","pt":"msg","to":"OFF","tot":"env"},{"t":"set","p":"topic","pt":"msg","to":"CTOPIC","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":160,"wires":[[]]},{"id":"8c41e6c213bcdefe","type":"change","z":"402169a8.8a791","name":"ON","rules":[{"t":"set","p":"payload","pt":"msg","to":"ON","tot":"env"},{"t":"set","p":"topic","pt":"msg","to":"CTOPIC","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":210,"wires":[[]]},{"id":"a2ec504194f78107","type":"change","z":"402169a8.8a791","name":"OFF","rules":[{"t":"set","p":"payload","pt":"msg","to":"OFF","tot":"env"},{"t":"set","p":"topic","pt":"msg","to":"CTOPIC","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":300,"wires":[[]]},{"id":"3a564786d2308bdd","type":"change","z":"402169a8.8a791","name":"ON","rules":[{"t":"set","p":"payload","pt":"msg","to":"ON","tot":"env"},{"t":"set","p":"topic","pt":"msg","to":"CTOPIC","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":250,"wires":[[]]},{"id":"a035346e85f036ba","type":"inject","z":"402169a8.8a791","name":"Start Mode","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"0.2","topic":"","payload":"StartMode","payloadType":"env","x":190,"y":140,"wires":[["69ae694095adea75"]]},{"id":"4cca89516db73bd2","type":"status","z":"402169a8.8a791","name":"TOGGLE node status monitor","scope":["69ae694095adea75"],"x":600,"y":490,"wires":[[]]},{"id":"e50af91e3f733c64","type":"subflow:402169a8.8a791","z":"0918ee609bf69fc7","name":"","env":[{"name":"StartMode","value":"0","type":"num"},{"name":"OffTXT","value":"OFF","type":"str"},{"name":"OffCLR","value":"teal","type":"str"},{"name":"OnTXT","value":"ON","type":"str"},{"name":"OnCLR","value":"lime","type":"str"},{"name":"OFF","value":"stop","type":"str"},{"name":"ON","value":"go","type":"str"},{"name":"CTOPIC","value":"topic","type":"str"}],"x":2730,"y":3620,"wires":[["4d73a0d654cca663"],[],["85992fde5f7274b1"]]}]