I hope this isn't seen as trying to prove anything to anyone.
I shall upload it soon to the library, but I would like to be sure of this after a few other recent uploads.
This flow (which would be super great if I could make a sub-flow) is for buttons on dashboards.
But I think there is a problem setting the time in the trigger
node.
I am going through re-designing and writing a lot of my stuff as I have got better.
But a lot of my dashboards were just "over run" with buttons, and it was getting worse.
One flaw I have is "protecting" buttons from accidental pressing. I therefore have an ENABLE
button which allows the buttons to then be pressed.
But even that was taking up way too much real estate. So, I got adventurous with the button
node and have written a few different things with buttons.
I have also made a press button
flow so when the button is pressed, it indicates the press by changing colour, text and/or image.
Anyway, that lead to this: The integration of those two functions and a bit more.
Rather than having 3 buttons: "enable" "option 1" and "option 2", you have one!
At "rest" but button shows what is selected/active.
Pressing it once, it becomes active.
Pressing it again - within a time limit - it toggles to the second value.
Then, after the time, it becomes inactive.
I am sure there may be other ways of doing this, but I have put a lot of hours into it and shot myself in the foot so many times, I am luck to have any toes left.
It has a READ ME node in it.
[{"id":"ed9234b8.2f122","type":"function","z":"df652827.d02c3","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\nvar enabled = context.get(\"ENABLED\")||0;\n\n// Look for a !X message to get 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.colour = msg.colourA;\n msg.fontclr = msg.txtclrA;\n return msg;\n}\n\n// Now on to the real stuff.\n//if (msg.payload === true)\nif (msg.payload == \"X\")\n{\n //node.waran(\"X detected\");\n // Insert here code to enable other stuff.\n// if (context.get(\"ENABLED\") === 0)\n if (enabled === 0)\n {\n //node.waran(\"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 return msg;\n }\n\n state = (state + 1)% 2;\n //node.waran(state);\n context.set(\"STATE\",state);\n// close loop\n\n if (context.get(\"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.waran(\"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":3120,"y":280,"wires":[["e01f15d7.afae28","e380fd5d.7618b8"]]},{"id":"e01f15d7.afae28","type":"ui_button","z":"df652827.d02c3","name":"28 June","group":"373c4fb2.a22078","order":5,"width":"3","height":"1","passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":3110,"y":230,"wires":[["ed9234b8.2f122","356bd2e0.9a44fe"]]},{"id":"584e530b.bfda9c","type":"inject","z":"df652827.d02c3","name":"Inject","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"3","x":3100,"y":140,"wires":[["5bc8465e.969d08"]]},{"id":"5bc8465e.969d08","type":"function","z":"df652827.d02c3","name":"Setup","func":"msg = {\n \"topic\":\"SETUP\",\n \"disabledColour\":\"brown\",\n \"colourA\": \"yellow\",\n \"colourB\": \"green\",\n \"txtA\": \"Option 1\",\n \"txtB\": \"Option 2\",\n \"txtclrA\": \"black\",\n \"txtclrB\": \"black\",\n \"payloadA\": 0,\n \"payloadB\": 1,\n \"topicSET\": \"CONTROL\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":3100,"y":190,"wires":[["ed9234b8.2f122"]]},{"id":"7adca369.70a604","type":"comment","z":"df652827.d02c3","name":"Read me","info":"Variables needing to be set in the **setup** node:\n\"disabledColour\":\"brown\",\n\"colourA\": \"yellow\",\n\"colourB\": \"green\",\n\"txtA\": \"Option 1\",\n\"txtB\": \"Option 2\",\n\"txtclrA\": \"black\",\n\"txtclrB\": \"black\",\n\"payloadA\": 0,\n\"payloadB\": 1,\n\"topicSET\": \"CONTROL\"\n\nDisabledColour - this is the colour shown if the\nbutton is inactive.\ncolourA - this is the colour of the button when\noption A is selected.\ncolourB - (as above but for option B)\ntxtA - this is the text shown when option A\nis selected.\ntxtB - (as above but for option B)\ntxtclrA - the font colour for option A\ntxtclrB - the font colour for option B\npayloadA - what is sent out when option A is\nselected.\npayloadB - (as above but for option B)\ntopicSET - the topic of the payload sent\n\nAdjust the time the button accepts input by\nediting the `trigger` node.\n\nThe output is AFTER the `switch` node.\nThis will need to be edited if the `topic` is \nnot \"CONTROL\".\nThis could be worked around with flow.context\nvariables, but I don't want to make too many\nchanges to people's flows. But by all means,\nchange if it suits you.\n\n","x":3100,"y":100,"wires":[]},{"id":"356bd2e0.9a44fe","type":"trigger","z":"df652827.d02c3","op1":"","op2":"Z","op1type":"nul","op2type":"str","duration":"3","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":3110,"y":320,"wires":[["ed9234b8.2f122"]]},{"id":"e2b7cb62.3cec68","type":"debug","z":"df652827.d02c3","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":3320,"y":360,"wires":[]},{"id":"e380fd5d.7618b8","type":"switch","z":"df652827.d02c3","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"CONTROL","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":3270,"y":280,"wires":[["e2b7cb62.3cec68"]]},{"id":"373c4fb2.a22078","type":"ui_group","name":"Group 1","tab":"bca4b6a6.5ee09","order":1,"disp":true,"width":6},{"id":"bca4b6a6.5ee09","type":"ui_tab","z":"","name":"Pushbutton","icon":"dashboard","order":44,"disabled":false,"hidden":false}]