Timers give me errors and a headache

Hi
I am using Openhab 2.3 on openhabian and was trying to write a script but it falls over with this error:
indent preformatted text by 4 spaces

2018-10-07 20:04:45.987 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2018-10-07T20:04:45.965+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@3730db

  <XFeatureCallImplCustom>.sendCommand(<XFeatureCallImplCustom>)

} ] threw an unhandled Exception: 

java.lang.NullPointerException: cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.reschedule(org.joda.time.base.AbstractInstant) on null

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

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

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) [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._doEvaluate(XbaseInterpreter.java:459) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:243) [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.$Proxy153.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]

2018-10-07 20:04:45.994 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2018-10-07T20:04:45.965+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@3730db

  <XFeatureCallImplCustom>.sendCommand(<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: cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.reschedule(org.joda.time.base.AbstractInstant) on null

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

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

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

	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._doEvaluate(XbaseInterpreter.java:459) ~[?:?]

	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.$Proxy153.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


and the script at the moment is just to test timers

rule "Travel Through Light Spectrum"
when
 Item TestSwitch changed to ON
then
			var Timer BlueLightTimer = null
			var int percent = 0
			var int B1_cnt = 20
			BlueLightTimer = createTimer(now.plusSeconds(5))[|
				if (B1_cnt < 60) {
					B1_cnt = B1_cnt + 4
					logInfo("Timer","Rescheduling")
					BlueLightTimer.reschedule(now.plusSeconds(5))
					}				
			TestSwitch.sendCommand(OFF)
			]	
			BlueLightTimer = null


end

I am really new to the forum and openhab.
Thanks for all the help.
Bart

Ok,

  • You need to declare the variable BlueLightTimer as a timer in the header of the rule file
  • Also as timers are Lambda they can’t access local variables and you need to create percent and B1_cnt as globals in the header of the rule file again
  • I used the notation createTimer( , Lambda) instead of createTimer() Lamdba, I think it’s clearer
  • I fixed your indents (Don’t mix spaces and tabs)
var Timer BlueLightTimer = null
var int percent = 0
var int B1_cnt = 20

rule "Travel Through Light Spectrum"
when
    Item TestSwitch changed to ON
then
    var Timer BlueLightTimer = null
    if (BlueLightTimer === null) {
        BlueLightTimer = createTimer(now.plusSeconds(5), [ |
            if (B1_cnt < 60) {
                B1_cnt = B1_cnt + 4
                logInfo("Timer","Rescheduling")
                BlueLightTimer.reschedule(now.plusSeconds(5))
            }				
            TestSwitch.sendCommand(OFF)
            BlueLightTimer = null //Cancels timer
        ])
    }
end

Actually this is one of those cases where the difference between global lambdas, collections lambdas (e.g. forEach) and Timer’s lambdas are different. I tend to gloss over this because it hasn’t been a problem. But I should talk about it here.

When you create the lambda for the Timer, it actually does get a copy of all the vars and vals in the context where it was created. So In OP’s original, percent, B1_cnt, and BlueLightTimer should all be available inside the lambda.

The key point though is that it gets a copy. So when the lambda that gets passed to createTimer is created, BlueLightTimer is null, so the copy of BlueLightTimer inside the lambda is also null.

I think it works with a global var for BlueLightTimer though, as your example shows, because global vars and vals are passed by reference into the lambda instead of by value. This is programmer speak for “global vars/vals get a pointer to the var/val but local Rule var/val get copied into the lambda.” Because the lambda get a reference to the global var BlueLightTimer instead of a copy, we can access the Timer inside the lambda even though BlueLightTimer was null at the time the lambda was created.

Having said all that, the problem isn’t that you can’t access Rule local var/vals in a Timer lambda because you can. The problem is the lambda only gets a copy of the variable meaning any changes made after the lambda is created do not exist inside the lambda.

Thanks a lot I have tried your code vzorglub but it only reschedules one time and then throws this at me:

2018-10-08 19:12:42.047 [INFO ] [eclipse.smarthome.model.script.Timer] - Rescheduling

2018-10-08 19:12:42.055 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2018-10-08T19:12:37.024+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@18b299a

  <XFeatureCallImplCustom>.sendCommand(<XFeatureCallImplCustom>)

  <null>.BlueLightTimer = <XNullLiteralImplCustom>

} ] threw an unhandled Exception: 

java.lang.NullPointerException: cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.reschedule(org.joda.time.base.AbstractInstant) on null

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

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

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) [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._doEvaluate(XbaseInterpreter.java:459) [156:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:243) [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.$Proxy153.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]

2018-10-08 19:12:42.063 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2018-10-08T19:12:37.024+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@18b299a

  <XFeatureCallImplCustom>.sendCommand(<XFeatureCallImplCustom>)

  <null>.BlueLightTimer = <XNullLiteralImplCustom>

} ] 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: cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.reschedule(org.joda.time.base.AbstractInstant) on null

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

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

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

	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._doEvaluate(XbaseInterpreter.java:459) ~[?:?]

	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.$Proxy153.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

Thanks for explanation.

So technically if I create a variable at the beginning of the rule file it should be global. Then the hypothesis is whenever I create a timer a reference to the variable is passed into the timer function and I operate on the real variable not its copy hence if want to have a loop counter in a sense I should create a global variable. But if I were to live with the copies does rescheduling wipe them each time I reschedule?
I would have thought that if I go into the timer with B1_cnt at 20 If it’s not wiped I still should be able to reschedule 10 times then break out of the timer but at the end of it B1_cnt would still read 20 as I was actually looping on a copy right?

No, rescheduling doesn’t wipe out the copies in the lambda. A lambda is just an Object. When you reschedule the lambda, you are reusing the same lambda Object so all the copies of the val/vars will still be there. More importantly, all the changes you’ve made to those copies of the var/vals will still be there as well. So you should be able to have a counter that goes up by one each time you reschedule the Timer, so long as you define it before you create the Timer.

var Timer timer = null

rule "Test string"
when
  Item Test changed
then
  logInfo("Test", "Test changed to \""+Test.state.toString+"\"")

  var count = 0
  timer = createTimer(now, [ |
      logInfo("test", "Looping timer with " + count)
      if(count < 10) {
        count = count + 1
        timer.reschedule(now.plusMillis(500))
      }
      else {
        timer = null
      }
  ])
end

Produces

2018-10-08 12:34:35.050 [INFO ] [.eclipse.smarthome.model.script.Test] - Test changed to "foo"
2018-10-08 12:34:35.054 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 0
2018-10-08 12:34:35.556 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 1
2018-10-08 12:34:36.057 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 2
2018-10-08 12:34:36.558 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 3
2018-10-08 12:34:37.061 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 4
2018-10-08 12:34:37.561 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 5
2018-10-08 12:34:38.063 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 6
2018-10-08 12:34:38.564 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 7
2018-10-08 12:34:39.066 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 8
2018-10-08 12:34:39.569 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 9
2018-10-08 12:34:40.072 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 10
2018-10-08 12:34:40.748 [INFO ] [.eclipse.smarthome.model.script.Test] - Test changed to ""
2018-10-08 12:34:40.751 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 0
2018-10-08 12:34:41.253 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 1
2018-10-08 12:34:41.756 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 2
2018-10-08 12:34:42.257 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 3
2018-10-08 12:34:42.759 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 4
2018-10-08 12:34:43.265 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 5
2018-10-08 12:34:43.766 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 6
2018-10-08 12:34:44.268 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 7
2018-10-08 12:34:44.770 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 8
2018-10-08 12:34:45.273 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 9
2018-10-08 12:34:45.774 [INFO ] [.eclipse.smarthome.model.script.test] - Looping timer with 10

But if for some reason in the above code if my Rule ran for a long time and I tried to use count again later on in the Rule while the looping timer was running then count would remain 0.

Thanks a lot for this explanation.
I have found the problem now.
I’ve used Vincent’s code and it gave me error
but using

else
{
	TestSwitch.sendCommand(OFF)
	BlueLightTimer = null //Cancels timer
}

sorted it out. I guess I have wrongly assumed that rescheduling the timer before will skip these two lines and they do not have to sit in an else statement but setting timer to null after rescheduling it was messing something up.

1 Like

Yes of course, my apologies