"wait until" node changed behavior after recent update

Hello everyone!

I have been using Node-RED to configure home automations during these past two years.
One of the first and most complex automations is related to different sets of window blinds (or "covers") in my house. I have 6 covers, 3 in each room, and I wanted them to open or close in sequence. So I created a flow that receives a list of devices and activates the first one. After the current device reports its status change (i.e. cover1 closed), the next one is activated and so on.

To do this, I use a "wait until" node that waits until the cover in msg.device updates its data.event.new_state.last_updated property. This has been working fine for two years.

Since the last update in Node-RED (I am in v4.0.2, and previously I was on v3.1.9) the "wait until" node is getting stuck after the first cover. It receives the device name in msg.device and acts when the first cover finishes moving, and then when it has to do this with the next cover, it gets stuck and only sends the message after the timeout.

I had to create a workaround to match this incorrect behavior, but I want this automation to be scalable (the covers that are supposed to be activated come in a msg.devices string, and then there's a function node that sends each one in order in msg.device).

I already checked that the devices are reporting the data.event.new_state.last_updated properly, I tried extending the timeout to check if it wasn't a delay issue, and I tried sending a msg.reset=true to the node before each blind, but it doesn't seem to change anything.

I would like to get any recommendations on how to solve this and go back to the "one wait until node" solution that worked previously. And please help me understand if there are any errors on my side or if this is a bug that should be reported and fixed.

[{"id":"b684b87c36e2067d","type":"ha-wait-until","z":"b84e61f8ff473dab","name":"","server":"8a86b0cc.b2bac","version":3,"outputs":2,"entities":{"entity":["{{device}}"],"substring":[],"regex":[]},"property":"data.event.new_state.last_updated","comparator":"is_not","value":"0","valueType":"str","timeout":"23","timeoutType":"num","timeoutUnits":"seconds","checkCurrentState":false,"blockInputOverrides":false,"outputProperties":[],"entityLocation":"data","entityLocationType":"none","x":480,"y":1400,"wires":[["1af19f883221ba84"],["79808095d9f78bed"]]},{"id":"969f931f45f11f87","type":"inject","z":"b84e61f8ff473dab","name":"","props":[{"p":"payload"},{"p":"device","v":"cover.ns1","vt":"str"},{"p":"devices","v":"cover.ns2,cover.ns3,end","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":300,"y":1380,"wires":[["b684b87c36e2067d"]]},{"id":"1af19f883221ba84","type":"debug","z":"b84e61f8ff473dab","name":"continue_with_next_cover","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":730,"y":1380,"wires":[]},{"id":"79808095d9f78bed","type":"debug","z":"b84e61f8ff473dab","name":"cover_timeout_error","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":720,"y":1440,"wires":[]},{"id":"a73079c1926af00a","type":"inject","z":"b84e61f8ff473dab","name":"","props":[{"p":"payload"},{"p":"device","v":"cover.ns3","vt":"str"},{"p":"devices","v":"cover.ns2,cover.ns1,end","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":300,"y":1440,"wires":[["b684b87c36e2067d"]]},{"id":"90ba6791db56944d","type":"ha-wait-until","z":"b84e61f8ff473dab","name":"cover1","server":"8a86b0cc.b2bac","version":3,"outputs":2,"entities":{"entity":["cover.ns1"],"substring":[],"regex":[]},"property":"data.event.new_state.last_updated","comparator":"is_not","value":"0","valueType":"str","timeout":"23","timeoutType":"num","timeoutUnits":"seconds","checkCurrentState":false,"blockInputOverrides":true,"outputProperties":[],"entityLocation":"data","entityLocationType":"none","x":470,"y":1540,"wires":[["4bb37e549cce9a70"],["e8ada4ecc423e379"]]},{"id":"2749ebfaf117ec0a","type":"switch","z":"b84e61f8ff473dab","name":"","property":"device","propertyType":"msg","rules":[{"t":"eq","v":"cover.ns1_living","vt":"str"},{"t":"eq","v":"cover.ns2_bathroom","vt":"str"},{"t":"eq","v":"cover.ns3_bedroom","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":290,"y":1580,"wires":[["90ba6791db56944d"],["27484dd9e94786e5"],["692ad3e8e5e3bdd7"]]},{"id":"27484dd9e94786e5","type":"ha-wait-until","z":"b84e61f8ff473dab","name":"cover2","server":"8a86b0cc.b2bac","version":3,"outputs":2,"entities":{"entity":["cover.ns2"],"substring":[],"regex":[]},"property":"data.event.new_state.last_updated","comparator":"is_not","value":"0","valueType":"str","timeout":"23","timeoutType":"num","timeoutUnits":"seconds","checkCurrentState":false,"blockInputOverrides":true,"outputProperties":[],"entityLocation":"data","entityLocationType":"none","x":470,"y":1580,"wires":[["4bb37e549cce9a70"],["e8ada4ecc423e379"]]},{"id":"692ad3e8e5e3bdd7","type":"ha-wait-until","z":"b84e61f8ff473dab","name":"cover3","server":"8a86b0cc.b2bac","version":3,"outputs":2,"entities":{"entity":["cover.ns3"],"substring":[],"regex":[]},"property":"data.event.new_state.last_updated","comparator":"is_not","value":"0","valueType":"str","timeout":"23","timeoutType":"num","timeoutUnits":"seconds","checkCurrentState":false,"blockInputOverrides":true,"outputProperties":[],"entityLocation":"data","entityLocationType":"none","x":470,"y":1620,"wires":[["4bb37e549cce9a70"],["e8ada4ecc423e379"]]},{"id":"4bb37e549cce9a70","type":"debug","z":"b84e61f8ff473dab","name":"continue_with_next_cover","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":750,"y":1560,"wires":[]},{"id":"e8ada4ecc423e379","type":"debug","z":"b84e61f8ff473dab","name":"cover_timeout_error","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":740,"y":1620,"wires":[]},{"id":"3d9c20ba546e81dc","type":"comment","z":"b84e61f8ff473dab","name":"Before update this worked","info":"","x":170,"y":1340,"wires":[]},{"id":"08d787c15d87e3d5","type":"comment","z":"b84e61f8ff473dab","name":"After the update I had to do this, which I don't find acceptable.","info":"","x":280,"y":1500,"wires":[]},{"id":"c0b82d09a88b7a22","type":"inject","z":"b84e61f8ff473dab","name":"","props":[{"p":"payload"},{"p":"device","v":"cover.ns1","vt":"str"},{"p":"devices","v":"cover.ns2,cover.ns3,end","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1540,"wires":[["2749ebfaf117ec0a"]]},{"id":"9ea2b5decc7186d4","type":"inject","z":"b84e61f8ff473dab","name":"","props":[{"p":"payload"},{"p":"device","v":"cover.ns3","vt":"str"},{"p":"devices","v":"cover.ns2,cover.ns1,end","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1600,"wires":[["2749ebfaf117ec0a"]]},{"id":"8a86b0cc.b2bac","type":"server","name":"Home Assistant R","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

Thanks!
Rodrigo

The wait until node appears to be a Home Assistant node. Few here use HA so you may have to ask about it on the HA forum.

However, this simple node-red flow will perform multiple actions sequentially, waiting for one to finish before starting the next one. Open the Comment node to see more detail on how to use it.

[{"id":"b6630ded2db7d680","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":480,"wires":[["ed63ee4225312b40"]]},{"id":"ed63ee4225312b40","type":"delay","z":"bdd7be38.d3b55","name":"Queue","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":310,"y":480,"wires":[["d4d479e614e82a49","7eb760e019b512dc"]]},{"id":"a82c03c3d34f683c","type":"delay","z":"bdd7be38.d3b55","name":"Some more stuff to do","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":800,"y":480,"wires":[["7c6253e5d34769ac","b23cea1074943d4d"]]},{"id":"2128a855234c1016","type":"link in","z":"bdd7be38.d3b55","name":"link in 1","links":["7c6253e5d34769ac"],"x":95,"y":560,"wires":[["3a9faf0a95b4a9bb"]]},{"id":"7c6253e5d34769ac","type":"link out","z":"bdd7be38.d3b55","name":"link out 1","mode":"link","links":["2128a855234c1016"],"x":665,"y":560,"wires":[]},{"id":"b23cea1074943d4d","type":"debug","z":"bdd7be38.d3b55","name":"OUT","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":420,"wires":[]},{"id":"d4d479e614e82a49","type":"debug","z":"bdd7be38.d3b55","name":"IN","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":450,"y":420,"wires":[]},{"id":"3a9faf0a95b4a9bb","type":"function","z":"bdd7be38.d3b55","name":"Flush","func":"return {flush: 1}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":190,"y":560,"wires":[["ed63ee4225312b40"]]},{"id":"7eb760e019b512dc","type":"function","z":"bdd7be38.d3b55","name":"Some functions to be performed","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":480,"wires":[["a82c03c3d34f683c"]]},{"id":"e35f37deeae94860","type":"comment","z":"bdd7be38.d3b55","name":"Set the queue timeout to larger than you ever expect the process to take","info":"This is a simple flow which allows a sequence of nodes to be \nprotected so that only one message is allowed in at a time. \nIt uses a Delay node in Rate Limit mode to queue them, but \nreleases them, using the Flush mechanism, as soon as the \nprevious one is complete. Set the timeout in the delay node to \na value greater than the maximum time you expect it ever to take. \nIf for some reason the flow locks up (a message fails to indicate \ncompletion) then the next message will be released after that time.\n\nMake sure that you trap any errors and feed back to the Flush \nnode when you have handled the error. Also make sure only one \nmessage is fed back for each one in, even in the case of errors.","x":270,"y":360,"wires":[]}]
2 Likes

Thanks @Colin for your reply. Indeed, I need to report this in the Home Assistant forum, I thought this was Node-RED related but I need the "wait until" node to check specifically on a Home Assistant device.

R.

Hello, any luck? seems i'm going the same path. wait until seems totally unstable at the moment
simple flow find closed covers, open one and next

[{"id":"a8cbc5efbc7785a8","type":"ha-get-entities","z":"a6872dce.94f5c","name":"Find closed covers","server":"82ddb5fe.332648","version":1,"rules":[{"condition":"state_object","property":"entity_id","logic":"in_group","value":"cover.rolety_pietro","valueType":"str"},{"condition":"state_object","property":"state","logic":"is","value":"closed","valueType":"str"}],"outputType":"random","outputEmptyResults":false,"outputLocationType":"msg","outputLocation":"payload","outputResultsCount":1,"x":390,"y":2740,"wires":[["14ee1fd7786be595"]]},{"id":"550c37680e580030","type":"ha-wait-until","z":"a6872dce.94f5c","name":"wait until state open","server":"82ddb5fe.332648","version":3,"outputs":2,"entities":{"entity":["{{ payload.entity_id }}"],"substring":[],"regex":[]},"property":"state","comparator":"is","value":"open","valueType":"str","timeout":"90","timeoutType":"num","timeoutUnits":"seconds","checkCurrentState":true,"blockInputOverrides":true,"outputProperties":[{"property":"roleta","propertyType":"msg","value":"","valueType":"entity"}],"x":980,"y":2740,"wires":[["a8cbc5efbc7785a8"],[]]},{"id":"14ee1fd7786be595","type":"api-call-service","z":"a6872dce.94f5c","name":"open cover","server":"82ddb5fe.332648","version":7,"debugenabled":true,"action":"cover.open_cover","floorId":[],"areaId":[],"deviceId":[],"entityId":["{{ payload.entity_id }}"],"labelId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":true,"domain":"cover","service":"open_cover","x":650,"y":2740,"wires":[["550c37680e580030"]]},{"id":"82ddb5fe.332648","type":"server","name":"Home Assistant","version":5,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":true,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

Found something - disable - block input overrides

1 Like

You mean that disabling "block input overrides" do the trick? I'm on the same boat...

ok seems it is working unstable, sometimes it working as expected, sometimes is passing all covers at once

Yes is really unstable right now. I can't find any report for this on HA forum.
I opened a thread on the forum Wait until node in nodered doesn't work anymore as expected - Third party integrations / Node-RED - Home Assistant Community (home-assistant.io), please join.

1 Like

In the example provided in the first post, you are sending the entities as a string. They need to be in an array in the entities key.

{
  "entities": ["light.living_room", "light.bedroom"]
}

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/wait-until.html#full-payload

Edit: I see you are sending a single entity, it still needs the entities key.

{
  "entities": "light.living_room"
}
[{"id":"393cf2754fd83302","type":"ha-wait-until","z":"0a325c35fc29f44e","name":"","server":"","version":3,"outputs":2,"entities":{"entity":["{{payload}}"],"substring":[],"regex":[]},"property":"state","comparator":"is","value":"on","valueType":"str","timeout":"1","timeoutType":"num","timeoutUnits":"minutes","checkCurrentState":true,"blockInputOverrides":false,"outputProperties":[],"x":520,"y":4320,"wires":[["4acd45b38442a0a3"],[]]},{"id":"c72a95eb9ea49951","type":"inject","z":"0a325c35fc29f44e","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{   \"entities\": \"light.dj\" }","payloadType":"jsonata","x":290,"y":4320,"wires":[["393cf2754fd83302"]]},{"id":"4acd45b38442a0a3","type":"debug","z":"0a325c35fc29f44e","name":"debug 208","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":770,"y":4320,"wires":[]}]

Hi @mikefila, thanks for your reply.
The "wait until" node reacts to the "entity" message which contains the current entity that has been triggered (this node waits until this current entity reports that it stopped). The "entities" message is passed on as a string, it contains the next entity that is going to be triggered by other nodes that are not in this example.

R.

I tried fiddling with these settings and didn't find a solution there. It seems that after the node works, it takes maybe a minute for it to work again. It only works with the first command and then the rest fail. I tried sending a msg.reset before sending the next entity and it didn't help.

Thanks,
R.

Edit:I see that is your flow in the first post, it sends just the value without the proper key.

If you want to send the entity dynamically, you need to send the entity in the format.

{
  "entities": "light.living_room"
}

If you are not sending the variable correctly formatted it's hard to say that the node isn't functioning correctly.

Solution here:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.