Motion detection and how to translate "for" to node-red

So for the second time I am trying to slowly pass my automations from yaml to node-red.
I am stuck in one of the most used automations that I have. How to turn off lights if there is no motion for X minutes.

What I have done so far is:

[{"id":"ece70edb.8ef5c","type":"server-state-changed","z":"17be72b6.fc87cd","name":"Kitchen Motion Detection","server":"eaecb825.5ab888","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"binary_sensor.motion_sensor_158d0003f3edfc","entityidfiltertype":"substring","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"x":130,"y":440,"wires":[["94cce413.5caff8"]],"info":"binary_sensor.motion_sensor_158d00036d5a35_garage_workbox"},{"id":"ab6affb5.5bb88","type":"api-call-service","z":"17be72b6.fc87cd","name":"Turn on","server":"eaecb825.5ab888","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.shelly_kitchen_lights_cabinet","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":960,"y":420,"wires":[["ad59f9c2.6dbc68"]]},{"id":"dd8cde40.54d79","type":"api-current-state","z":"17be72b6.fc87cd","name":"Is any light on?","server":"eaecb825.5ab888","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"light.kitchen_lights","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":540,"y":420,"wires":[[],["a04a51cf.1ef3c"]]},{"id":"ad44f84c.c0d828","type":"comment","z":"17be72b6.fc87cd","name":"Kitchen Motion Detection","info":"","x":110,"y":380,"wires":[],"icon":"node-red/bluetooth.png"},{"id":"94cce413.5caff8","type":"switch","z":"17be72b6.fc87cd","name":"On-Off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":330,"y":440,"wires":[["dd8cde40.54d79","ad59f9c2.6dbc68"],["ad59f9c2.6dbc68"]]},{"id":"a04a51cf.1ef3c","type":"api-current-state","z":"17be72b6.fc87cd","name":"Low illumination?","server":"eaecb825.5ab888","version":1,"outputs":2,"halt_if":"60","halt_if_type":"num","halt_if_compare":"lte","override_topic":false,"entity_id":"sensor.illumination_158d0003f3edfc","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":770,"y":420,"wires":[["ab6affb5.5bb88"],[]]},{"id":"ad59f9c2.6dbc68","type":"stoptimer","z":"17be72b6.fc87cd","duration":"10","units":"Minute","payloadtype":"num","payloadval":"0","name":"10 min","x":630,"y":500,"wires":[["83780870.ece548"],[]]},{"id":"f8b17db4.bb34d","type":"api-call-service","z":"17be72b6.fc87cd","name":"Turn off","server":"eaecb825.5ab888","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.kitchen_lights","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1220,"y":460,"wires":[[]]},{"id":"4493d623.b25d58","type":"api-current-state","z":"17be72b6.fc87cd","name":"Is TV off?","server":"eaecb825.5ab888","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"media_player.lg_kitchen_tv","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1040,"y":500,"wires":[["f8b17db4.bb34d"],["eb7a166.1bf23e8"]]},{"id":"eb7a166.1bf23e8","type":"trigger-state","z":"17be72b6.fc87cd","name":"TV turns off","server":"eaecb825.5ab888","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"media_player.lg_kitchen_tv","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"id":"ygscgf6zloj","targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off"}],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":1210,"y":540,"wires":[["1d7b6933.00b027"],[]]},{"id":"8ac39f82.44d8","type":"api-call-service","z":"17be72b6.fc87cd","name":"Turn off","server":"eaecb825.5ab888","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.kitchen_lights","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1580,"y":540,"wires":[[]]},{"id":"1d7b6933.00b027","type":"stoptimer","z":"17be72b6.fc87cd","duration":"2","units":"Minute","payloadtype":"num","payloadval":"0","name":"2 min","x":1410,"y":540,"wires":[["8ac39f82.44d8"],[]]},{"id":"83780870.ece548","type":"api-current-state","z":"17be72b6.fc87cd","name":"Is any light on?","server":"eaecb825.5ab888","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"light.kitchen_lights","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":860,"y":500,"wires":[["4493d623.b25d58"],[]]},{"id":"eaecb825.5ab888","type":"server","z":"","name":"Home Assistant","addon":true}]

What I am trying to do is:

If motion is detected and there is no open light and there is not much sun in the kitchen, turn on a light. Easy and it works perfect.

Now the difficult part.
If for 10 minutes there is no motion and there is a light on, check what happens with TV. If it is off, turn the lights off. If it is on, wait until the TV turns off and then after 2 minutes, close the lights.

Biggest problem here is that the part “If for 10 minutes there is no motion” doesn’t work correct and the lights close and don’t open again after even if there is motion in the room.
Then what I am trying to do with the TV, I haven’t been able to test it so far bcs of the previous issue.

The simple automation that I had before:

- alias: Kitchen light on when movement
  trigger:
  - entity_id: binary_sensor.motion_sensor_158d0003f3edfc
    platform: state
    to: 'on'
  condition:
    condition: and
    conditions:
    - condition: state
      entity_id: light.shelly_kitchen_lights_window
      state: 'off'
    - condition: numeric_state
      entity_id: sensor.illumination_158d0003f3edfc
      below: 60
  action:
  - data:
      entity_id: light.shelly_kitchen_lights_window
    service: light.turn_on

and:

- alias: Kitchen light off when no movement
  trigger:
  - entity_id: binary_sensor.motion_sensor_158d0003f3edfc
    for:
      minutes: 10
    from: 'on'
    platform: state
    to: 'off'
  action:
  - data:
      entity_id: light.kitchen_lights
    service: light.turn_off

WAF is killing me… :yum: Any suggestion would be nice.
But don’t forget that I am noob in node-red so take it easy on me! :smiley:

Did you tried to debug every output of the nodes? there is a debug node that outputs everything to the debug window of node-red.
With

you mean the lights turn off and don’t turn on again, right?

Yes they dont turn on again. Not for the next minute or so.

The debug where should I place it? in 2 cases of the switch?Capture

If you think the 10 min timer doesn’t work properly you could place them before and after that node. That way you can check which node does not behave like you want.

This problem had me stumped as well when I first moved over to NodeRed. This is how I handle things now:

For a basic “turn the lights on/off after delay on motion”, this is how I do it:

Basically, the trigger node is my best friend for motion-based flows. The reason why I use it over a delay node is that it can be reset with a payload set to a defined string. This works GREAT for motion and contact sensors because if you set it to “on” and wire both the true and false outputs of an event-state node, if the motion sensor detects motion again, it will cancel the timer.

1 Like

Looks like a good solution.
Also, if you want to use the debug node and you are working with different messages (not just payload), you have to set the debug-node to “full message object” or change the message (msg.yourMessage).

1 Like

I use the node-red-contrib-stoptimer3 node for motion lighting and I love it. Everytime it recieves a message, it restarts the timer. You can send it a paylod.duration and it will update the timer duration. You send it a payload of stop and it will stop the timer and never send the message. It is the workhorse of all my motion lighting flows:

2 Likes

I used to use stoptimer3 until the source got corrupted during a node update a couple of years ago. Ever since then I switched over to trigger. I do miss the payload.duration though (trigger has no way to specify a duration programmatically :frowning: ).

I haven’t noticed any issues yet; thanks for the heads-up. Another node I’ve started playing with for motion lighting is the timed-counter node. You set a duration and it counts all the messages in that period. I’ve begun playing with using this node with stoptimer3 to dynamically extend the motion timeout based on activity in the room. I think I want to extend the duration as more events get detected (an indication of an active, engaged room).

Still have to perfect it, but looking good so far.

1 Like

Yeah, that’s kind of what my “Occupied” nodes are going to do eventually. So, if a motion event happens (on/off), set a flow variable to true/false denoting the room is “occupied”. Then, when another motion event happens, check to see if the occupied flag is set, and if it is, extend the timeout by {x} number of seconds or minutes. Currently my triggers work well enough, but there are times where we encounter a race condition that the trigger has expired and the lights start to go off and then motion happens again and the lights come back up. It produces this weird “half on/half off” effect just long enough to be annoying.

The initial goal was for audio notifications to only route to rooms that are occupied rather than just blasting over the whole house. But now, I have more grandiose ideas. LOL

1 Like

can u please export and post an example? I thought I was doing more or less the same thing but it doesn’t seem to reset the timer.

can you please export it so as I can understand better what u r doing in the switch with the 6 out options?
And the “Setup Payload”.
:slight_smile:

Yeah, but the “Mode” node is part of my own mode manager which I do using a combination of NodeRed and HA time of day sensors.

This is a cleaner one without my mode stuff in it:

[{"id":"1ccfc23a.98ab6e","type":"tab","label":"Hallway","disabled":false,"info":""},{"id":"297a1042.d2a5d8","type":"server-state-changed","z":"1ccfc23a.98ab6e","name":"Hallway Motion","server":"df8e6220.fa7b2","version":1,"exposeToHomeAssistant":true,"haConfig":[{"property":"name","value":"Hallway Motion Trigger"},{"property":"icon","value":""}],"entityidfilter":"binary_sensor.hallway_motion_sensor","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":120,"y":120,"wires":[["c3d85946.7180a8","c59b1889.03cb5","95f3000d.6a1a1"],["c59b1889.03cb5","95f3000d.6a1a1"]]},{"id":"c3d85946.7180a8","type":"function","z":"1ccfc23a.98ab6e","name":"Setup Payload","func":"msg.payload = {};\n\nvar mode = global.get(\"mode\");\n\nnode.status({fill:\"green\", shape: \"ring\", text: mode });\n\nmode = mode.toLowerCase().replace(\" \", \"_\");\n\nmsg.payload = {\n domain: \"scene\",\n service: \"turn_on\",\n data: {\n entity_id: \"scene.hallway_light_\" + mode\n }\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":120,"wires":[["edcdb42d.45aed"]]},{"id":"edcdb42d.45aed","type":"api-call-service","z":"1ccfc23a.98ab6e","name":"Lights on","server":"df8e6220.fa7b2","version":1,"debugenabled":false,"service_domain":"","service":"","entityId":"","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":540,"y":120,"wires":[[]]},{"id":"c59b1889.03cb5","type":"trigger","z":"1ccfc23a.98ab6e","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"15","extend":false,"units":"s","reset":"on","bytopic":"all","topic":"topic","outputs":1,"x":350,"y":200,"wires":[["ee60f62b.c9936"]]},{"id":"ee60f62b.c9936","type":"api-call-service","z":"1ccfc23a.98ab6e","name":"Lights off","server":"df8e6220.fa7b2","version":1,"debugenabled":false,"service_domain":"scene","service":"turn_on","entityId":"scene.hallway_light_off","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":540,"y":200,"wires":[[]]},{"id":"95f3000d.6a1a1","type":"trigger","z":"1ccfc23a.98ab6e","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"15","extend":false,"units":"min","reset":"on","bytopic":"all","topic":"topic","outputs":1,"x":350,"y":260,"wires":[["ee60f62b.c9936"]]},{"id":"df8e6220.fa7b2","type":"server","z":"","name":"Home Assistant","legacy":false,"addon":false,"rejectUnauthorizedCerts":false,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":false}]

I cant understand the logic behind it if u can help. why do you have 15 seconds and 15 minutes?
If there is no motion for 15 seconds, the lights will turn off? If yes then why do you also have the 15 minutes trigger?

I am confused! :confused:

Because I use WizLights (which I LOVE) and they support powering off and on via the switch to change light modes. BUT, when that happens, the motion sensor routine gets out of whack. Plus, I also have the event-state node exposed to HA as a switch so that if I don’t want the lights to react to motion (like in the middle of the night or when my wife and I aren’t home and the dogs are running around).

So, because I don’t want to have to remember to turn off the lights, and we generally don’t spend more than 10 minutes in the hallway, they automatically turn off after 15 minutes.

I hope that makes sense?

I am getting there!
So in my case I should only use one trigger.
Something like that?


and the option “extend delay if new message arrives” shouldnt be active?
in your last example it is not.

That would do it. How do you have the trigger node configured? Make sure that msg.payload is set to “on” in the trigger settings.

Nah, I generally don’t use it because I trend towards longer time outs and I use a reset anyhow.

1 Like

1 Like

You should be good to go! Make sure to check out stoptimer3 as well. Both it and trigger are lifesavers when it comes to motion lighting.

Yes I will check it! Hopefully I will get help from the extract of Andy later.
Thx for your help. will try it and if needed will come back to you.

1 Like