Node-RED, particularly when trying to work with the Home Assistant WebSocket nodes, is confusing when you first start, and so much has to be setup correctly it can sometimes be a real minefield to get anywhere.
The challenge here is as much to do with trying to unpick your flow, which for me I’m afraid does not make a lot of sense. In the spirit of trying to help (and also to perhaps leave a few posts that just may help others later on) here are my thoughts.
Scenes:
These are an HA thing, and can be setup in config to effectively execute a ‘script’ of things to do (entities to change) when activated. Hence, from HA, you activate or ‘run’ a scene.
They also get included as entities when you integrate things like Google Home - In my case I have integrated my Somfy TaHoma Switch (which has ‘scenes’) hence I too have scenes like ‘Morning_Sun’ in TaHoma. Because of my TaHoma (Overkiz) integration I have an entity for scene.morning_sun in HA.
Yes I can ‘activate’ the scene in HA, and the scene is then run inside TaHoma. The state value for the entity scene.morning_sun is nothing more than the timestamp for when it was last run or executed, so when I activate the scene from within HA, the state value of scene.morning_sun is set to ‘now’.
Node_RED flow - trigger:
All flows have to start with something triggering them. NR is after all an event based ‘language’.
So, yes you can listen out for the state of ‘scene.bed_time’ changing (which it will do every time it is run from within HA).
You are using the trigger: state node, which is an advanced version of the event: state node, with additional conditional checks for the actual state change. In reality, since the scene entity state will only ever be a timestamp, you can simply listen out for it to change, so you really don’t need anything more complicated than the event: state node. This would be easier to set up and much more likely to work.
(as the other posters above have said - your trigger: state node is set to listen to the Boolean version of the state - which, for a timestamp should always be a non-zero ‘true’ - and with no conditions, so it is probably just firing on any old state update anyway.)
Switches:
Yes, we are all confused here!
You have trigger nodes again, apparently listening to your switches changing state. This is very different to having a service call that turns on (or off) a switch, so your user experience here seems to be:-
I say “Hey Home Assistant, activate bed time”.
Then I turn a wall switch on and off (twice)
Then… (something happens but your flow is not going anywhere else)
If this is not what you want to happen, then yes change the switch trigger nodes for service calls that change a switch entity state.
Loops:
I find Node-RED not great when trying to do loops, and I really do miss a ‘while…do’ loop. Well yes there is the loop node, but I personally like to arrange my code myself to ensure it works correctly. Physical loops in Node-RED can be a real problem with non-termination (loop control), memory leaks, and spaghetti code.
Looking at your code, you really just seem to want to do (something) twice following the trigger. In Node-RED ‘better’ practice would be to use an array, and iterate (or loop) over this by splitting it into parts, so each part is processed (and then perhaps later join up the array).
Example flow:
So, I have set up a simple events: state node to listen to a scene being triggered.
( I have also removed all of the output properties to just msg.payload - as I don’t need them I like to try and keep things like this tidy)
Then I have used a change node and a JSONata expression to generate an integer array (the [a…b] construct in JSONata generates a list of integers between a and b, hence I end up with just a simple array [1, 2])
Then I have used a split node, which spits out a new message for each item in the array (ie two messages)
Then I have put in a delay node set to rate-limit the messages so they are spaced out a bit in sequence. This is a neat way of doing things repeatedly, but without having a loop.
Then I used a call service node to (in this case) toggle a switch (a smart plug).
Then I tidy up again by joining up my split (this is not that important, but it does reduce the potential risk of memory leak as I have found from experience…)
This all avoids going around any loop, hence no control required to do and to exit the loop, no risk of infinite looping, and no memory leak issues.
It works too - I tried it. Winking lights when I activate my scene. Just change your ‘scene’ and ‘switch’ and ‘service’ to whatever you require (and reset to your Home Assistant server as I have ‘scrubbed’ this from my exported flow).
Merry Christmas to one and all.
[{"id":"98805b1fceb0f656","type":"server-state-changed","z":"023b12ef7d84d6be","name":"When I activate my routine","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"scene.morning_sun","entityIdType":"exact","outputInitially":false,"stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"}],"x":150,"y":80,"wires":[["781d8babde1e323a"]]},{"id":"0f231fe4979f1b1f","type":"split","z":"023b12ef7d84d6be","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":530,"y":80,"wires":[["0a93e223b2b8198a"]]},{"id":"781d8babde1e323a","type":"change","z":"023b12ef7d84d6be","name":"Set array 1 to n","rules":[{"t":"set","p":"payload","pt":"msg","to":"[1..2]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":80,"wires":[["0f231fe4979f1b1f"]]},{"id":"7e2f729a3c1aaa6b","type":"debug","z":"023b12ef7d84d6be","name":"debug 294","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":890,"y":180,"wires":[]},{"id":"0a93e223b2b8198a","type":"delay","z":"023b12ef7d84d6be","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"3","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":320,"y":180,"wires":[["ca94d21053e0e603"]]},{"id":"ca94d21053e0e603","type":"api-call-service","z":"023b12ef7d84d6be","name":"Toggle Light (switch)","server":"","version":5,"debugenabled":false,"domain":"switch","service":"toggle","areaId":[],"deviceId":[],"entityId":["switch.t2"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":540,"y":180,"wires":[["a2a50fb269b5697e"]]},{"id":"a2a50fb269b5697e","type":"join","z":"023b12ef7d84d6be","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":730,"y":180,"wires":[["7e2f729a3c1aaa6b"]]},{"id":"de16c07f02115655","type":"inject","z":"023b12ef7d84d6be","name":"Manual Test","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":190,"y":40,"wires":[["781d8babde1e323a"]]}]