[SOLVED] Timer rule - but more elegant

Hi All,

I have a switch that i like to switch on with a timer. I created a massive rule, which works but is far from elegant. What i did is as soon as my timer receives a new input, it waits for 1 minutes and then inputs the value minus 1.

So i have my regular on/off switch an item with mappings for the timer and an item that shows how many minutes are left on the timer.

Items are as follows:

Switch	item=TestSwitch				label="Test Switch"		icon="ostairlights"
						Switch	item=TestSwitch_Timer 		label="Timer Select"	icon="timer" 	mappings=[0="5 min", 1="15 min", 2="30 min", 3="1 hr", 4="2 hrs"]
						Text	item=TestSwitch_TimerDur	label="Remaining timer [%.0f]"		icon="timer"

Now the rules i have created is as follows (the countdown rule i made for every minutes from 120 down to 0). So how can I simplify this rule to just one instead of 120 rules.

rule "Test Lights 30 min"
	Item TestSwitch_Timer received command "2"
	logInfo("info","Test light 30 min timer activated")

rule "Switch Timer to 0"
	Item TestSwitch_TimerDur received command "0"
	logInfo("info","Test light switches off")

rule "Timer from 30 to 29"
    Item TestSwitch_TimerDur received command "30"
    logInfo("info","30 min left on timer")
    createTimer(now.plusMinutes(1), [ | TestSwitch_TimerDur.sendCommand(29)] )
rule "Timer from 29 to 28"
    Item TestSwitch_TimerDur received command "29"
    logInfo("info","29 min left on timer")
    createTimer(now.plusMinutes(1), [ | TestSwitch_TimerDur.sendCommand(28)] )
rule "Timer from 28 to 27"
    Item TestSwitch_TimerDur received command "28"
    logInfo("info","28 min left on timer")
    createTimer(now.plusMinutes(1), [ | TestSwitch_TimerDur.sendCommand(27)] )

That’s really simple :wink:

Switch item=TestSwitch label="Test Switch" icon="ostairlights"
Switch item=TestSwitch_Timer label="timer [%.0f mins]" icon="timer" mappings=[0="OFF",5="5 min", 15="15 min", 30="30 min", 60="1 hr", 120="2 hrs"]
var Timer tTimer = null                                                      // pointer to timer

rule "Timer"
    Item TestSwitch_Timer received command
    if(receivedCommand instanceof Number) {                                   // just to be sure
        val Number mins = (receivedCommand as Number).intValue                // duration to set
        if(mins == 0) {                                                       // deactivate timer if set to 0
            if(tTimer !== null)                                               // if there is an active timer
                logInfo("timer","Timer deactivated!")
                tTimer.cancel                                                 // cancel
                tTimer = null                                                 // deinitialize
                TestSwitch.sendCommand(OFF)                                   // switch light off
        } else {                                                              // set timer
            logInfo("timer","Timer set to {} Minutes!",mins)
            TestSwitch.sendCommand(ON)                                        // switch light on
            tTimer?.cancel                                                    // cancel existing timer
            TestSwitch_Timer.postUpdate(mins)                                 // set display to duration
            tTimer = createTimer(now.plusMinutes(1), [                        // initialize timer
                val Number nDuration = (TestSwitch_Timer.state as Number) - 1 // get new duration
                TestSwitch_Timer.postUpdate(nDuration)                        // set display to duration
                if(nDuration > 0) {                                           // already reached end?
                    logInfo("timer","Timer end pending {} Minutes",nDuration)
                    tTimer.reschedule(now.plusMinutes(1))                     // repeat
                } else {
                    logInfo("timer","Timer ended.")
                    TestSwitch.sendCommand(OFF)                               // switch light off
                    tTimer = null                                             // deinitialize timer

Timer is created once and is repeated until reached end. Display is updated once a Minute (Display is the same Item as timer control).

You can deactivate the timer. You can simply add other duration by setting the Item state accordingly.



Awesome. Works perfectly. Just needed to change the , to . in the line


Ups, sorry, Typo…

For reference, I did the correction above :slight_smile:


Line 18: tTimer?.cancel // cancel existing timer

“?” is correct? or typo?


The use of ? here is a bit of magic. If timer is null the cancel will not be attempted, avoiding what would otherwise be an error.

1 Like

Yes, that’s correct.


is the same as

if(tMyTimer !== null) tMyTimer.cancel
1 Like


I have even more elegant requirement for rule, but struggling.
I have several Items, and want them work together.
Garage_gate (Open/close)
Garage_door (Open/close)
Light_switch (on/off)
Several move detection items with (open/close)
and I have also event for sunset/sunrise.

I wan something very elegant.
when I open garage door or garage gate, and it’s also after sunset event (possible with delta), then I turn on light. Later I want to keep light on for 2 minutes, for example. but when I receive move detection, I want this timer back reset to 2 minutes. and turn off when a timer get 0 or it’s sunrise (sunrise it’s optional, but preferred).

Maybe I can get help with this?


Take a look at Area Triggers and Actions. The example code fits most people’s lighting needs…

Hi, I was trying this example as is,same items, same sitemap, but I get a warning and it doesn’t work.
I’m doing a clean install of oh 2.5.10-1.
The warning is:2020-11-13 18:39:24.943 [WARN ] [rest.core.internal.item.ItemResource] - Received HTTP POST request at 'items/TestSwitch_Timer' with an invalid status value '5'.

what am I doing wrong?
thank you in advance

You probably created TestSwitch_Timer as a Switch type Item, which willnot like being sent numeric commands. Make it a Number type Item.

Perfect…thanks…that was the problem