Switch Item off- error

Hello,
I’ve tried to switch a item off after a defined time, but i’m getting following error:

2018-10-13 21:20:25.645 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2018-10-13T21:20:25.616+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  <XFeatureCallImplCustom>.sendCommand(<XFeatureCallImplCustom>)

  <null>.heater_Timer = <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.IllegalArgumentException: Couldn't invoke 'assignValueTo' for feature JvmVoid:  (eProxyURI: home.rules#|::0.2.8.2.0.0.7.6.1.1.0.1::0::/1)

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

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

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

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

The rules:

var     Timer   heater = null
val     Integer heater_TimeOut = 1
...

rule "Heater OFF"
when
Item prt1 changed from OFF to ON
then
heater = createTimer(now.plusMinutes(heater_TimeOut))
[|
prt1.sendCommand(OFF)
heater_Timer = null
]
end

Try this

var Timer  heater = null

rule "Heater OFF"
when
Item prt1 changed from OFF 
then
if(heater === null){
heater = createTimer(now.plusMinutes(10)) [ |         // minuets for timeout
prt1.sendCommand(OFF)
heater = null
]
}
end

Seems to work, thank you!

Please mark the thread as solved.
Check the square box in the post that provided the solution to your problem.
Thanks

I would suggest changing the name of the timer and using the syntax createTimer(time, [ lambda ])
instead of the createTimer(time) [ lambda ] it is clearer to read

Also watch your code indentation. It’s important to read the code. In 6 months time when you go over that rule for some reason, you want to be able to read what you did without unwrapping everything

var Timer heaterTimer = null

rule "Heater OFF"
when
    Item prt1 changed from OFF to ON
then
    if (heaterTimer === null) {
        heater = createTimer(now.plusMinutes(10), [ |         // minutes for timeout
            prt1.sendCommand(OFF)
            heaterTimer.cancel // Cancels the timer
            heaterTimer = null  // Resets the timer
        ])
    }
end

This is a very basic timer function that will always run when prt1 is changed to OFF

You can use the expire binding to achieve the same thing without any code.
Install the expire binding and your item:

Switch prt1 "label" { expire="10m, command=OFF" }

Done!

I know several have made the same suggestion but with so little happening I don’t see it making much difference. Also the , if left out results with issues. On the other hand if there are lots of things happening then I agree. Actually, I agree with all your rules and coding techniques, small code today, big code tomorrow with no changes needed.:+1:

Very true but its a good feeling, when new to OH, writing a rule and it works.:sunglasses:

1 Like

In fact there should be no difference, other than the readability of your code. :wink:

Inside a timer this method will do nothing at all, as the timer is already expired :slight_smile:

I didn’t pretend otherwise. I just wanted to show better coding practice.
Consistency and readability are just as important.