Createtimer problem in rule

Hi everybody

I would like to create a rule based on time triggers for controlling lights outside some time ranges. For example, if one light changes from off to on, the light will be assigned a timer for 1 hour max and will go off after.
The problem is since I have a a fews lights, I will use a group that will find the state of each member and if is it at ON, a timer will be created with a 1 hour laps. So, how can I create dynamic VAR Timer when each of member group is on a state ON? Do I have to assign a one on one timer and have those created before?

Thanks for your help
Jose

You need a one-to-one mapping between your lights or a whole lot of really ugly logic. This is easy to do with a HashMap. You do not need to create them before. The following approach will work even when you add or remove Items from the group.

Here is how I would solve what I think you are trying to do. It is easier to show in code than explain:

var Map<SwitchItem, Timer> timers = createHashMap

rule "Light turned on"
when
    Item gLight received update // NOTE, rule will be triggered multiple times per update, the code handles this
then
    gLight.members.forEach[light |  // for each light

        // If the light is ON and there isn't already a timer, create one
        if(light.state == ON && timers.get(light) == null){
            timers.put(light, createTimer(now.plusHours(1), [|
                light.sendCommand(OFF)
                timers.put(light, null)
            ])
        }

        // If the light is OFF and there is a timer, cancel it
        else if(light.state == OFF && timers.get(light) != null) {
            timers.get(light).cancel
            timers.put(light, null)
        }
    ]
end

One limitation to this is it does not handle the case where you want to reset the timer even further into the future (e.g. a motion sensor based light). It will turn off in an hour no matter what. If you need this functionality it gets more tricky.

Hi

Thanks for your help.
I tested your rule but I have a strange problem.
It does work the first time that I gets updated but the second time, it
doesn’t.
I put some traces in the rule (logging) and the first time it logs activity
but not the second time.
Do you think that the timer ainst getting the null condition?

Thanks
Jose

One thing I have learned recently is that it is best not to use a SwitchItem or a GroupItem as the key in a Map. Also, it might be having a problem with timers not being final as we are trying to use it inside a forEach.

So change timers to a val Map<String, Timer> timers = createHashMap

Then everywhere you have timers.put( or timers.get( replace light with light.name.

Hi

in the val definition, is it createHashMap or newHashMap?
I think that I used Create and I had an error…

Thanks
Jose

You are right, it is newHashMap. It is createTimer for timers. I got them mixed up.

Hi
I’ve tried the final configuration and it does work
Thanks for your help!

José

Hi

Small newbie question.
Regarding the timers, is it possible to have the remaining time for a
specific light?

Thanks
jose

Not without implementing it yourself. Search for countdown on the forum and you souks see at least one thread discussing one approach.

Hi

Thanks for the hint.

José