Help with a loop (Runs too fast / Ignores timers)

I’ve got DPs for everything. :smiley:

I think I was the one who originally came up with that idea. I’ve often wondered if I should write it up as a DP. Maybe I should.

Anyway, to implement what you are trying to do correctly I think you would do something like (note I’ll assume [Deprecated] Design Pattern: Time Of Day) the following. It think the behavior you are after is every hour to send a command to some lights, wait for a time, then send the command off, then wake up in some number of minutes and do it again:

val Timer awayFromHomeTimer = null
val Timer offTimer = null

rule "Away from home lighting"
when
    Item Away_from_home changed
then
    // cancel the timer if someone comes home
    if(Away_from_home.state == OFF && awayFromHomeTimer !== null) {
        awayFromHomeTimer.cancel
        awayFromHomeTimer = null
        offTimer.cancel
        offTimer = null
        return;
    }

    // Ignore the command if there is already a Timer (this should never happen)
    else if(awayFromHomeTimer !== null) return;

    awayFromHomeTimer = createTimer(now.plusSeconds(60), [  
        var lightsState = if(TimeOfDay.state == "DAY") 100 else 30 // I'm assuming Ghouselights is a Number Item
        var lights = if(TimeOfDay.state == "DAY") Ghouselights else GusLights
        var offTime = if(TimeOfDay.state == "DAY") 15 else 1
        var reschedule = if(TimeOfDay.state == "DAY") 25 else 132

        if(Away_from_home == ON) {
            lights.sendCommand(lightsState)
            offTimer = createTimer(now.plusMinutes(offTime), [ |
                lights.sendCommand(0)
                offTimer = null
            ]
            awayFromHomeTimer.reschedule(now.plusMinutes(reschedule))
        }
        else awayFromHomeTimer = null
    ]
end

I have to say, this is not pretty code but I think it does what you originally intended using Timers. I’d highly recommend using one of the other approaches discussed on the thread rossko57 linked to.

1 Like