Looking for a beginner guide about timers

Hi there,

I would like to get familiar with using timers instead of thread::sleep. Could you please provide a link with a step by step guide how to set up and use timers in rules.

All I found is:
https://www.openhab.org/docs/configuration/actions.html#core-actions

and
https://community.openhab.org/t/why-have-my-rules-stopped-running-why-thread-sleep-is-a-bad-idea/47695

But there is no information concerning e.g. reschedule or cancel etc.

Thanks,
Selter

I don’t type as fast as others but I will give you an example rule using timers.

var Timer stopMotionTimer = null
val int timeoutMinutes = 60
rule "Detect Motion when Garage is Open"
when
    Item Esp_Easy_Motion changed from OFF to ON
then
    if(Proxy_Motion.state == ON && stopMotionTimer === null && ESP_Easy_Door.state == OFF){  // Door open = OFF
    Echo_Plus_TTS.sendCommand('Alert, there is movement in the garage!')
        stopMotionTimer = createTimer(now.plusSeconds(10)) [|
            stopMotionTimer = null
        ]
    }
end

rule "Auto ON Garage Motion Detection after One Hour when Garage is Open"
when
    Item Proxy_Motion changed from ON to OFF
then
    if(stopMotionTimer === null){
        Echo_Plus_TTS.sendCommand('The garage motion sensor will be suspended for one hour')
        stopMotionTimer = createTimer(now.plusMinutes(timeoutMinutes)) [|
        Proxy_Motion.sendCommand(ON)
        stopMotionTimer = null
        Echo_Plus_TTS.sendCommand('Garage motion sensor will be switched back on')
        ]
    }
end

In the first rule when the if statement is true, my alexa will say the message “alert blaa blaa”, then stopMotionTimer is created by, createTimer(now.plusSeconds(10)) and is no longer = to null
Now after 10 sec stopMotionTimer is set back to = null. If 10 sec later Item Esp_Easy_Motion is still changing from OFF to ON ( because there is still movement occuring ) I will hear the alexa message “Alert blaa” again because the if statement is once again true. True because stopMotionTimer is now = to null.

The second rule is similar except I defined the amount of time as a value integer with the name timeoutMinuets and set it for 60 minuets.
So after 60 minutes the everything after the [ | part of the rule will be executed.

Does this kinda help with timers and some way they can be used?

2 Likes

Thanks for the answer.

So in the second rule it would be possible to replace createTimer(now.plusMinutes(timeoutMinutes)) with createTimer(now.plusMinutes(60)) with the same result?

Yep, difference is I defined it globally (at the top of the rules) so I will be able to use that same value multiple times.

I was just showing some options but this will have the same result plus I wouldn’t have to define the val int timeoutMinues at the top.

I see that Rich is replying to your question as well. His reply will much more elaborate and through, he’s good and I recommend reading everything he post, twice. :grinning:

Just hope you found the visual above helpful.

There isn’t really that much to it.

Purpose: To schedule a bit of code (i.e. lambda) to execute at some point in the future.

How to create one: call createTimer(<time to run>, <lambda>). The <time to run> is usually created using now, as in now.plusMinutes(5) which will be five minutes from now. The lambda is a bit of code surrounded by [ | ] e.g. [ | logInfo("test", "Hello world") ].

The call to createTimer will return a Timer object. If you save that Timer object to a variable you can reference that Timer later to do things like cancel it or rechedule it.

The best way to learn what methods are available on any Object is to use VSCode. Type in the name of the Object followed by a . and wait for the code completion dialog to pop-up.

image

The only methods you really need to worry about in practice are reschedule which causes the Timer to go off at the new time passed to the reschedule method, cancel which causes the Timer to not go off, isRunning which returns true when the Timer is running and hasTerminated which returns true when the timer has triggered and exited.

In practice most of us initialize our Timers to null, and set the Timer variable back to null as the last line of the lambda. Then we just check to see if the timer variable is null to determine if it is running or not. You see this in @H102’s examples.

Lamda’s vs expire, is this just a preference or is one better that the other?

Another visual

My items file

Group:Switch:AND(OFF,ON) gPresent <present>
Switch Present "Phone is home" <present>
Switch Present_Timer { expire="20m, command=OFF" }
Switch MyDevice <network> (gPresent) { channel="network:pingdevice:SiPhone:online" }

Rules file with no lambda’s

rule "start gPresent on system start"
when
    System started
then
    Present.sendCommand(OFF) // assume no one is home
end

rule "gPresent updated, at least one change of state"
when
    Item gPresent received update
then
    // someone came home
    if(gPresent.state == ON && Present.state != ON) { 
        Present_Timer.postUpdate(OFF) // cancel the timer if necessary
        Present.sendCommand(ON)
    }

    // no one is home and timer is not yet ticking (otherwise endless loop)
    else if(gPresent.state == OFF && Present.state != OFF && Present_Timer.state != ON) {
        Present_Timer.sendCommand(ON) // start the timer
    }
end

rule "Present_Timer expired"
when
	Item Present_Timer received command OFF
then
	Present.sendCommand(OFF)
end

It depends. Expire timers usually require less code and simpler code usually. But the time is fixed. You can’t have a dynamic timeout. Expire timers are also really easy to reset on an OH restart (if you are using persistence). A lot of use cases can be accomplished without even the need for Rules.

Timers are more flexible as they allow one to dynamically calculate the time in the Timer or based the amount of time on some value.

It depends on what you need. There is pretty much never a case where one approach in OH is always better than an alternative.

Thanks Rich, I couldn’t remember having run across that Q&A before. Thought maybe it would give the OP another look at rules and times.

Side note: I’ve read you use motion sensors in your home automation and thought you might be interested in the RCWL-0516 ($10 for 5 Amazon). I’ve been testing one in the garage for 3 weeks and 0 false triggers. Best part is I have it connected to an Esp8266 12E NodeMCU Dev board, along with 2 door switches and a photocell, and its all powered off the Esp.

Info only : you will run across a quirk when developing with Timers. Don’t panic!
A running Timer will survive the reload of the .rules file that spawned it.
But when it expires, the little block of code that it executes will have lost the context of it’s parent rule file, that all got destroyed and recreated.
Not always - but usually - it’ll throw a java error in the log mentioning quartz.

Short version, if you edit and reload a rule file after having started timers of some minutes, don’t be alarmed if you get error logs some minutes later.
Can save some head scratching, it’s easy to forget if you are working on some unrelated rules.

@rossko57 check your e-mail please.

Interesting device. Does it only detect motion or does it detect presence? For example, if I am motionless in the room will it see me as still being there or do I need to move?

I actually don’t use too many motion sensors in my setup besides a single PIR I have deployed at my dad’s house. But I have two use cases where these could come in handy. The motion sensor swich (not smart switch) can’t see me when I’m working at the far end of the garage. I can turn that switch into a smart switch and add a couple of these to keep the light on while I’m working.

The other is I bet this would make a good trigger for a game camera. There are bear, mountain lions, and bobcats in my neighborhood. It’d be cool to catch some shots of them passing through the back yard. An IR RPi camera is pretty cheap.

Of course, I already have four PIRs sitting in a box waiting to be wired to something to give them a job. I should probably try using those first.

You will need to be moving for it to sense you, but it doesn’t take much when your only a few feet away. At 5ft just snapping your fingers will trigger motion.

They work only with objects that are made of/with water (bear yes, bobcat maybe). They will detect through sheet-rock and doors with glass panels as well. I find the outdoors is great for this type detection b/c trees blowing or birds flying by wont effect it. Also good as front porch detection, can be set up inside and read through the glass, just need to add some type of shielding to the back so people inside wont cause false triggers.

Here’s a description on the specs. https://ita.ovh/files/rcwl-0516.pdf

Has a 3.3v 100mA output but I haven’t tested that part yet. The power off the Esp that it’s running on is 4.5v and the min is 4v.

1 Like