How to cancel/reset a createTimer in a generic rule

Hello,

I would like to set dynamic timers to specific switches while using a generic rule.

I implemented it by adding a gSwitcheTimers group for each switch that I want to run a timer and creating a Number item with the prefix of the switch Item and a “_Timer” suffix.

In sitemap I can set a different timer for each switch and in the rule I am using createTimer that once activated I turn off the switch.

The problem starts if someone turn off the switch and then turn it on while the timer is already running (the switch will be turn off based on the first activation of the timer and not the current one).

Is there a way to stop a running timer or reset it in the example below?

Items:
Group gTimers
Group:Switch:OR(ON, OFF) gSwitchTimers

Switch	Relay1_Output		"Fan"			    <fan_ceiling>	(gSwitchTimers)	{channel="...."}
Number  Relay1_Output_Timer	"Fan - Timer [%s]"	<fan_ceiling>	(gTimers)

Switch	Relay2_Output		"Wall"			    <light>		(gSwitchTimers)	{channel="...."}
Number  Relay2_Output_Timer	"Wall - Timer [%s]"	<light>		(gTimers)

Sitemap:
Setpoint item=Relay1_Output_Timer minValue=1 maxValue=60 step=1
Setpoint item=Relay2_Output_Timer minValue=1 maxValue=60 step=1

Rule:
rule "Timers"
    when
        Member of gSwitchTimers changed to ON
    then
        val device = triggeringItem
        var logger = 1
        val loggerName = "Timers"
        if(device !== null)
        {
            val timer=gTimers.members.findFirst[ t | t.name == device.name + "_Timer" ] as NumberItem
            if (timer.state >0)
            {
                switch(vTimeOfDay.state) 
                {
                    case "NIGHT",
                    case "BED": 
                    {
                        if (logger==1) logInfo(loggerName, "Starting " + timer.name + " timer for "+ (timer.state as Number).intValue + " mins")
                        createTimer(now.plusMinutes((timer.state as Number).intValue)) [ |
                            if(triggeringItem.state == ON)
                            {
                                if (logger==1) logInfo(loggerName, "Turning off "+ timer.name)
                                triggeringItem.sendCommand(OFF)
                            }
                        ]
                    }
                }
            }
            else
            {
                if (logger==1) logInfo(loggerName, "Timer is null")
            }
        }
end

You can’t cancel a timer unless you keep a reference to it between rule runs

Thanks, can I create an Item that holds a reference to the timer? How?

No.

In the examples given, the “handle” takes the form of a ‘global variable’.
If you have many to keep, say individual timers for several lights, you can use a global Map to hold a set of refeences keyed by Item names.