Reseting Timer If Motion is Detected

Hello all,

I am trying to create a rule that will turn off certain items (mainly lights) if motion is not detected for 1 hour. I am using the HC-SR501 PIR motion sensor with the mysensors framework. The sensor checks every 10 seconds (may increase this time later, just using a small number for testing) for motion. If it detects motion it returns a 1 and if it does not detect motion it returns a 0. I currently have a rule set up that turns on lights when the motion sensor changes from 0 to 1.

var timer = null
rule "Motion Sensor Lights On"
when
	Item Bedroom_Motion changed from 0 to 1
then
	if(now.getHourOfDay < 22 && now.getHourOfDay > 8){
	Outlet_4.sendCommand(ON)
	Night_Stand_Lamp.sendCommand(ON)
	createTimer(now.plusSeconds(3)) [|
	Outlet_5.sendCommand(ON)
	timer = null]
	}
end 

This rule seems to work great. I have created a somewhat working rule to turn them off. My problem is that it basically turns the lights off after 1 hour unless motion it detected after that 1 hour. My problem is that I wish to reset the timer if motion is detected at all. Here is the rule I’ve been using:

rule "Motion Sensor Lights Off"
when
	Item Bedroom_Motion changed from 1 to 0
then
	createTimer(now.plusSeconds(3600)) [|
	if(Bedroom_Motion.state == 0){
	Outlet_4.sendCommand(OFF)
	Night_Stand_Lamp.sendCommand(OFF)
	createTimer(now.plusSeconds(3)) [|
	Outlet_5.sendCommand(OFF)
	timer = null]	
	}
	timer = null
	]
end

Also the reason I have another timer nested is because I needed a delay before turning on the other light. If anyone could offer any advice it’d be much appreciated! Thanks

1 Like

Start with creating a variable like
Timer nightStandLampTimer = null
Then in the rule when you create the timer use
if (nightStandLampTimer != null) {
nightStandLampTimer. cancel
nightStandLampTimer = null
}
nightStandLampTimer = createTimer(now.plusSeconds(3600)) [|
if(Bedroom_Motion.state == 0){
Outlet_4.sendCommand(OFF)
Night_Stand_Lamp.sendCommand(OFF)
createTimer(now.plusSeconds(3)) [|
Outlet_5.sendCommand(OFF)
timer = null]
}
nightStandLampTimer = null
]
end

I did this post on my phone so it may need adjustments.

I would definitely use the expire binding in this case as it simplifies a lot the coding part

To give an example from my rules I have created an motion sensor item (you can ignore the mosquitto part and check the expire part where it is set to expire (set to OFF) 20 seconds after being triggered

Switch BathMvSensor {mqtt"<[mosquittobroker:mysensors-out/5/2/1/0/16:state:ON:1]",expire="20s,state=OFF"}

If it is triggered in between the timer is reset

Then the rule really becomes easy. Here is an example

rule "Bathroom Motion"
when
        Item BathMvSensor received update
then
        if(Manual_Override.state!=ON) {
        logDebug("debugrules", "Manual override is OFF")
                if(BathMvSensor.state != OFF) {
                        logDebug("debugrules", "Bathroom: Motion Detected and lights ON")
                        sendCommand(BathLights, ON)
                }
                else {
                        logDebug("debugrules", "Bathroom: Motion OFF and lights OFF")
                        sendCommand(BathLights, OFF)
                }
        }
end

Hope this helps
Christos