Detect motion sensor movement and set / extend timer

For some reason I can’t get my head around which nodes I need to use.

I have TUYA pir sensor, binary_sensor.stairs_sensor, in Home Assistant when movement is detected it sets the state to ‘on’, but the state then stays on and doesn’t switch back to off. There appears to be more attributes available on the TUYA api but HA only appears to give access to the state.

I am thinking,

trigger when binary_sensor.stairs_sensor.state changes from off to on
set binary_sensor.stairs_sensor.state to off
if light.stairs_light is not on then turn on for 5 minutes,
if light.stairs_light is already on then extend the timer by a couple of minutes.
when timer is reached then turn light.stairs_light off.

Could anyone please advise which nodes I should look at using for a flow to do this

Have you been patient and waited for it to switch back?
Some PIR sensors have the detection time hardcoded and others can be set to a user defined value.
Several minutes are not uncommon though.

yes, I reset the state to off last night while testing, then it detected motion and it’s been in the on state since 10:22pm last night, its now 08:27am so for 10 hours.

Last changed:
[February 24, 2022, 10:22:58 PM]

Last updated:
[February 24, 2022, 10:22:58 PM]

There has been motion detected since then but it’s not updating on HA as it’s not switching state back to off so the state remains unchanged

I have now hacked a python script to turn the state off so just getting there

Ok, you have a working sensor then. :slight_smile:
Set your script to reset right away and then make your Node Red flow detect on that sensor.
Make the next detection node in Node Red split out to 2 other nodes.
The first one is the turn on chain and the other is the turn off chain.
Start the turn off chain with a merge node (dark yellow) and set the time here to how long you want your device turned on after last detection.

A merge node will reset the timer whenever a new message arrive and first sent the message on when the timer gets to 0 without being restarted.

1 Like

this is what I have, ‘is stairs on’ just checks if stairs light state has changed from off to on, ie if turned on by voice command etc

The ‘motion at bottom/top of stairs’ detects state off to on on the relevant motion sensor. next node calls the python script that sets the state to off for the relevant sensor. Next just checks it night time, no need to have on during daylight. and if so turns light on.

The Delay turning light off node is a ‘mytimeout’ node set to 180 seconds when started, each time it receives a message it restarts so should not reach 0 until 3 minutes after last motion, then when it gets to 0 the ‘turn stairs off’ does exactly that, turns light off.

Looks like you got all your requirements fulfilled. :slight_smile:

Yes, all works a treat thanks

For anyone else with same issue with state not turning off on their motion sensors here is the python script I used, saved as python_scripts/turn_off_sensor.py

inputEntity = data.get('entity_id')
if inputEntity is None:
    logger.warning("===== entity_id is required if you want to set something.")
else:
    inputStateObject = hass.states.get(inputEntity)
    inputState = inputStateObject.state
    inputAttributesObject = inputStateObject.attributes.copy()
    inputState = 'off'

    hass.states.set(inputEntity, inputState, inputAttributesObject)

Then use the call service node in node red, domain = python_script, service = script name, entitiy id = id of sensor to turn off.

For any one looking for a non python way this is what I did, has been working for at least a year reliably.

[{"id":"560a48e311b7eb68","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"5c2db089c40906f7","type":"stoptimer","z":"560a48e311b7eb68","duration":"20","units":"Minute","payloadtype":"num","payloadval":"0","name":"","x":460,"y":200,"wires":[["5f0b738695627d36","8aea4325d5c1efcd"],[]]},{"id":"5f0b738695627d36","type":"api-current-state","z":"560a48e311b7eb68","name":"Shop Motion","server":"1f07ad34.678b53","version":2,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.shop_motion_occupancy","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"x":450,"y":300,"wires":[["5c2db089c40906f7"],["05d5265c633fdc53"]]},{"id":"05d5265c633fdc53","type":"api-call-service","z":"560a48e311b7eb68","name":"shop lights off","server":"1f07ad34.678b53","version":3,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.shp_lights","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":680,"y":220,"wires":[[]]},{"id":"9e0ec0746592f426","type":"api-call-service","z":"560a48e311b7eb68","name":"shop lights on","server":"1f07ad34.678b53","version":3,"debugenabled":false,"service_domain":"switch","service":"turn_on","entityId":"switch.shp_lights","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":680,"y":140,"wires":[[]]},{"id":"fffc264821afe1b2","type":"server-state-changed","z":"560a48e311b7eb68","name":"shop motion","server":"1f07ad34.678b53","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"binary_sensor.shop_motion_occupancy","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":230,"y":200,"wires":[["247c114b9cd7f03c"]]},{"id":"dcf42bac9c0e9e5c","type":"server-state-changed","z":"560a48e311b7eb68","name":"Shop Motion 2","server":"1f07ad34.678b53","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"binary_sensor.shop_motion_2_occupancy","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":210,"y":280,"wires":[["247c114b9cd7f03c"]]},{"id":"8aea4325d5c1efcd","type":"api-current-state","z":"560a48e311b7eb68","name":"Shop motion 2","server":"e173a2fc.b1fb3","version":2,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.shop_motion_2_occupancy","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":440,"y":380,"wires":[["5c2db089c40906f7"],["05d5265c633fdc53"]]},{"id":"247c114b9cd7f03c","type":"switch","z":"560a48e311b7eb68","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":410,"y":140,"wires":[["9e0ec0746592f426"],["5c2db089c40906f7"]]},{"id":"1f07ad34.678b53","type":"server","name":"Home Assistant","version":1,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true},{"id":"e173a2fc.b1fb3","type":"server","name":"Home Assistant","version":1,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

1 Like

Thanks for the python script, but I have a noob question. How do you declare and pass the entity id from the call service node to the script?

I believe this might work. The first node is listening to events, not states, so I hope that’ll do it.

[{"id":"cbea822c.dfd82","type":"api-current-state","z":"937ef78.ec6b408","name":"Get lights state","server":"9405c3fe.d0a6c","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"light.stairs_light","state_type":"str","blockInputOverrides":true,"outputProperties":[{"property":"delay","propertyType":"msg","value":"","valueType":"entityState"}],"for":0,"forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":360,"y":180,"wires":[["41760a4a.c5fad4"]]},{"id":"571f7f64.4fec9","type":"server-state-changed","z":"937ef78.ec6b408","name":"stairs' PIR","server":"9405c3fe.d0a6c","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"binary_sensor.stairs_sensor","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"}],"x":200,"y":180,"wires":[["cbea822c.dfd82"]]},{"id":"41760a4a.c5fad4","type":"change","z":"937ef78.ec6b408","name":"set delays","rules":[{"t":"change","p":"delay","pt":"msg","from":"on","fromt":"str","to":"120000","tot":"num"},{"t":"change","p":"delay","pt":"msg","from":"off","fromt":"str","to":"300000","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":180,"wires":[["d4af371.ec856c8"]]},{"id":"d4af371.ec856c8","type":"trigger","z":"937ef78.ec6b408","name":"","op1":"","op2":"","op1type":"pay","op2type":"payl","duration":"250","extend":true,"overrideDelay":true,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":2,"x":615,"y":180,"wires":[["38163490.a4df3c"],["4a991734.321648"]],"l":false},{"id":"553b7105.a2369","type":"api-call-service","z":"937ef78.ec6b408","name":"light on","server":"9405c3fe.d0a6c","version":3,"debugenabled":false,"service_domain":"","service":"","entityId":"","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":780,"y":160,"wires":[[]]},{"id":"be79b69d.31d678","type":"api-call-service","z":"937ef78.ec6b408","name":"light off","server":"9405c3fe.d0a6c","version":3,"debugenabled":false,"service_domain":"","service":"","entityId":"","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":780,"y":200,"wires":[[]]},{"id":"38163490.a4df3c","type":"api-current-state","z":"937ef78.ec6b408","name":"light off?","server":"9405c3fe.d0a6c","version":3,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","entity_id":"stairs_light","state_type":"str","blockInputOverrides":true,"outputProperties":[],"for":0,"forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":675,"y":160,"wires":[["553b7105.a2369"],[]],"l":false},{"id":"4a991734.321648","type":"api-current-state","z":"937ef78.ec6b408","name":"light on?","server":"9405c3fe.d0a6c","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"stairs_light","state_type":"str","blockInputOverrides":true,"outputProperties":[],"for":0,"forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":675,"y":200,"wires":[["be79b69d.31d678"],[]],"l":false},{"id":"9405c3fe.d0a6c","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

check my post at Detect motion sensor movement and set / extend timer - #8 by iamgrog68

Opera Snapshot_2022-03-22_172414_homeassistant.local

As you can see, there is no entity id field to complete. As soon as I select the script, all the other fields disappear. If I enter the entity id before selecting the service I get the logger error that enity_id is required.

Sorry for confusion, when I posted the post above it doesn’t look like I had set service.

Service is set to ‘set_state’ and there is no entity_id when that is set, I am assuming it passes the entity_id from the trigger state node to the script as it still works as expected.

This works only if your sensor sends an “off” state to trigger the switch (On/Off). For some of the tuya sensors it only ever sends an “on” state, so the lights never turn off (because the state never changes).

Does this help?

1 Like

It doesn’t work for me. I have bought new PIRs, but am happy to test any solution given, as I’ve still got the old ones and would like to integrate them if possible.