2 Expire timers affecting each other

I have two garage doors. I wanted to be notified if I inadvertently left a door open longer the x minutes. It looked like using the Expire binding would fit nicely into my plan. Following a tutorial, I put together this test code.

My items.

Number myGar1Counter "Garage1 Minutes counter [%s]" <clock> {expire="1m,command=-1", autoupdate="false"}
Switch myGar1testLamp "Garage1 example light [%s]" <light>
Switch MyGar1Door "Garage Door1" <button> 

Number myGar2Counter "Garage2 Minutes counter [%s]" <clock> {expire="1m,command=-1", autoupdate="false"}
Switch myGar2testLamp "Garage2 example light [%s]" <light>
Switch MyGar2Door "Garage Door2" <button> 

Site Map


		Text item=myGar1Counter 
		Switch item=myGar1testLamp
		Switch item=MyGar1Door
		
		Text item=myGar2Counter 
		Switch item=myGar2testLamp
		Switch item=MyGar2Door

Rules


// Rule to manage countdown
rule "Garage 1 Door"
when
	Item myGar1Counter received command
then
	var cmmd = (receivedCommand as Number).intValue // integers only
	var count = 0
	var String msg = "Garage 1 Door" + cmmd
    logInfo("motion", msg)
	if (myGar1Counter.state != NULL) {  // avoid 1st time run error
		count = (myGar1Counter.state as Number).intValue
	}
	if (cmmd == -1 && count > 0) {  // decrement counter, do not go below zero
		if (count == 1) {
			// do actions for counter expiry, as we about to zero it now
			myGar1testLamp.sendCommand(OFF)
		}
		myGar1Counter.postUpdate(count - 1)
	} /*else if (cmmd >= count || cmmd < -1) {  // new or refreshed target
		if (cmmd < -1) {  // force override
			cmmd = 0 - cmmd  // make it positive
		}
		myGar1Counter.postUpdate(cmmd)  // nb we still update even if equal value - resets expire binding
		// do startup/continue actions
		if (myGar1testLamp.state != ON) {
			myGar1testLamp.sendCommand(ON)
		}
	}*/ 
	else if (cmmd == 5) {  // new or refreshed target
		myGar1Counter.postUpdate(cmmd)  // nb we still update even if equal value - resets expire binding
		// do startup/continue actions
		if (myGar1testLamp.state != ON) {
			myGar1testLamp.sendCommand(ON)
		}
		
		}
	else if (cmmd == 0) {  // cancel countdown
		myGar1Counter.postUpdate(0)
		// do optional cancel actions
		myGar1testLamp.sendCommand(OFF)
	}
end

rule "Garage 2 Door"
when
	Item myGar2Counter received command
then
	var cmmd = (receivedCommand as Number).intValue // integers only
	var count = 0
		var String msg = "Garage 2 Door" + cmmd
    	logInfo("motion", msg)
	if (myGar2Counter.state != NULL) {  // avoid 1st time run error
		count = (myGar1Counter.state as Number).intValue
	}
	if (cmmd == -1 && count > 0) {  // decrement counter, do not go below zero
		if (count == 1) {
			// do actions for counter expiry, as we about to zero it now
			myGar2testLamp.sendCommand(OFF)
		}
		myGar2Counter.postUpdate(count - 1)
	} /*else if (cmmd >= count || cmmd < -1) {  // new or refreshed target
		if (cmmd < -1) {  // force override
			cmmd = 0 - cmmd  // make it positive
		}
		myGar1Counter.postUpdate(cmmd)  // nb we still update even if equal value - resets expire binding
		// do startup/continue actions
		if (myGar1testLamp.state != ON) {
			myGar1testLamp.sendCommand(ON)
		}
	}*/ 
	else if (cmmd == 3) {  // new or refreshed target
		myGar2Counter.postUpdate(cmmd)  // nb we still update even if equal value - resets expire binding
		// do startup/continue actions
		if (myGar2testLamp.state != ON) {
			myGar2testLamp.sendCommand(ON)
		}
		
		}
	else if (cmmd == 0) {  // cancel countdown
		myGar2Counter.postUpdate(0)
		// do optional cancel actions
		myGar2testLamp.sendCommand(OFF)
	}
end


rule "Garage1 opened"
when
	Item MyGar1Door changed from OFF to ON
then
	myGar1Counter.sendCommand(5)
end

rule "Garage1 Closed"
when
	Item MyGar1Door changed from ON to OFF
then
	myGar1Counter.sendCommand(0)
end

rule "Garage2 opened"
when
	Item MyGar2Door changed from OFF to ON
then
	myGar2Counter.sendCommand(3)
end

rule "Garage2 Closed"
when
	Item MyGar2Door changed from ON to OFF
then
	myGar2Counter.sendCommand(0)

end

So when I set MyGar2Door to ON, myGar2Counter is set to 3, three minutes. So far so good. When I set MyGar1Door to ON, myGar1Counter is set to 5, five minutes. When
myGar1Counter decrements to 4, myGar2Counter also goes to 4. I don’t know why myGar2Counter is now equal to myGar1Counter.

I have looked at this code over and over again, and don’t understand how the two counters are reacting to each other. I am at a loss as to why this is.

I am on openHab 2.5.1 with a Raspberry Pi apt install. Expire binding is 1.14.0

Thanks,
Chris

I believe your counters should be Switch not Number.

Thanks, but the counters are used to store the minutes remaining of the Expire values. In this case they are integers. Switches are binary for 1 or 0, I believe.

Thanks,
Chris

The answer lies here, look closely at 1’s and 2’s

rule "Garage 2 Door"
...
	if (myGar2Counter.state != NULL) {  // avoid 1st time run error
		count = (myGar1Counter.state as Number).intValue
	}

Did you see the Group based version in the counter demo? One rule to work both counters, this error would not arise :wink:

Comment; take care with all those similarly named rules, you must keep unique rule names (system wide)

Wow, thank you so much rossko57!!! That was the problem. I’ll take a look at the Group based version. Also good point on similar names in rules. I thought it would be easier, but also easy for my old eyes to miss the mistake.

BTW, when I looked for the grouped based example, I see it was your example that I used. Thank you for taking the time to post the examples. Your time and efforts are really appreciated.

Thanks,
Chris

1 Like

Please tick the solution, thanks