Using dashboard to to set delay time

Hi I have recently started using node red and I’ve got stuck.! I would like to use a drop down box to select a delay time on delay node. Is this possible? Can someone help? Thanks

Which bit don’t you know how to do? The dropdown select box or setting the delay time?
Note that there has been a lengthy thread within the last few days about setting a variable delay time.

As summary of that thread which was very interesting to me too you have:


[{"id":"e3e57dbf.e1ccb","type":"change","z":"cf6706ec.415a58","name":"","rules":[{"t":"set","p":"delay","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":600,"wires":[[]]},{"id":"8d1875eb.631a38","type":"inject","z":"cf6706ec.415a58","name":"","topic":"","payload":"3000","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":600,"wires":[["e3e57dbf.e1ccb"]]},{"id":"4ae0b364.e31a8c","type":"debug","z":"cf6706ec.415a58","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":630,"y":680,"wires":[]},{"id":"233b0af9.423696","type":"delay","z":"cf6706ec.415a58","name":"","pauseType":"delayv","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":480,"y":680,"wires":[["4ae0b364.e31a8c"]]},{"id":"d1edf7f8.1d2398","type":"change","z":"cf6706ec.415a58","name":"","rules":[{"t":"set","p":"delay","pt":"msg","to":"delay","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":680,"wires":[["233b0af9.423696"]]},{"id":"4fa77bc6.9e1f64","type":"inject","z":"cf6706ec.415a58","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":680,"wires":[["d1edf7f8.1d2398"]]},{"id":"fb10915a.47745","type":"inject","z":"cf6706ec.415a58","name":"","topic":"","payload":"4000","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":640,"wires":[["e3e57dbf.e1ccb"]]}]

Hi Colin the drop down box is fine I am stuck on how to use the selection of the drop down box to set the delay time.

I prefer this solution to that from @davidcgu. I don’t like global variables. Apart from that David’s is fine though.

[{"id":"3edc9f5b.5cfea","type":"inject","z":"6dc690a3.1abc88","name":"","topic":"delay","payload":"2000","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":99,"y":687,"wires":[["33116ffe.769ba8"]]},{"id":"a87e4f8f.a642d8","type":"inject","z":"6dc690a3.1abc88","name":"","topic":"","payload":"Message to be delayed","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":800,"wires":[["33116ffe.769ba8"]]},{"id":"88eab954.f85478","type":"inject","z":"6dc690a3.1abc88","name":"","topic":"delay","payload":"3000","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":725,"wires":[["33116ffe.769ba8"]]},{"id":"eefd1ddd.b713b","type":"debug","z":"6dc690a3.1abc88","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":583,"y":653,"wires":[]},{"id":"33116ffe.769ba8","type":"function","z":"6dc690a3.1abc88","name":"Set delay","func":"if (msg.topic === \"delay\") {\n    context.set(\"delay\", msg.payload);\n    msg = null;\n} else {\n    delay = context.get(\"delay\");\n    if (delay === undefined) delay = 1000;  // default delay ms\n    msg.delay = delay;\n}\nreturn msg;","outputs":1,"noerr":0,"x":302,"y":748,"wires":[["78252539.d7ae4c"]]},{"id":"78252539.d7ae4c","type":"delay","z":"6dc690a3.1abc88","name":"","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":485,"y":750,"wires":[["81ccddb.13174a"]]},{"id":"81ccddb.13174a","type":"debug","z":"6dc690a3.1abc88","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":646,"y":750,"wires":[]}]

Hey Colin,

I know if you tell this must be some good reason… so for me to understand, what is the problem with global variables?

For me are very useful as you can access it anywhere so you can split things and have a better order on your editor however maybe this is causing some lag or something on processing that I don’t know.

Can you please explain?

Thanks in advance

One issue with global variables is handling what to do if the code using it is run before the variable is setup. In this particular case this is not an issue as the result of assigning the undefined global variable to msg.delay actually does nothing, so msg.delay is not set and the delay node defaults to the configured value.

Another issue is the very fact that global variables are global. Suppose you have the flow you supplied in your system and the system becomes (or already is) complex and consists of many tabs. Imagine now a year goes by and you wish to add another similar flow but have forgotten that you are already using the global variable named delay. You might easily use the same named variable again and you have a very subtle bugs caused by the fact that you were setting the variable to different values in two places. It can be very difficult to find such bugs. The situation can be even worse if someone else takes over your code and did not even realised that a global variable of that name was in use.

A third issue, which is not a problem for your flow, is if a global is set in one bit of the flow and used somewhere else entirely, or even worse in mutliple places. Then when something is not working right it can be very difficult to find all the places it is set and used in order to try and work out what is going wrong.

By using message passing rather than globals the code can become a little more complex, but it is always clear where data is coming from and where it is used.

Thanks for the explanation Colin,

What I do to avoid this regarding the timers configured on my system there are all together on a specific tab on the configuration and also on the dashboard and define all timers consistently as delay1,delay2 …

From other side all those variables are saved on a file and restored on case of restart.

I think all this makes safe and easier to track the use of global variables.

With this I make the delays be configurable on the system on a specific tab dedicated to system configurations.

Regards

Certainly with care the potential problems of globals can be avoided. There is always the temptation, though, to use them more and more as often at first glance it looks like the easiest solution to a problem.

Hi Colin,
I agree! in every programming language we should avoid the use of global variables.

Unfortunately the built in nodes only allow to get/set global or flow variables, set/get local (context) variables (e.g. using the change node) would be useful.

That’s what messages are for - passing data to nodes. You don’t need to be able to set another nodes context, just send it a message.

But you have to get that data from somewhere - it doesn't just appear.

There are plenty of scenarios where you need to store some sort of state between two messages arriving at a node. If you don't want to use context then you need to build into your flows the necessary nodes to get/set those state values from somewhere. You also still have to deal with the case where the state value has not been initialised.

I agree that using global context can lead to issues when you want to copy things around. In most cases flow context gives you a much more appropriate scope.

I agree that littering your flow with context variables without comments or sensible naming schemes is a problem; that's true in any programming environment.

But I don't agree that means they should be avoided and considered bad practise.

1 Like

I agree that local context is valuable within the change node – and although I submitted a PR for this last year, it was decided to not introduce the feature until some other features were put in place (can’t remember which, maybe persistence?).

I didn't go that far, I said I prefer not to do it that way and then explained why. It is a matter of personal opinion. I have never used flow or global context but that is because I have wasted so much time over my career tracking down the problems that global variables have caused in code that I and others have written that now I am strongly in favour of avoiding them whenever practical.

Do you mean the ability in a Change node to change the node context of another node?

Actually I've built a contrib-node (not published) to store (set/get) local variables.
But honestly I also use flow and global variables if necessary.

No, what I mean is to store data in local variables, similar to your function above.
The only way at the moment is to use a function node (or a contrib-node). But I generally try to avoid function nodes for simple stuff and prefer to use e.g. the change node.

Nick, why not have an area in the editor that displays all global variables?

Have a look here:

1 Like

Yes node-red-contrib-contextbrowser exists - one of those nodes we’d have preferred to have been preceded with some discussion as it would have been a useful contribution to the core.

Once we’ve got the current work on Persistable Context complete, then it’ll be worth revisiting. As ever, if anyone wanted to help, that would certainly make things happen a bit quicker.