Trigger node: configurable delay time

In my project, the Trigger node is used as a watchdog.
The delay time depends on a user configuration.
So the delay of the Trigger node must be changed sometimes.
Currently, the delay time can only be hardcoded.
So the request is: can the delay be made configurable (e.g. similar as in Delay node or by listening to a flow and global variable)?

1 Like

It would be a good feature and should be simple to implement.

If the @knolleary / @dceejay approve the request, I don't mind giving a PR a go :slight_smile:


You can use a delay to achieve the same effect eg

[{"id":"e7fa8d8a.806a2","type":"inject","z":"dfa1c83b.a5fa68","name":"","topic":"","payload":"10","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":40,"wires":[["7762da53.9e78e4"]]},{"id":"7762da53.9e78e4","type":"function","z":"dfa1c83b.a5fa68","name":"PH Control - dosing amount","func":"//variables de cantidad\n\nvar x = msg.payload;\nvar acid = 0.24;\nvar PH_modify = 0.3;\nvar msg1 = {};\nmsg1.payload = 0;\n\nvar time = 0.2; \nmsg1.payload = (acid * (x + 0.3))/ PH_modify * 1000; \n\nreturn [msg, msg1];\n\n","outputs":2,"noerr":0,"x":260,"y":100,"wires":[[],["57853e7.a0cc6c","42f63877.7b8c08","638d62c7.34805c"]]},{"id":"57853e7.a0cc6c","type":"debug","z":"dfa1c83b.a5fa68","name":"PH OUT4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":500,"y":40,"wires":[]},{"id":"42f63877.7b8c08","type":"change","z":"dfa1c83b.a5fa68","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":100,"wires":[["50348305.1e408c"]]},{"id":"638d62c7.34805c","type":"change","z":"dfa1c83b.a5fa68","name":"","rules":[{"t":"set","p":"delay","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":160,"wires":[["b8951281.9b068"]]},{"id":"50348305.1e408c","type":"rpi-gpio out","z":"dfa1c83b.a5fa68","name":"Fan","pin":"11","set":true,"level":"0","freq":"","out":"out","x":890,"y":120,"wires":[]},{"id":"b8951281.9b068","type":"delay","z":"dfa1c83b.a5fa68","name":"","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":480,"y":220,"wires":[["704021b7.1914a"]]},{"id":"704021b7.1914a","type":"change","z":"dfa1c83b.a5fa68","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":220,"wires":[["50348305.1e408c"]]}]

Thanks for thinking along.

The watchdog behavior my Trigger node needs is different:

  • Send nothing
  • wait for x configurable seconds
  • extend delay if new messsage arrives
  • send true

So, no output as long there is an input within x seconds.

That sounds like a simple function node with a setTimeout... and a bit of context... :slight_smile:

[{"id":"dc9b1aab.519b98","type":"inject","z":"5c11352a.fe0b7c","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":360,"wires":[["fc67f358.0a408"]]},{"id":"bbbc1621.851d98","type":"debug","z":"5c11352a.fe0b7c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":650,"y":360,"wires":[]},{"id":"ea08f04c.7d624","type":"function","z":"5c11352a.fe0b7c","name":"","func":"var timer = context.timer || null;\n\n// If existig timer then clear out old timeout\nif (timer !== null) {\n    clearTimeout(timer);\n}\n\n// set up new timeout using msg.timeout (S) as the time\nif (msg.timeout) {   // but only if msg.timeout exists\n    timer = setTimeout(function() {\n        node.send({payload:true});\n    }, msg.timeout * 1000);\n}\n// save the new timeout and return nothiing.\ncontext.timer = timer;\nreturn null;","outputs":1,"noerr":0,"x":490,"y":360,"wires":[["bbbc1621.851d98"]]},{"id":"fc67f358.0a408","type":"change","z":"5c11352a.fe0b7c","name":"","rules":[{"t":"set","p":"timeout","pt":"msg","to":"2","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":360,"wires":[["ea08f04c.7d624"]]}]
1 Like

Thank you. That works indeed.
But for me this is not a simple function (need knowledge of context.timer, etc.)!
I can understand the code. But I still see this as a workaround.
The existing Trigger node is versitile and so much better readable. It just did the job.
Is it not important that code reads like a novel?
Node-RED is attractive due to these simple to use core nodes and user contributed nodes!
So please don't reject this feature request!

1 Like

I can't immediately see why we couldn't do this - would need to make sure there aren't any subtle behaviours under the covers that make it more complicated.

For example, if 'extend delay' option is enabled, then presumably it would extend it by the value of msg.delay that was received?

We'd also need to figure out what to do if a message doesn't have msg.delay set - I can't remember off the top of my head what the Delay node does in that case.

The trickier part is likely to be getting the UI right. The delay node has an explicit option for setting the delay by msg.delay. The trigger node would need a similar option. Its UI currently has this:

(and "wait for" can also be "resend it every" ... and if we let you set one of those by a msg property, then it'd be short-sighted not to consider the other)

One option would be to add a select box at the start of the line with options for "fixed interval" and "interval set by msg.delay" - with the time interval only shown for the former option.

So it is doable. Just need to make sure there aren't any hidden issues.

I think to be consistent with the delay node then the time interval would still need to be shown, as that would be the "default" in case the msg.delay was not set on every msg.

Any pull request should target the dev branch as there are already some upcoming changes in there.
(and there should be some tests of course)

I just re-noticed this thread and realised I'd volunteered to do the work on it - I'll try and crack on :slight_smile: