The DELAY node. Not doing what I want

It will be in the undefined state when you restart node red as the node context will be empty at that point. You should always allow for the case where a context variable may not have been set yet.

And that’s why I put the inject node there to inject a “default” time at start up (or after a DEPLOY) just to tidy things up.

Right?

I’m confused.

As I said previously, the inject node is not necessary because in your function contains the the lines

    delay = context.get("delay");
    if (delay === undefined) delay = 1000;

That code gets the value of delay from the node context, then tests the value provided and if it is undefined (which means you have not yet saved it the first time) then set it to 1000 (which is 1 second). You can change that to whatever time you want the default to be. There is no need for the additional node.

1 Like

Thanks.

Honestly though that was above my skill set.

However I shall apply it asap. I have just spent the past couple of … hours ? chasing a typo’ I made when copy/pasting node data from one to the another and messed up on most.

So some worked and most didn’t. But that is now fixed. Phew!

As an alternative you could use a change node (no function node necessary):

[{"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"]]}]
1 Like

As I said, you should take some time out to learn the basics, it will save you time in the long run.

Just discover something that I think deserves to be pointed… once you set the delay with the msg.delay it doesnt matter anymore what time base you set on the delay node, will works always on miliseconds.

Regards

2 Likes

Trying_to_learn,

It might be helpful to spend a little time to figure out how to manipulate the msg object. this is just my opinion. in general it is less complicated to keep all of the data related to a sequence in the message. this will help avoid conflict that can happen when using any of the external contexts.

i don't understand all of the details of your flow so i will give a general outline of an example.

There is some trigger event that is going to execute a sequence that will set a timer along the way. and, the design is to allow the sequence to fetch the delay duration from a slider. pretty typical use case: user turns on the exhaust fan in the kitchen, which triggers a sequence that will turn on the fan, delay from some amount of time, then turn off the exhaust fan. The fan run time is adjustable using a slider.

when the the exhaust fan is turned on, the first thing the sequence wants to do is fetch the duration from the slider and tuck the value away in the msg object for use later. after your flow uses some kind of node to get the duration from the slider, i am guessing that the duration value will be in msg.payload. you can use a change node to set msg.duration to the value in msg.payload. for the duration of the life of the msg, msg.duration will be available. when you get ready to send the msg to the delay node, use another change node to set msg.delay = msg.duration. presto change-o. when the msg arrives to the delay node, it knows how long to delay. if the msg moves on to another node, msg.duration will still be available. if duration is no longer necessary, another change node can be used to delete msg.duartion.

i too am a newb to node-red. something that i have discovered and don't yet fully understand is the way msg.payload is treated. it seems to me that msg.payload (and all child objects) has some type of protection that prevents its manipulation. (i.e. if msg.payload exists, i don't think i can add anything to it.) so, when i have a flow that uses a node that returns data in msg.payload, i have developed the habit of saving any payload data (just like you will have if you put the msg.payload duration from your slider into msg.duration) then i use a change node to delete msg.payload.

i have several sequences that add as many as 6 different elements to msg (i.e. msg.datathinie1, msg.datathingie2, etc) and those data are available to the sequence for the entire life of the msg.

in the example i have used here, it is possible that the user might turn off the exhaust fan switch before the delay has expired. to deal with that, consider capturing the switch to off state change, use a change node to add msg.reset = true (i think. look at the delay node help to verify), then connect that change node to the same delay node that was used when the switch was turned on.

something else I have not yet verified and that I can't find in the delay node help. it appears to me as though a sequence that sends msg.reset to the delay node terminates at the delay node and will not move to any subsequent nodes beyond the delay. but, i am not completely sure of this. makes sense that it works that way. likewise, if a sequence is delayed, and the delay node received a msg.reset, the original, delayed sequence also seems to terminate at the delay, which does not make sense to me.

hope this helps.

Hi "Athome".

Yeah, node-red is fun.

I've been off-line for a while.

I am not qualified enough to comment on the last part you wrote but:
If you have the DELAY node and send it a RESET message, it is to be expected the message would terminate there.

Suggestion:
Post the flow you have to the forum and see if anyone helps.

I'll give it a look-see as well and see if I can help you.

All the best.

Awesome alternative