[SOLVED] How do I resolve my timer rule error?

  • Platform information:
    • Hardware: Raspberry Pi
    • OS: Raspbian 9
    • openHAB version: 2.4

So I have been busy trying to work out my rule to utilize my Philips Hue Motion sensor to do what I would like. For the most part, it works. Here is my code so far:

var Timer motionTimer = null

rule "SKJ Motion Sensor ON" 
when 
    Item MotionSensorPresence received update ON
then
    if (AstroSunDown.state == ON && Mensen_Thuis.state == ON && Bureaulamp_Slaapkamer_Jasper.state == OFF && J_Slaapkamer_Plafondlamp.state == OFF) {
        Plafondlamp_Slaapkamer_Jasper_Brightness_Slider.sendCommand(Bri)
        }
    else if (AstroSunDown.state == ON && Mensen_Thuis.state == OFF && J_Slaapkamer_Plafondlamp.state == OFF) {
                Plafondlamp_Slaapkamer_Jasper_Brightness_Slider.sendCommand(75)
                    motionTimer = createTimer(now.plusSeconds(60), [ |
                        MotionSensorPresence.sendCommand(OFF)
                        motionTimer = null
                        J_Slaapkamer_Plafondlamp.sendCommand(OFF)
                        ])
    }
    else {
        motionTimer.reschedule(now.plusSeconds(60 ))
    }
end

So a quick run down how it works: When I am home (Mensen_Thuis = on), I don´t want the script to turn off my lights. When I am not home and someone has to get something from my room, I want the light to turn off after 60 seconds if there is no more movement, otherwise reschedule the timer.

So far so good, the script works. Unfortunately, when the states of above items are in such a way that the script imideatly reaches the last esle (Sun is up, I´m not home and/or one of my lights are on), my system gives an error.

Rule 'SKJ Motion Sensor ON': cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.reschedule(org.joda.time.base.AbstractInstant) on null

Now, I have searched for an answer, but I did not find one (or understood it right). Does anyone know what is going wrong in my script?

(P.S. I know my item names are not good, but that is something I still need to find time for in order to change :sweat_smile: )

Threads I read:

You could try wrapping your reschedule with an if statement that makes sure motionTimer is not null.

else {
    if (motionTimer !== null) {
        motionTimer.reschedule(now.plusSeconds(60 ))
    }
}
1 Like

Thy whole point is, you can’t simply reschedule a timer without knowing if it exists. :slight_smile:

I’m pretty sure the rule should be slightly different:

rule "motion sensor"
when
    Item MotionSensorPresence received update ON
then
    if(AstroSunDown.state == ON && Bureaulamp_Slaapkamer_Jasper.state == OFF && J_Slaapkamer_Plafondlamp.state == OFF) {
        Plafondlamp_Slaapkamer_Jasper_Brightness_Slider.sendCommand(if(Mensen_Thuis.state == ON) Bri else 75)
        if(motionTimer === null) {
            motionTimer = createTimer(now.plusSeconds(60), [ |
                if(Mensen_Thuis.state == ON) {
                    motionTimer.reschedule(now.plusSeconds(60))
                } else {
                    MotionSensorPresence.sendCommand(OFF)
                    J_Slaapkamer_Plafondlamp.sendCommand(OFF)
                    motionTimer = null
                }
            ])
        } else {
            motionTimer.reschedule(now.plusSeconds(60))
        }
    }
end

This way, the timer is always scheduled, but it will not switch off the light but be rescheduled if at home. If leaving home (Mensen_Thuis.state == OFF), the light will also be switched off automatically.

1 Like

Thank you very much, this works! I did not know it was possible to do an if statement inside a sendCommand, good to know :smile:

I have been using Tasker for Android since a while now, and as I understood, it is good practice to not have a rule (or profile as they call it there) always on/running. I guess this is not the case with OpenHAB seeing your solution of the rule never really ends, right?

Also thank you @mhilbush for your answer!

The rule runs and finishes within a few milliseconds.
The rule runs each time you get a motion event.
The rule may set up a timer - this is like an alarm clock, it’s just an appointment to run a block of code at a future time.
The rule may reschedule that timer.
Nothing is running all the time.