A little bit of a flow that others may like

I have recently been playing with dashboards and while playing with buttons, I needed a “fail safe” to prevent me pressing a button by mistake.

So I put an “Activate” button to allow the other button to be pressed.
I haven’t worked out how to do colours, and other fancy stuff, but at the end of the day it works.

How to use:
The ACTIVATE button enables the RESET ALL button.
That is done by the timeout node which I have set to 2 seconds.
I put a switch in the equation as well to indicate the time allowed.

Then, when you press the RESET ALL button, the message is passed through.

That is taken from the output of the EN node and then processed as you need.

I know it isn’t that great, but someone may find it helpful/handy, and I feel I should give back after all the questions I ask.

Code below:
[{"id":"e300107f.8667e8","type":"ui_button","z":"fb549e2f.4d026","name":"","group":"5a16edf3.798c04","order":3,"width":0,"height":0,"passthru":true,"label":"Reset All!","color":"","bgcolor":"","icon":"","payload":"RESET","payloadType":"str","topic":"","x":680,"y":170,"wires":[["1f5cca83.8f19c5"]]},{"id":"1f5cca83.8f19c5","type":"function","z":"fb549e2f.4d026","name":"EN","func":"if (msg.topic === \"ENABLE\")\n{\n //\n if (msg.payload === 'true')\n {\n node.status({fill:\"yellow\",shape:\"dot\",text:\"ENABLED\"});\n context.set('enable',1);\n }\n //if (msg.payload === 'false')\n else\n {\n context.set('enable',0);\n// context.enable = 0;\n// context.set('enable',enable_topic);\n node.status({fill:\"red\",shape:\"dot\",text:\"DISABLED\"});\n }\n}\nif (msg.topic != \"ENABLE\")\n{\n if (context.get('enable') == 1)\n {\n //\n node.status({fill:\"green\",shape:\"dot\",text:\"On-line\"});\n return msg;\n }\n}\n","outputs":1,"noerr":0,"x":810,"y":170,"wires":[["2205799b.d99d3e","5bb56ab7.6882ac"]]},{"id":"99fc784c.cb71b8","type":"function","z":"fb549e2f.4d026","name":"Set Topic","func":"msg.topic=\"ENABLE\";\nreturn msg;","outputs":1,"noerr":0,"x":820,"y":90,"wires":[["9f1b1a02.1ab5"]]},{"id":"14983a82.e709bd","type":"ui_button","z":"fb549e2f.4d026","name":"","group":"5a16edf3.798c04","order":1,"width":0,"height":0,"passthru":true,"label":"Enable","color":"","bgcolor":"","icon":"","payload":"true","payloadType":"str","topic":"","x":680,"y":90,"wires":[["99fc784c.cb71b8"]]},{"id":"9f1b1a02.1ab5","type":"timeouttrigger","z":"fb549e2f.4d026","ontimeouttype":"bool","ontimeoutval":"false","duration":"2","units":"s","name":"","x":690,"y":130,"wires":[["1f5cca83.8f19c5","f81b8be4.ad3f7"]]},{"id":"f81b8be4.ad3f7","type":"ui_switch","z":"fb549e2f.4d026","name":"","label":"switch","group":"5a16edf3.798c04","order":2,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"str","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":820,"y":130,"wires":[["4d56bc1b.f1220c"]]},{"id":"5a16edf3.798c04","type":"ui_group","z":"","name":"Input","tab":"cababfc5.7b2f6","order":4,"disp":true,"width":"4","collapse":false},{"id":"cababfc5.7b2f6","type":"ui_tab","z":"","name":"Control Display","icon":"dashboard","order":6}]

Also a newbie here. I like to learn new techniques, but when I try to import your flow to learn how it works, I get the all too common error: “Unknown: …”.

What is the “Timeout Trigger” node?

If you try to import a flow containing nodes that you haven’t installed you will get this error.

I know that, but it would be nice if someone posts a flow with uncommon or new nodes to describe them. There is no “Timeout Trigger” node in the pallette manager, so I can’t do much other than reading the function code.

Hopefully the default trigger node could be used instead.

Hi.

I am sorry I didn’t declare the need for the timeout node.

The node is called TIMEOUTTRIGGER.

There are three “timeout” nodes you can get.

I have all three - for reasons still unknown to myself - but I like to try things.

Here is a walk through of what is going on in the flow:

There are two buttons and one switch.
The switch is there as an indicator more than as an input.

The first button is the ENABLE button.
When pressed, it sends a message via a node to set the TOPIC as well.
That way that message is identifiable to the node controlling the data flow.

The output from that node then goes into the TIMEOUT node which is set to 2 seconds.
When it receives input, it passes it to the output and waits a given time before “timing out”.
In this case it is set to 2 seconds.
So: It passes the message received from the ENABLE button on to the next node and after 2 seconds, it sends another message indicating it has “timed out”.

Those two messages are received by the node I wrote.
The first message is received and it sets itself up to pass any OTHER messages it receives to its output.

During this time, you press the RESET ALL button and the message goes on down the flow and is sent out the output of the node called EN. (Short from ENABLE)

If you wait more than 2 seconds, the EN node receives the “timed out” message from the timer node and blocks the message received from the RESET ALL button getting anywhere.

I think that would be handy if you have a “BIG RED BUTTON” that you don’t want to accidentally press.

Does that help?

And again sorry for not declaring the need for the timeout node.

So would it be possible to use the built in trigger node in the same way ? That way everyone has all the nodes by default.

I would be interested how to do what I did in the flow with the built in trigger mode.

Could you maybe show me how that works?

Well hopefully it is obvious enough… set the first field to the thing you want sent when a message arrives… - then the timeout (2 seconds) - then the second output to send after the timeout. There is an option to extend the timeout if any more messages arrive (to make a hold off timer) - or not. That should be just about it.

As @dceejay said - this should do the same as the contrib-timeouttrigger node

Yeah, ok.

I think we are talking about very different things.

How so ? - you say it goes into the timeout node that passes it through (same as trigger node first output) - waits two seconds and times out - and then what does it send ? it can only be either true or false as that is what the switch is set to respond to… so the trigger node sending false as second output should be the same…
(just trying to understand also)

Sorry, I stand corrected.

I got the INJECT mode and TRIGGER nodes mixed up.

Yeah, ok.

I guess I just hadn’t thought of the TRIGGER node and how it can send a “pulse” on its output.

Here is a rewrite of the flow with TRIGGER rather than TIMEOUT.

[{"id":"4531aaa2.b10d4c","type":"ui_button","z":"fb549e2f.4d026","name":"","group":"5a16edf3.798c04","order":3,"width":0,"height":0,"passthru":true,"label":"Reset All!","color":"","bgcolor":"","icon":"","payload":"RESET","payloadType":"str","topic":"","x":530,"y":830,"wires":[["e2198e6d.913dc"]]},{"id":"978b992f.33783","type":"inject","z":"fb549e2f.4d026","name":"Wipe","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":380,"y":830,"wires":[["4531aaa2.b10d4c"]]},{"id":"e2198e6d.913dc","type":"function","z":"fb549e2f.4d026","name":"EN","func":"if (msg.topic === \"ENABLE\")\n{\n //\n if (msg.payload === 'true')\n {\n node.status({fill:\"yellow\",shape:\"dot\",text:\"ENABLED\"});\n context.set('enable',1);\n }\n //if (msg.payload === 'false')\n else\n {\n context.set('enable',0);\n// context.enable = 0;\n// context.set('enable',enable_topic);\n node.status({fill:\"red\",shape:\"dot\",text:\"DISABLED\"});\n }\n}\nif (msg.topic != \"ENABLE\")\n{\n if (context.get('enable') == 1)\n {\n //\n node.status({fill:\"green\",shape:\"dot\",text:\"On-line\"});\n return msg;\n }\n}\n","outputs":1,"noerr":0,"x":680,"y":830,"wires":[["5f215b3c.afdd64"]]},{"id":"f085d58b.b3c7d8","type":"function","z":"fb549e2f.4d026","name":"Set Topic","func":"msg.topic=\"ENABLE\";\nreturn msg;","outputs":1,"noerr":0,"x":380,"y":770,"wires":[["e3ad87f2.b84c6"]]},{"id":"d8d1d9f2.e6dfd8","type":"ui_button","z":"fb549e2f.4d026","name":"","group":"5a16edf3.798c04","order":1,"width":0,"height":0,"passthru":true,"label":"Enable","color":"","bgcolor":"","icon":"","payload":"true","payloadType":"str","topic":"","x":540,"y":710,"wires":[["f085d58b.b3c7d8"]]},{"id":"5d791d2d.f646b4","type":"ui_switch","z":"fb549e2f.4d026","name":"","label":"Enabled","group":"5a16edf3.798c04","order":2,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"str","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":680,"y":770,"wires":[["12f65d14.e6cb13"]]},{"id":"12f65d14.e6cb13","type":"debug","z":"fb549e2f.4d026","name":"Junk","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":810,"y":770,"wires":[]},{"id":"c01d77d.5b9ee88","type":"inject","z":"fb549e2f.4d026","name":"Enable","topic":"","payload":"true","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":380,"y":710,"wires":[["d8d1d9f2.e6dfd8"]]},{"id":"5f215b3c.afdd64","type":"debug","z":"fb549e2f.4d026","name":"Wipe message","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":840,"y":830,"wires":[]},{"id":"e3ad87f2.b84c6","type":"trigger","z":"fb549e2f.4d026","op1":"true","op2":"false","op1type":"str","op2type":"bool","duration":"5","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":530,"y":770,"wires":[["e2198e6d.913dc","5d791d2d.f646b4"]]},{"id":"5a16edf3.798c04","type":"ui_group","z":"","name":"Input","tab":"cababfc5.7b2f6","order":4,"disp":true,"width":"4","collapse":false},{"id":"cababfc5.7b2f6","type":"ui_tab","z":"","name":"Control Display","icon":"dashboard","order":6}]

1 Like

Top tip - is you put ``` in front and after the code it will turn it into a code block - much easier for others to cut/paste. (I edited your post above to do this)

Thanks.

Appreciated.

I am still getting to terms with the new layout.

I know. Excuse.

I’m trying - to learn and get better.

no probs - we are all learning all the time - here’s a useful link.
http://commonmark.org/help/

Hi

Here's a little example how to get more fanciness out of your buttons

[{"id":"b072ed3c.e56b4","type":"ui_button","z":"dcdf0ef7.c1e56","name":"on/off","group":"e905c597.18d9c8","order":0,"width":"0","height":"0","passthru":false,"label":"{{msg.topic}}","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"","payloadType":"date","topic":"","x":910,"y":380,"wires":[["84f03fb5.3cfe3"]]},{"id":"84f03fb5.3cfe3","type":"function","z":"dcdf0ef7.c1e56","name":"buttonHandler","func":"var state = global.get(\"devicestate\");\nvar label;\nvar color;\n\nif(state.active === true){\n state.active = false;\n label = \"OFF\";\n color = \"red\";\n}\nelse{\n state.active = true;\n label = \"ON\";\n color = \"green\";\n}\nglobal.set(\"devicestate\", state);\n\n\nvar buttonstate = {enabled:false, background:color, topic:label};\n\nmsg.payload = \"whatever data needs to be sent to proccessing\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":1070,"y":380,"wires":[["b072ed3c.e56b4"],["fded91c9.8089c"]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"fded91c9.8089c","type":"delay","z":"dcdf0ef7.c1e56","name":"waste time to fake proccesing","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":880,"y":600,"wires":[["689aec32.79fff4"]]},{"id":"180bb725.c111d9","type":"function","z":"dcdf0ef7.c1e56","name":"Init","func":"var devicestate = {active:true};\nglobal.set(\"devicestate\",devicestate);\nreturn msg;","outputs":1,"noerr":0,"x":530,"y":360,"wires":[["689aec32.79fff4"]]},{"id":"53516ef3.dd82","type":"inject","z":"dcdf0ef7.c1e56","name":"Once","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":390,"y":360,"wires":[["180bb725.c111d9"]]},{"id":"689aec32.79fff4","type":"function","z":"dcdf0ef7.c1e56","name":"determineButtonState","func":"var state = global.get(\"devicestate\");\nvar label;\nvar color;\n\nif(state.active === true){\n label = \"ON\";\n color = \"green\";\n}\nelse{\n label = \"OFF\";\n color = \"red\";\n}\nmsg = {enabled:true, topic:label, background:color};\nreturn msg;","outputs":1,"noerr":0,"x":730,"y":420,"wires":[["b072ed3c.e56b4"]]},{"id":"e905c597.18d9c8","type":"ui_group","z":"","name":"BUTTON","tab":"209ff019.06775","order":2,"disp":true,"width":"6","collapse":false},{"id":"209ff019.06775","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]

Thanks very much.

Looking at it now and it looks good.

(Second try)

Thanks.

But what is the “waste time” part for? Is the return needed to have it all work?

I’ll mess around with it but I want to ask you because I may see something and THINK something that could (and usually is) wrong.

:wink: