Timer and variable assignment

Hi,

I’m hoping someone can tell me what is wrong with this rule:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import java.util.Date

var Timer timer
var Number lockout = 0 

rule "Motion sensor notification"
when
    Item sensor_motion changed to ON
then
    var Date starttime = now.withTime(20, 30, 0, 0).toDate()
    var Date endtime = now.withTime(23, 30, 0, 0).toDate()

    if(lockout == 0 && now.toDate().after(starttime) && now.toDate().before(endtime)) {
        if(XBMC_State.state == "Play") {
            if(mode.state != 2) {
                notification_text.postUpdate("ALERT: Motion detected.") 
                lockout = 1
                timer = createTimer(now.plusMinutes(10)) [|
                    lockout = 0
                ]
            }
        }
    }
end

The rule executes fine, however I get an error when the timer closure fires:

2015-12-12 14:36:39.592 [ERROR] [org.quartz.core.ErrorLogger ] - Job (DEFAULT.2015-12-12T14:36:39.577+13:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedu$
e0: org.eclipse.xtext.xbase.impl.XClosureImplCustom@4612e809 (explicitSyntax: true) threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
at org.quartz.core.JobRunShell.run(JobRunShell.java:224) ~[quartz-all-2.1.7.jar:na]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-all-2.1.7.jar:na]
Caused by: org.eclipse.emf.common.util.WrappedException: org.eclipse.xtext.util.PolymorphicDispatcher$NoSuchMethodException: Couldn’t find method ''assignValue’’ for o
bjects [JvmVoid: (eProxyURI: motion-sense.rules#xtextLink
::0.2.0.2.0.2.1.0.0.1.0.0.1.0.2.8.7.1.1.0.0::0::/1), , 0, org.eclipse.xte
xt.xbase.interpreter.impl.DefaultEvaluationContext@41d73e4c, org.eclipse.xtext.util.CancelIndicator$1@1811e064]
at org.eclipse.xtext.util.Exceptions.throwUncheckedException(Exceptions.java:23) ~[na:na]
at org.eclipse.xtext.util.PolymorphicDispatcher$DefaultErrorHandler.handle(PolymorphicDispatcher.java:41) ~[na:na]
at org.eclipse.xtext.util.PolymorphicDispatcher.handleNoSuchMethod(PolymorphicDispatcher.java:304) ~[na:na]
at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:286) ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.assignValue(XbaseInterpreter.java:849) ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateAssignment(XbaseInterpreter.java:844) ~[na:na]
at sun.reflect.GeneratedMethodAccessor105.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:218) ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateBlockExpression(XbaseInterpreter.java:321) ~[na:na]
at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:218) ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:204) ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:28) ~[na:na]
at com.sun.proxy.$Proxy115.apply(Unknown Source) ~[na:na]
at org.openhab.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:44) ~[na:na]
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-all-2.1.7.jar:na]
… 1 common frames omitted
Caused by: org.eclipse.xtext.util.PolymorphicDispatcher$NoSuchMethodException: Couldn’t find method ''assignValue’’ for objects [JvmVoid: (eProxyURI: motion-sense.rul
es#xtextLink
::0.2.0.2.0.2.1.0.0.1.0.0.1.0.2.8.7.1.1.0.0::0::/1), , 0, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationCon
text@41d73e4c, org.eclipse.xtext.util.CancelIndicator$1@1811e064]
… 22 common frames omitted

…which seems to be related to the assignment of the lockout variable, but I can’t for the life of me work out why this is a problem.

Any help appreciated.

Thanks in advance.

I’ve had limited success reassigning vars from within a timerv like that. I think the problem is the lambda has a copy of the environment, not direct access to it.

Fit this sort of problem I use the existence of the the active timer as the lockout.

So instead of ‘if(lockout == 0 &&’ I would use ‘if((timer == null || timer.has terminated) &&’. This eliminates the need for lockout entirely.

Thanks Rich, that sounds like the approach to take.