PIR sensor, timer rule won't work as intended

Hi All,

I’ve been tearing my hair out trying to get a rule to work as I want. If anyone could help that would be great, thanks in advance.

What I’m trying to do:

  1. I walk in the room and the light turns on

  2. If motion has not been detected for 5min then turn light off

  3. Only send a command to my light switch when necessary so my gateway does not get multiple “on” commands for example

  4. Have the ability to turn the rule off so if someone sleeps in the room the light is not going on and off in the middle of the night.

What I’ve read:

And about another 10 topics but those are the main ones.

.items

Switch Sensor_Office_Motion   		"Office Motion"		{ channel="zway:zwayDevice:192_168_0_222:24:sensorMotion-ZWayVDev_zway_24-0-48-1",expire="5m,command=OFF"}
Switch Switch_Rule_Office_Motion

.sitemaps

Switch item=Switch_Rule_Office_Motion label="Office" icon="motion" mappings=[OFF="Off", ON="On"]

.rules

rule "Office Motion On"
when 
	Item Sensor_Office_Motion changed from OFF to ON
then
	if (Dimmer_Office.state != "0" && Switch_Rule_Office_Motion.state != "ON") 
	{
		Dimmer_Office.sendCommand(99)
		logInfo("Office motion", "IF")
	}
	else 
	{
		logInfo("Office motion", "ELSE")
	}
end

Switch_Rule_Office_Motion appears to a Switch Item, so it doesn’t have a string state of “ON” , rather it would be ON or OFF

I don’t know what kind of Item Dimmer_Office might be, but I’ll bet it is not String either.

I don’t know about zwave and on that device also. Please refer to the manual of your PIR sensor. Normally they have own logic, which can interfere with your rule-logic. I experienced two main behaviours:

  1. sensor sends ON at the time of the first movement, then nothing and OFF after xx min. (fixed interval within the sensor, oftentimes configurable)
    This will repeat immediately, if further movement after OFF is detected.
  2. sensor sends ON everytime he sees Motion (normally it won’t send OFF)

Presently you’re using the expire-binding to switch your openHAB item Sensor_Office_Motion to OFF after 5mins, if the item doesn’t get updates within that time.
You have a second item Switch_Rule_Office_Motion, which is only being changed via the sitemap in the UI.

What’s going on is, your rule only fires, if the sensor is changed von OFF to ON. So depending on the above behaviour this can be only once or everytime after the sensor’s interval. It won’t be triggered though, if you click the Switch_Rule_Office_Motion in the UI.

So, next, your IF-clause won’t go in, as both items are Switches and not strings.

	if (Dimmer_Office.state != OFF && Switch_Rule_Office_Motion.state != ON) 

but that’s still not the logic you Need (see above). So please check your sensor’s behaviour and try again with this info. Come back here, if you need more help, of course.

Sorry I’m very new to rules and code in general so forgive me if i don’t understand correctly.

So the following type of code in my rule only works for strings and I’m using a switch?

if (Dimmer_Office.state != OFF && Switch_Rule_Office_Motion.state != ON)

My sensor in z-wave is set to send an “ON” command to Openhab when it detects motion, it then follows up with an “OFF” command after 10 seconds (default setting in gateway). I can see this happening in the OH logs. I set my rule to “changed from OFF to ON” so it only sends the command to OH when it detects motion and ignores the “OFF”

I can change the timing in my gateway to 5 minutes for example but all that does is triggers an action and goes to sleep for 5 minutes which is useless.

In an effort to tackle one problem at a time I have simplified my rule:

.rule

rule "Office Motion On"
when 
	Item Sensor_Office_Motion changed from OFF to ON
then
	Dimmer_Office.sendCommand(99)
	logInfo("Office motion", "Turn Light ON")
end

.items

Switch Sensor_Office_Motion   		"Office Motion"		{ channel="zway:zwayDevice:192_168_0_222:24:sensorMotion-ZWayVDev_zway_24-0-48-1",expire="5s,command=OFF"}

log

14:56:33.739 [INFO ] [marthome.event.ItemStateChangedEvent] - Sensor_Office_Motion changed from OFF to ON
14:56:34.139 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'Dimmer_Office' received command 99
14:56:34.152 [INFO ] [smarthome.model.script.Office motion] - Turn Light ON
14:56:39.361 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'Sensor_Office_Motion' received command OFF
14:56:40.483 [INFO ] [marthome.event.ItemStateChangedEvent] - Sensor_Office_Motion changed from ON to OFF

With this the dimmer turns on when my PIR receives motion but after 5s it does not turn off even though I have the “Expire” binding added and have added "expire=“5s,command=OFF” to my item.

Any ideas?

It does exactly what it should! :wink:

First of all: understand, what your sensor does - and this is behaviour #1 in my previous post:

  1. it sends ON if it detects movement
  2. it does nothing for a configurable time (in that case 5sec)
  3. it sends OFF (regardless of motion in between first movement detection)
  4. it sends ON again, if there’s (still? you won’t know) movement

so, keep this always in mind - That logic is as it is and you can only change the interval from 5secs to 5mins or whatever).

so, what you have to do is to take those two events (ON and OFF) - and bring it in correlation. Your goal is obviously to turn the light on (and let it burn) while there’s movement. and turn it off, if there’s no more movement, isn’t it?

so, you have to have an expire-intervall, which is longer than the sensor-intervall in your zwave. How much longer depends on the use of the room and the position, the sensor is placed. you can have short intervalls in your zwave sensor and a long one in expire, so the light will not turn off eventually, if someone is still in the room but either in a dead angle or just not moving (like - watching TV, staring in the computer screen or whatever).

For a better understanding, use two rules then:

when 
	Item Sensor_Office_Motion changed to ON 
	// do something: I guess, turning on your dimmer_office and logInfo it (as you already did)

(remember, if you just restarted OH2 for some reason, the Change will be from UNDEF to ON! that’s why I left out the from part.)
theres a difference between changed to and received command - even if your item received the command ON from the sensor if it still had the state ON, it didn’t change - see?

when 
	Item Sensor_Office_Motion changed to OFF 
	// do something: If you expired the Dimmer_office you won't turn it off, but at least logInfo the event to understand your sensor's behaviour (at least until everything works, then you can turn logging it to OFF #SPAM

so, and now to the first part of your question:
if you have a String item, you want to have If Item == '<STRINGVALUE>' (with quotes) in your rule. if you have Number it’s If Item == <Number> (without quotes). And if it’s Switch in your case, you want it If Item == <ON/OFF>.

So, now to your problem: If your sensor sends OFF from itself, you won’t need the expire-part on openHAB side with Sensor_Office_Motion, do you? so, put the expire-part on your Dimmer_Office item and play around as I said with both intervals until it fits your needs.

Thanks very much for taking the time to help me out, it is much appreciated!

Exactly

Yes my intention is to leave the sensor settings as is and set OH to turn my light off after no movement has been detected for 10min.

Ahh I see!

Currently I have no String items, do I need them in order to correctly switch my rule on and off?

Switch Sensor_Office_Motion "Office Motion" { channel="zway:zwayDevice:192_168_0_222:24:sensorMotion-ZWayVDev_zway_24-0-48-1",expire="1m,command=OFF"}
Switch Switch_Rule_Office_Motion
Dimmer Dimmer_Office "Office Main " { channel="zway:zwayDevice:192_168_0_222:2:switchMultilevel-ZWayVDev_zway_2-1-38" }

I’ll do some experimenting based on what you have said and see where I get to. Thanks again!

no, you won’t need extra String items, but you want the expire-command on the dimmer (but you’re on it already I guess):

Switch Sensor_Office_Motion "Office Motion" { channel="zway:zwayDevice:192_168_0_222:24:sensorMotion-ZWayVDev_zway_24-0-48-1"}
Switch Switch_Rule_Office_Motion
Dimmer Dimmer_Office "Office Main " { channel="zway:zwayDevice:192_168_0_222:2:switchMultilevel-ZWayVDev_zway_2-1-38",expire="1m,command=OFF" }

(if everything works we can discuss the UI-switch issue)

Here is my updated rule

rule "Office Motion On"
when 
	Item Sensor_Office_Motion changed to ON
then
	Dimmer_Office.sendCommand(99)
	logInfo("Office motion", "Rule Light ON")
end

rule "Office Motion Off"
when 
	Item Sensor_Office_Motion changed to OFF
then
	logInfo("Office motion", "Rule Light OFF")
end

Oh dear, I cannot believe I did not realise that the “expire” should be on the dimmer. I put on the sensor as I thought I wanted the manual switch to work independently of my rule but what would have been the point of that! :confounded:

I guess if I did want another switch that was not effected by the expire then I should just create another item without the expire code on the end.:roll_eyes:

Anyway, motion or the flick of my manual switch turns the light on and after 10 min it turns off. The “Office Motion Off” shows the log info as it should so I’ve commented it out.

Part way there now, thanks very much.

So now I have two remaining things to solve:

  1. Be able to switch the rule off so my sensor does nothing and also make sure that my light does not go off automatically once the manual switch is pushed. I don’t even know where to begin.

  2. Only send a command to my z-wave gateway when necessary.

I’m glad to hear, you worked it out!

So, now you have the behaviour you want for automatic use. If you want to override that one, you need a proxy item, which you can check for this one.

So, what you need is:

  1. Proxy item “Office Manual Mode” (I suggest using a Switch item)
  2. if that proxy item is ON, that means your Office is in manual mode.
  3. you have to Change the rule(s - at leas the ON rule) to check, if manual mode is active.

so, create a new item

Switch Office_Manual_Mode "Office Manual Lights" { expire="8h,command=OFF" } // the expire-part is optional

note: If you want the rule to be deactivated until the light is turned OFF again, just remove the expire-part and make sure, with a click of the physical button also Manual mode will turn OFF

you could now

  • add that item to your sitemap and trigger it
  • add some rule, which sets that item to ON, if some hardware button is pressed

That’s basically up to you and your use cases of that room, on how that Proxy Switch gets de-/activated.

within your existing rule, just add a If-clause like this:

rule "Office Motion On"
when 
	Item Sensor_Office_Motion changed to ON
then
	If (Office_Manual_Mode.state != ON) {
		Dimmer_Office.sendCommand(99)
		logInfo("Office motion", "Rule Light ON")
	}
end

two things on the rule:

  • never forget the .state, if you like to have the state of an item within a rule :wink:
  • notice, I asked if the state was not ON; now remember some posts above, if OH2 just started the state of an item is UNDEF until it is changed (via buttons, rules, persistence, …), that’s why I asked if the state isn’t ON - in every other case the rule will turn your light on an log that info.

from what I see, you only send commands to the z-wave item Dimmer_Office:

  • in the rule while motion ON
  • in the item with expire
  • in your UI (if Dimmer_Office is in there)
  • in some z-wave button, which triggers your light directly via the z-wave gateway (I hope that’s correct…?)

Correct on all three points.

So currently, if I’m dancing about in that room, every 20 seconds a command gets sent to my z-wave gateway.

Yes I have a Fibaro Dimmer 2 in my light switch

I’m not sure, how the z-wave binding handles this, but your Dimmer_Office item is ON the whole time. It receives command everytime your Sensor_Office_Motion changes to ON. If the z-wave binding sends the same command over to the gateway everytime regardless the actual state, you could either live with it (it doesn’t hurt, does it?) or you can add this one to your IF-clause:

	If (Office_Manual_Mode.state != ON) {
		If (Dimmer_Office.state != 99) {
			Dimmer_Office.sendCommand(99)
			logInfo("Office motion", "Rule Light ON")
		}
	}

// you could also combine both:
	If (Office_Manual_Mode.state != ON  && Dimmer_Office.state != 99) {
		Dimmer_Office.sendCommand(99)
		logInfo("Office motion", "Rule Light ON")
	}


It does not hurt generally but I try and keep z-wave communication to a minimum as I have had problems with actions being delayed due to too much traffic. So if I can avoid useless commands then that would be ideal.

I think I’ve interpreted your rule correctly but it is not doing what I expect.

Should the Dimmer_Office.state not be 0? So if my UI switch is on and my lights are off then set dimmer to 99. Else don’t do anything.

I’ve interpreted what you have sent as:

.rule

rule "Office Motion On"
when 
	Item Sensor_Office_Motion changed to ON
then
	if (Switch_Rule_Office_Motion.state != ON  && Dimmer_Office.state != 0) 
	{
		Dimmer_Office.sendCommand(99)
		logInfo("Office motion", "IF: Rule ON & Dimmer OFF")
	}
	else 
	{
		logInfo("Office motion", "ELSE:")
	}
end

.items

Switch Sensor_Office_Motion   		"Office Motion"		{ channel="zway:zwayDevice:192_168_0_222:24:sensorMotion-ZWayVDev_zway_24-0-48-1"}
Switch Switch_Rule_Office_Motion
Dimmer Dimmer_Office 		        "Office Main "		{ channel="zway:zwayDevice:192_168_0_222:2:switchMultilevel-ZWayVDev_zway_2-1-38",expire="1m,command=OFF" }

But even though my switch is on and my dimmer is off the rule still logs ELSE

openhab> smarthome:status Switch_Rule_Office_Motion
ON
openhab> smarthome:status Dimmer_Office
0

12:05:31.360 [INFO ] [marthome.event.ItemStateChangedEvent] - Sensor_Office_Motion changed from ON to OFF
12:05:37.222 [INFO ] [marthome.event.ItemStateChangedEvent] - Sensor_Office_Motion changed from OFF to ON
12:05:37.243 [INFO ] [smarthome.model.script.Office motion] - ELSE:

If I do the above “correctly” won’t that mean that the Expire won’t refresh each time motion is detected as we are stopping the command from being run in OH too? Meaning I cannot avoid sending a command to my gateway…

Apologies if I don’t quite get it.

no problem, we’ll work through this!

at first you’re absolutely right and I forgot: If you won’t update your Dimmer_Office it will just expire.
So I guess, you have to live with the Z-Wave binding updating the gateway with the same state (or work out a solution within the binding - as said, I know nothing about Z-Wave… :wink: )

you could only work out a much more complex logic, which won’t update the Dimmer_Office item directly, but again with some proxy item - and the proxy item will update the Dimmer_Office item accordingly. So if it changes (and only then) it will update Dimmer_Office with its own state.

So:

Dimmer Dimmer_Office_Proxy	        "Office Main Proxy"	{ expire="1m,command=OFF" }
Dimmer Dimmer_Office 		        "Office Main "		{ channel="zway:zwayDevice:192_168_0_222:2:switchMultilevel-ZWayVDev_zway_2-1-38" }

now: replace Dimmer_Office with Dimmer_Office_Proxy in your existing rules.
then add this rule:

rule "Office Motion Proxy"
when 
	Item Dimmer_Office_Proxy changed
then
	Dimmer_Office.sendCommand(Dimmer_Office_Proxy.state)
end

But again: this will complex your whole installation, I would recommend sticking with the initial configuration and live with updating Z-Wave…

I agree. Let’s ignore the gateway spam issue.

So I just need to be able to turn the rule on/off so I can use the light switch in a traditional way without a sensor and not switching off automatically after x min.

I must have not understood you correctly as my rule does not seem to work. Here is what I did

.items

Switch Switch_Rule_Office_Motion
Dimmer Dimmer_Office 		        "Office Main "		{ channel="zway:zwayDevice:192_168_0_222:2:switchMultilevel-ZWayVDev_zway_2-1-38"}
Dimmer Dimmer_Office_Proxy	        "Office Main Proxy"	{ expire="1m,command=OFF" }

.rules

rule "Office Motion On"
when 
	Item Sensor_Office_Motion changed to ON
then
	if (Switch_Rule_Office_Motion.state != ON  && Dimmer_Office_Proxy.state != 0) 
	{
		Dimmer_Office_Proxy.sendCommand(99)
		logInfo("Office motion", "IF: Rule ON & Dimmer ON")
	}
	else 
	{
		logInfo("Office motion", "ELSE:")
	}
end

rule "Office Motion Proxy"
when 
	Item Dimmer_Office_Proxy changed
then
	Dimmer_Office.sendCommand(Dimmer_Office_Proxy.state)
end

I’m sorry, the whole Proxy-Thing was just about the more complex situation… let’s forget this for a minute.

Because I think, we’re meeting the crucial point in our discussion. I was under the impression, the Dimmer_Office was already the physical light! I think, you meant with it the physical switch the whole time?

Let’s step back again:

  • Sensor_Office_Motion: digital twin of a physical PIR Sensor (we agree on that)
    sends permanently ON (and OFF) as long there’s movement
  • Dimmer_Ofice: digital twin of a physical ZWave switch (Is it so? the Z-Wave config points to the switch?)
    controls the light directly via ZWave gateway
  • Light_Office: digital twin of the physical light (could be a new item bound directly to your light?)
    I hope, this one works in ZWave, and you can directly Control the light
  • Office_Manual_Mode: proxy item only in openHAB
    allows (if OFF) or disallows (if ON) the use of the rule

That’s all you need, if you’re fine with sending multiple ONs to your Z-Wave Gateway. As stated before, I know nothing about ZWave and I hope, you can address the light directly via Z-Wave Gateway and you don’t need the switch for it?
Please make sure, this is as I hope it is - otherwise we need to reconsider how we can implement your requirement to have a manual override…

Ok, I just read me in on the Z-Wave basics. now I understand your confusion…
Your switch is the actuator already. Meaning you connect your 230V installation through it. So, the only thing you can control your office light with is that exact switch.

With this in mind, openHAB can’t decide if a switch was triggered from a manual action (e.g. pressing the physical dimmer) or a automatic one (e.g. letting openHAB switch it on for you). It’s simply a state in openHAB. So unfortunately to meet your goal of a manual mode we need - a proxy item! YEAH! (and now I know exactly why you used it already…)

so, now this:

Switch Office_Manual_Mode
Dimmer Dimmer_Office_Proxy	        "Office Main Proxy"	{ expire="1m,command=OFF" }
Dimmer Dimmer_Office 		        "Office Main "		{ channel="zway:zwayDevice:192_168_0_222:2:switchMultilevel-ZWayVDev_zway_2-1-38"}

again:

  • Office_Manual_Mode: prevents automatic state changes (you can trigger it from UI or it will be triggered by pressing the Z-Wave switch)
  • Dimmer_Office_Proxy: we can automate this one - and it will update the “real” switch
  • Dimmer_Office: your physical switch

at first - pressing the dimmer will result in a) turning on the light (no openHAB needed) b) activating Manual Mode, if turning the light OFF the reverse will happen:
hint: I’m not sure, what the state of the Dimmer in Z-Wave will be. I assume, it should be numeric 0 - 100? If not, please adjust the rule accordingly.

rule "Manual Dimmer Action"
when
	Item Dimmer_Office changed
then
	if (Dimmer_Office > 0) {
		// physical button pressed and it changed to ON
		Office_Manual_Mode.sendCommand(ON) // turn on manual mode only 
	}
	if (Dimmer_Office == 0) {
		// physical button pressed and it changed to OFF
		Office_Manual_Mode.sendCommand(OFF) // turn on automatic mode
	}

next one, if there’s motion - trigger the proxy item

rule "Office Motion"
when 
	Item Sensor_Office_Motion changed
then
	// we agreed to send the commands everytime, evenif the state is the same
	if (Sensor_Office_Motion == ON) {
		Dimmer_Office_Proxy.sendCommand(99) // help me out: could be 100 also?
		logInfo("Office motion", "ON")
	}
	if (Sensor_Office_Motion != ON) {  // remember there are other states like UNDEF
		Dimmer_Office_Proxy.sendCommand(0)
		logInfo("Office motion", "NOT ON")
	}
end

so now, we do the magic

rule "Office Light"
when 
	Item Dimmer_Office_Proxy changed
then
	if (Office_Manual_Mode != ON) {
		Dimmer_Office.sendCommand(Dimmer_Office_Proxy)
	}

so now you should

  • turn on the light via physical button and it stays on (until the physical button is set to 0 again)
  • turn on the light via motion and turning it off again after 1m

Yes

Exactly. Physical switching and digital in OH both update the gateway in the same manor.

The physical light itself is just a dumb bulb… the only way i control it is using a z-wave dimmer module inside the physical switch.

I’m a bit lost to be honest does my reply help you any?

1 Like

I’m sure you are. In my world (KNX & Co.) you have a switch and it’s only a switch :smile: and then you have an actuator, that then turns on the light - so you have two discrete devices.

but you can forget about it - and please read my above parallel answer, I hope I could explain good enough what I meant there…

1 Like

:+1: Going through your response now and testing. I think we are on the same page now, so I’m confident we will get it to work, bear with me.