Design Pattern: Expire Binding Based Timers

Thanks. I added the Expire binding and it works perfect.

Hi all,

I’ve been using the expire binding and similar dummy items to the design pattern above as a timer for a while. I thought it was a hack to avoid timers and sleep rather than an actual way to do it so pretty pleased with it all.

I’ve one question on the expire binding now as I’m implementing a new rule for a light switch. I’ve a motion sensor that turns ON when it senses motion, which in turns turns on the light item itself and also a dummy item with a 30 second expire to then turn the light off again after 30 seconds.

My issue is that I want the expire time to reset if the motion sensor detects more movement, ie the person is still milling about in the area.

I know from the docs that if you update the state of the item to be the same state it already was then it resets the timer, (which is what I want), but in this case is there a difference between sendcommand(ON) and postupdate(ON)? Will one rest the timer and the other do nothing???

Either one will reset the timer. From the Expire binding’s perspective, assuming you have not configured the Item with autoupdate=false, it’s the same as the command will result in an update. If you have autoupdate=false, that will prevent the command from automatically updating the Item so the Expire binding would not see the update. What I don’t know is whether Expire would still see the command or not.

2 Likes

Thanks for document many design patterns it makes life much easier. I’ve a question: If upon system restart you send each timer a command. Would that mean if all timer Items were initially OFF, now you will got all alert triggered by doing a system restart? Assuming command OFF to those timers usually are defined as some notification.

I’m not sure of the question really, but it is probably answered by understanding expire’s simple rule.
From the docs -

The expiration time will be started or restarted every time an item receives an update or command other than the specified “expire” update/command.

So yes, the existing state of an Item affects what expire will do.

To elaborate on rossko57’s answer, the “resting” state of an Expire Timer, as written in the original post, is OFF. When you update or command the Timer Item to OFF it cancels the Timer. That Rule triggers at startup to restart those timers that were not OFF when OH went down. Restore on startup does not trigger the Expire binding to start a Timer even if it restored an Item to ON. This rule ensures that those Timers that were running before OH went down are restarted when it comes back up.

I still don’t think I understand it completely.

Say I’ve this Item and rule:

Switch S_GarageDoor_Open_Timer "Garage door open timer" (gDoorsTimers) {expire="30m, command=OFF"}

rule "Set Door timer when opened"
when
    Member of gDoorSensors changed
then
   ...
    // Set the timer if the door is open, cancel if it is closed
    if(state == OPEN) sendCommand(name+"_Timer", "ON")
    else postUpdate(name+"_Timer", "OFF")
    ...
end

rule "Timer expired for a door"
when
    Member of gDoorsTimers received command OFF
then
    ......
    // send notification
    Alert_Text.sendCommand(doorName + " has been left open for 30 minutes.")
   Echo_Family_PlayAlarmSound_Alert.sendCommand(ON)
end

Basically, An alert will be sent whenever Timer item received command ‘OFF’, versus receiving state ‘OFF’ will cancel the timer. If everything is fine and my door is OFF when system restarted. Your pattern will send ‘OFF’ command to the timer again. Would that generate another alert?

Yes, as you have it written it would trigger your rule. So in that case you would want to filter the group and only send the commands to those Timer Items that are ON. As with all the DPs, the intent is to customize it to work with your specific environment.

Thanks for the response. That makes total sense, and sendCommand(ON) to timers which was ON fits me.

I’m having issues using the expire binding with rollershutters. I would like to send a stop command to the rollershutter after 60 seconds.

As background but not really important, the reason is the physical module needs to receive a stop command when the screen is definitely open or closed otherwise the relais remains in open or closed state and next time a wall switch is pressed it needs to be pressed twice (first time to send a stop second time to set screen in motion).

I have the following item definition

Rollershutter NB_R1_01_living_achter_groot “Living A groot” { channel=“nikobus:rollershutter-module:mypclink:R1:output-1”, expire=“60s,command=STOP” }

The STOP command is sent, so that works great, the problem is the folowing, when a stop commend is received a rollershutter item receives a state 0. Since this does not match STOP the expire binding resets itself every time and the stop commend keeps being sent every 60 seconds over and over again.

Can someone share an example of how to use expire with rollershutters ?

Expire binding is not a cure-all. I’d say it is unsuitable for that usage.

If you must use it, you’d need to isolate the ‘expire’ from the unwanted state update triggers. Create a new dummy Item that does the expiring, have a rule that listens for non-STOP commands to the real Item, and passes them to the dummy. Have another rule that listens for dummy command at expire time, and passes that to real Item.

It seems simpler to make one rule with an independent timer.

first of all, I don’t know Nikobus rollershutters, but perhaps, there’s a native way to work around this? I can’t imagine any shutters, that need an explicit signal to close the relais…?
If there’s really no way to achieve the STOP-signal natively within nikobus, just have a look at the “Timer”-functionality. Have a rule on the behaviour of your Rollershutter items and let the Timer do the STOP-signal afterwards.

:slight_smile: indeed think I will have a go at the a rule for the item directly :slight_smile:

I managed to replace the expire with a rule, the only thing the rule with the timer does not do is the resetting of the timer when a new command is received.

rule "Stop screen after 90s"
when
    Member of gScreen received command DOWN or Member of gScreen received command UP
then
    var Timer myTimer = createTimer(now.plusSeconds(90), [ |
    logInfo("rules", "Timer activated")
    triggeringItem.sendCommand(STOP)
    ])
end

with this rule a stop command is sent after 90 seconds. But when I now press UP for a certain screen the timer starts (to send stop after 90s) but when I then press DOWN for the same screen 45 seconds later he first timer will still continue (as a new timer is created for the DOWN command) and will send a stop after 45 second (when the initial 90s is over) and the second timer will send another STOP 90s later.

I can live with this situation but I was wondering what would be the right way to tweak the rule such that it also does the reset of the initial timer rather than creating a new timer.

you could always use myTimer.cancel or myTimer?.cancel to avoid deleting a non-existent timer. This should cancel all timers with that name. but beware to not use “myTimer” in other rules, which can be triggered in parallel. or you can work some more complex logic around myTimer.reschedule, which doesn’t cancel the timer, but just reschedules it.

Thomas that’s a very interesting point. With the second command, or with any other screen being commanded the same rule is triggered and currently it looks like even though the rule is triggered multiple times in parallel with every time myTimer as timer name these timers act like separate instances that nicely run next to each other and don’t interfere.

But I have been wondering whether there is a way to use the value of triggeringItem as part of the timer name ? something like

var Timer myTimer+triggeringItem = createTimer(now…

this way if the rule was triggered by item screen1 the timer would be myTimerScreen1 and if it’s triggered by a different item receiving a command the timer name would be different (e.g. myTimerScreen3) or is that a completely stupid idea ?

Fellas, this is way off-topic for a tutorial about using Expire based timers. There are many tutorials and posts about regular timers. If you have a unique problem, you can always create your own new post for a unique solution.

Topics of interest to you -
Managing a timer using a handle in a global variable.
Managing an ‘array’ of similar timers for a group of Items.

Both of these are demonstrated in thesimple and complex examples here

Hi all, I’m trying to use expire binding on an amazonechocontrol smartHomeDevice.
I have untagged the item because I do not want the item to be imported to Alexa via OH Skill:
Switch LivingRoom_Light3 "Abajour" <light> (LivingRoom, gLight) ["Lighting", "Switchable"] {alexa="disable",channel="amazonechocontrol:smartHomeDevice:xxxxx:LivingRoom_Light3:powerState",expire="30s,command=OFF"}

The expire works fine only if I switch ON the light from OH Paper UI.
If I switch ON from Alexa this does not work.
Also I noticed that the OH switch is not updated when commended through Alexa.
I guess the issue comes from alexa=“disable” that I cannot remove (otherwise I have double device in Alexa).

Is there any workaround ?

One solution could be the use of a rule cron based with:
myItem.sendCommand("REFRESH") .
The problem is that with a Cron based every 10 seconds, the Expire get a counter reset at any time.

Yep, as you’ve guessed, these are connected. If openHAB does not get state updates for an Item, it cannot know to start the expire timer.

And REFRESH works as advertised - you call it, you get an Item update.

And if you get an Item update that is not the same as expire “target”, the expire timer will restart.

It’s all working as it supposed to.

Your real problem is that you do not get a state change update from Alexa. I don’t know how you address that. If you can’t address it, you can perform your “expire” functionality using rules and createTimers instead.

A short update on this issue for who is using Alexa Echo Control Binding.
The 2.5.10 version of Alexa Echo Control Binding was not properly working and was not passing the item updfate. This has been fixed in the last snapshot.
Nevertheless, the Echo Control Binding is refreshing items status every minute (more or less) and this seems to reset the expire timer.
The final result is that eny expire longer than 1-2 minutes is never fired.
As suggested by @rossko57 , for who is obliged to use Echo Control Binding the only solution seems to use rules and timers.