Creating of a delay in rules

Hello everybody

  • openHAB version: 2
  • Issue of the topic: Is it possible create a delay in rules? No timer with command line but just a delay? Unfortunately, I couldn’t find anything.

Thanks for your help

A virtual switch and the expire v1 binding works well

2 Likes

Here is a quick rule example that checks the condition of a timer and cancels/resets. Hope it gives you some ideas to work with.

var Timer myTimer = null
rule "Motion OFF"
when
    Item Motion changed from OFF
then
    if (myTimer === null) {
        if  (Motion.state == ON) {
            myTimer = createTimer(now.plusSeconds(60), [ |
                if (Motion.state == ON){
                //do stuff
                }
            ])   
        }
    }
end

rule "BACK FROM ON"
when
    Item Motion changed from ON
then
    myTimer.cancel
    myTimer = null
end

If you only need something to turn off/on after a certain time then the expire binding @Bruce_Osborne mentioned is the easiest route. :wink:

I’ll just add that while this is possible (see the links everyone has provided) we strongly recommend against doing so. There are only a few rules execution threads, 5 by default. This means only five Rules can run at the same time. When you add artificial delays to Rules you increase the amount of time that a Rule consumes one of those threads, and it’s doing nothing with that thread too. If you have too many Rules that do this sort of thing you can see a slowdown or a complete stop in all your Rules executing.

Am I correct in thinking that the limited number of execution threads is the main reason to cancel timers, or are there other benefits?

I only have a two or three timers in my system that almost always want to run to completion, so I don’t have any cancellation set up.

No. If you don’t cancel them they will run. Sometimes circumstances changed and you don’t want it to run any more. In that case you cancel the timer. For example, if you look at Generic Presence Detection, it sets a Timer to wait before setting the main presence proxy Item to OFF after all the sensors go to OFF. If someone returns before the Timer goes off, we no longer want to set the presence proxy Item to OFF so we cancel the Timer.

The limited number of execution threads is why you should use Timers instead of Thread::sleep to wait for something to occur. Timers don’t consume an execution thread but Thread::sleep will stop a Rule from exiting so it will continue to consume a thread.

There is no practical difference in terms of consuming a Rule execution thread between using the Expire binding and using a Rule Timer.

1 Like

Thanks, that’s the nuance I was missing.

I can think of one rule where I might benefit from cancelling the timer (though it hasn’t been an issue as of yet).

Thanks a lot for all the comments and useful explanations. I think the problem is solved now.