[SOLVED] Check condition during X seconds (not after X seconds only)

My rule checked .state after 60 seconds using Timer. But I would need to know if the .state has been kept unchanged during that interval of 60 seconds also (if not, I need to “return”). How to do that without persistance?

rule "OVER"
when Item HabpanelBattery changed from "OVER"
then
if  (HabpanelBattery.state == "NORMAL") {
        timer = createTimer(now.plusSeconds(60)) [|
            if (HabpanelBattery.state == "NORMAL"){
            //do stuff
            }
        ]   
}
end

Just check to see if a Timer exists and it it does exist cancel it.

then
    if(timer !== null) timer.cancel

    else {
        if(HabpanelBattery.state == "NORMAL") {
            timer = createTimer(now.plusSeconds(60)) [|
                // do stuff, you don't need the if because if it changed then the timer would have been cancelled
                timer = null
            ])   
        }
    }
end

create anothe rule with the trigger changed from "NORMAL" and cancel the timer:

var Timer myTimer = null
rule "OVER"
when
    Item HabpanelBattery changed from "OVER"
then
    if (myTimer === null) {
        if  (HabpanelBattery.state == "NORMAL") {
            myTimer = createTimer(now.plusSeconds(60), [ |
                if (HabpanelBattery.state == "NORMAL"){
                //do stuff
                }
            ])   
        }
    }
end

rule "BACK FROM NORMAL"
when
    Item HabpanelBattery changed from "NORMAL"
then
    myTimer.cancel
    myTimer = null
end
1 Like

I follow Vincent’s ideea of adding a new rule for reset the timers, so I’ve added for each change of the HabpanelBattery item. This new rule gave me more flexibility since HabpanelBattery has few more states in my situation and it is also helping me to simplify my code (eliminated double-check of the status after the Timer has been running out).

So, my actual code:


rule "reset timers for each change"
when Item HabpanelBattery changed
then
    myTimer1.cancel
    myTimer1 = null
end

rule "OVER"
when Item HabpanelBattery changed from "OVER"
then
if  (HabpanelBattery.state == "NORMAL") {
        myTimer1 = createTimer(now.plusSeconds(60)) [|
           //do stuff here
        ]   
}
end


Got this error after reboot OH:

[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'reset timers': cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.cancel() on null

Add a null check in the rule:

rule "reset timers for each change"
when Item HabpanelBattery changed
then
    if (myTimer1 !== null) {
        myTimer1.cancel
        myTimer1 = null
    }
end

1 Like

So simple, Vincent… thanks! :slight_smile:

And yet, I should have thought about it when writing the rule…

Uhhh… still having that error:

rule "reset timers"
when Item HabpanelBattery changed
then
    if (myTimer1 !== null){
        myTimer1.cancel
        myTimer2.cancel
        myTimer1 = null
        myTimer2 = null
    }
end
[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'reset timers': cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.cancel() on null

Aha… it’s coming from myTimer2… I’ll correct right now.

It seems to be solved with this updated rule:


rule "reset timers"
when Item HabpanelBattery changed
then
    if (myTimer1 !== null){
        myTimer1.cancel
        myTimer1 = null
    }
    
    else if (myTimer2 !==null){
        mytimer2.cancel
        mytimer2 = null
    }
end

Error again:

[ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2019-02-03T20:10:29.903+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  <XFeatureCallImplCustom>.sendCommand(<XFeatureCallImplCustom>)

  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@82f94b

  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@1cbb99d

  <XFeatureCallImplCustom>.sendCommand(<XFeatureCallImplCustom>)

  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)

  <null>.myTimer2 = <XFeatureCallImplCustom>

  <null>.myTimer2 = <XFeatureCallImplCustom>

} ] threw an exception.

org.quartz.SchedulerException: Job threw an unhandled exception.

	at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]

	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]

Caused by: java.lang.NullPointerException

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.getDefaultObjectValue(XbaseInterpreter.java:779) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:462) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:243) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]

	at com.sun.proxy.$Proxy171.apply(Unknown Source) ~[?:?]

	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) ~[?:?]

	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]

	... 1 more
rule "reset timers"
when Item HabpanelBattery changed
then
    if (myTimer1 !== null){
        myTimer1.cancel
        myTimer1 = null
    }
    
    if (myTimer2 !== null) {
        mytimer2.cancel
        mytimer2 = null
    }
end

I’ve corrected ELSE IF with IF as you suggest. But error again.

rule "reset timers"
when Item HabpanelBattery changed
then
    if (myTimer1 !== null){
        myTimer1.cancel
        myTimer1 = null
    }
    
    if (myTimer2 !==null){
        mytimer2.cancel
        mytimer2 = null
    }
end

[ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2019-02-03T20:29:20.561+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  <XFeatureCallImplCustom>.sendCommand(<XFeatureCallImplCustom>)

  <null>.myTimer2 = <XFeatureCallImplCustom>

} ] threw an unhandled Exception: 

java.lang.NullPointerException: null

	at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:66) [137:org.eclipse.smarthome.model.script:0.10.0.oh230]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:132) [137:org.eclipse.smarthome.model.script:0.10.0.oh230]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) [137:org.eclipse.smarthome.model.script:0.10.0.oh230]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1115) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1045) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:143) [137:org.eclipse.smarthome.model.script:0.10.0.oh230]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:763) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:219) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) [137:org.eclipse.smarthome.model.script:0.10.0.oh230]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) [137:org.eclipse.smarthome.model.script:0.10.0.oh230]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at com.sun.proxy.$Proxy171.apply(Unknown Source) [?:?]

	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) [137:org.eclipse.smarthome.model.script:0.10.0.oh230]

	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]

	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]

2019-02-03 20:29:20.585 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2019-02-03T20:29:20.561+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  <XFeatureCallImplCustom>.sendCommand(<XFeatureCallImplCustom>)

  <null>.myTimer2 = <XFeatureCallImplCustom>

} ] threw an exception.

org.quartz.SchedulerException: Job threw an unhandled exception.

	at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]

	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]

Caused by: java.lang.NullPointerException

	at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:66) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:132) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1115) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1045) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:143) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:763) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:219) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]

	at com.sun.proxy.$Proxy171.apply(Unknown Source) ~[?:?]

	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) ~[?:?]

	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]

	... 1 more


If you edit a rule file that has already spawned timers, the timers keep running. But when they expire and run their code block, it usually fails with some kind of null error because the context was destroyed when the rule file was reloaded.

1 Like