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
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
[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
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.