Motion Detector PIR not sending updates if already motion is detected

Hi,

I am running OH v3 fine on a windows base. I have a lot of stuff meanwhile in my house and also different vendors for motion sensors. I am running Homematic, Philips and Sonoff in this case.

Most of them are working properly but what I notice is that my rule for the Case with the Sonoff is not working properly. This device is sending the status via MQTT so that the Switch item in my case is detecting well if motion is detected (=ON) or if motion is not detected (=OFF).

I am using an occupancy timer in this case in the rule which is triggered well when the motion detector is off and on again before the initial timer runs out.
The problem is that when someone is in the room the detector turns on and the person is still moving the detector is not switching to off and so the occupancy timer runs out and will not rescheduled. In this case it happens that sometimes the lights turns out and cannot enabled again because the motion detector is still turned on in this case.

I have change my rule a little bit but I am not completely fine with it - any hints?

var Timer occupancyTimer = null

rule "BWM Gäste WC Test"

when
	Item BWM_GaesteWC_Motion changed from OFF to ON
	
then
	if(occupancyTimer === null || occupancyTimer.hasTerminated()) {
		
		Licht_GaesteWC_Dimmer.sendCommand(50)
			
		occupancyTimer = createTimer(now.plusMinutes(3), [|
			
			if(BWM_GaesteWC_Motion.state == OFF) {
				Licht_GaesteWC_Dimmer.sendCommand(0)
				occupancyTimer = null
			} else {
				occupancyTimer.reschedule(now.plusMinutes(1))
			}
		])
			
	}
		
	else {
		occupancyTimer.reschedule(now.plusMinutes(3))			
	}

end

The branch BWM_GaesteWC_Motion.state == OFF is never reached because you enter the rule only, if BWM_GaesteWC_Motion changed from OFF to ON, so it can’t be OFF.

You could separate the events:
When a movement is detected (ON) → switch on in the Dimmer
When no movement is detected (OFF) → start your occupancyTimer

1 Like

Ok - I thought that this will “worked through” if the timer reaches the limit. So I will make 2 rules:

1st rule

rule "BWM Gäste WC Einschalten"

when
	Item BWM_GaesteWC_Motion changed from OFF to ON
	
then
	Licht_GaesteWC_Dimmer.sendCommand(50)
end

2nd rule

var Timer occupancyTimer = null

rule "BWM Gäste WC Ausschalten"

when
	Item BWM_GaesteWC_Motion changed from ON to OFF
	
then
	occupancyTimer = createTimer(now.plusMinutes(2), [|
		Licht_GaesteWC_Dimmer.sendCommand(0)
		occupancyTimer = null
        ])
end

But how the timer will handle it if the detector jump to ON in the meantime - will the timer cancelt in this case?

Let your rule get triggered by any update and not only by state change.
If the updated state is ON, you can turn on light / reschedule trigger.

@Matze0211 Doesn’t

Item BWM_GaesteWC_Motion changed from OFF to ON

implies an update?

@Matthias_Marx The timer is only affected by a transition ON to OFF. If it is called when the timer is already running, I would expect that the timer is restarted.

What do you mean in detail? Are you referring to my 1st rule in the first post? In the past I was using

Item BWM_GaesteWC_Motion received update ON

instead without no success.

Or do you mean 1st and 2nd rule in the other post?

No. Update will trigger even if the item does not change the state

Sorry, but I do not understand, maybe you can give more information. So you suggest to use only one rule in this way?

var Timer occupancyTimer = null

rule "BWM Gäste WC Test"

when
	Item BWM_GaesteWC_Motion received update ON
	
then
	if(occupancyTimer === null || occupancyTimer.hasTerminated()) {
		Licht_GaesteWC_Dimmer.sendCommand(50)
			
		occupancyTimer = createTimer(now.plusMinutes(3), [|
			if(BWM_GaesteWC_Motion.state == OFF) {
				Licht_GaesteWC_Dimmer.sendCommand(0)
				occupancyTimer = null
			} else {
				occupancyTimer.reschedule(now.plusMinutes(1))
			}
		])
			
	}
		
	else {
		occupancyTimer.reschedule(now.plusMinutes(3))
	}
end

Yes, maybe add some logging so you will see how often the rule is triggered

I have now changed it this way. For now it looks that it is working. I will check it the next days:

var Timer occupancyTimer = null

rule "BWM Gäste WC Einschalten"
	when
		Item BWM_GaesteWC_Motion changed from OFF to ON
	then
		logInfo("TEST", "Regel wird gestartet - Einschalten")
		
		Licht_GaesteWC_Dimmer.sendCommand(70)
		
		if(occupancyTimer === null) {
			logInfo("TEST", "Timer läuft noch nicht")
		}
		else {
			occupancyTimer.reschedule(now.plusMinutes(2))
			logInfo("TEST", "Timer wurde hochgesetzt")
		}
	end

rule "BWM Gäste WC Ausschalten"
	when
		Item BWM_GaesteWC_Motion changed from ON to OFF
	then
		logInfo("TEST", "Regel wird gestartet - Ausschalten")
		
		Licht_GaesteWC_Dimmer.sendCommand(30)
		
		occupancyTimer = createTimer(now.plusMinutes(2), [|
			logInfo("TEST", "Timer abgelaufen")
			Licht_GaesteWC_Dimmer.sendCommand(0)
			occupancyTimer = null
			])
	end

You have again a rule thats only triggered by change, not by update.

If you want to have the light turned ON with motion, but turned OFF once no motion is detected, your rule should be triggered by change, but you do not need timers at all and can just turn on the light, if the PIR will change from OFF to ON and vice versa.

If you want the light to automatically go on, but only off after a certain time + you want to extend that time, if motion is continuously detected, than you should have a rule triggered by update + you need a timer.

My rule:
Triggered by Item update & state = ON (–> every time the PIR sends an ON message, not only when it is changing from OFF to ON)

Script:

//Turn on light
items.getItem('<light switch item>').sendCommand('ON');

        //40 seconds timer, to switch off the light (my PIR is sending update every 30 seconds)
        if (cache.private.exists('MyTimer') === false || cache.private.get('MyTimer').hasTerminated()) {
          cache.private.put('MyTimer', actions.ScriptExecution.createTimer('MyTimer', time.ZonedDateTime.now().plusSeconds(40), function () {
            items.getItem('<light switch item>').sendCommand('OFF');
            }));
        } else {
          //if timer is already scheduled, but PIR continue to send ON command, reschedule timer by another 40 seconds
          cache.private.get('MyTimer').reschedule(time.ZonedDateTime.now().plusSeconds(40));
        };

I absolutely understood what you say but the problem is that my PIR (SONOFF, connected via MQTT) is only sending 2 status updates: from ON to OFF and vice versa. I have this kind of rule the past months and it was not working in any case.

I am not seeing updates if the PIR is turned ON and stays on. In this case the light will turn off if I work with a timer. I see in your rule that your PIR is sending updates every 30 seconds, but this is not the case in my environment.
And if I turn off the light if the PIR turns from ON to OFF I am staying in the dark, too so that I have to trigger the motion again.

You need to simplify your rule to make sense of what’s happening here. Try this one and see what happens when you trigger your motion sensor. You should see logged an update to show your what state the motion is sending.

rule "Test My Motion Sensor"
	when
		Item My_Motion_Sensor received update
	then
		logInfo("TEST", "My Motion Sensor has received and update: {}.", My_Motion_Sensor.state)
	end

I don’t understand why your using the syntax “changed from OFF to ON” you could just use “changed to ON” instead.

I changed the rule to “changed to ON/OFF” instead of “changed from ON/OFF to ON/OFF”. I have also created the rule for logging and I will check if I get any output here.