Is it possible to delay triggering of an event?

I would use 3 separate rules or 2, with 1 for the Away event. Something like:


rule "Activate PIR"
when
    item Away changed to ON
then 
        awayTimer = createTimer(now.plusMinutes(10), [|
            awayTimer = null
            postUpdate(PIR_Enabled, ON)
    	])

end

rule "Back Home"
when
    item Away changed to ON
then
    awayTimer = null // cancel timer
    postUpdate(PIR_Enabled, OFF) // deactivate PIR
end
rule "Notify PIR"
when
    Item PIR_Outdoor_Front changed to OPEN  
then
    if(PIR_Enabled == ON) {
        sendTelegram((TelegramBots), (Message14))
        sendTelegramPhoto((TelegramBots), (IP_Cam_Driveway_URL), null, (IP_Cam_User), (IP_Cam_PW))    	
    }
end

Thanks @Udo_Hartmann and @digineut

You have given me something to work with in the morning.

As a totally noob in coding it is much appreciated and really helps out alot to see suggestions of how to solve things :relaxed:

I have been trying to delay items in some of my rules as well and found that because I could not get a timer to work, I had to find something easier. Basically, I was trying to get the hall light to turn on for 45 seconds when the PIR sensor trips. This would allow me enough time to get to the kitchen or back to the living room with the light on.
I found this command line in another post and changed it to suit my needs:

rule "Hallway Motion Light On" when Item Hall_Motion changed to OPEN then sendCommand(Hallway_Hue, 50) Thread::sleep(45000) //Turns on 1st floor hallway light for 45 seconds. sendCommand(Hallway_Hue, 0) end

When the motion is tripped, the hall light goes on for 45 seconds, then the rule will send the off command. This could work for you if you set a delay to your “Away mode”. So, when you want to put the house in away mode, you would add a Thread:: sleep(600000) in your rule before the house is actually put into away mode, this would give you 10 minutes to pull out of your garage. This would be similar to the 30 seconds you have to exit a house with an alarm when it is turned on.

Thread::sleep() is possible but awful :wink: The same result:

import org.joda.time.DateTime
var Timer tHallway = null

rule "Hallway Motion Light On"
when
    Item Hall_Motion changed to OPEN
then
    sendCommand(Hallway_Hue, 50)
    if (tHallway!=null)
        tHallway.cancel
    tHallway = createTimer(now.plusSeconds(45))[|
        sendCommand(Hallway_Hue, 0)
    ]
end

In contrast to your rule this one would only send 1 off-Command, i.e. the light is re-triggered if motion is detected within the 45 seconds. Your rule would switch off the light 1 time per trigger, so if a second trigger is detected, the first off command would fire up 45 seconds after the first trigger, and the second off command would fire 45 seconds after the second trigger.

EDIT: changed Code! (added missing bracket)

Udo_Hartmann,

Thank you for the code for a proper timer, I have been looking for an example of an easy way to do this, and this helps me understand it a lot better than some examples I have seen (they were a little complex for me to understand). I will definitely implement this, it seems to be a cleaner way of getting it done. I am not sure about the second trigger on my PIR, it’s an ecolink, which I think has a 3 or 5 minute reset before there can be a second trigger.

SoerenBM, sorry for hijacking your thread, I thought I was being helpful, sorry if I have confused you!

~John

Quite alright. We are all here to try to learn :slight_smile:

Now we are on the subject of timers, perhaps someone can educate me on what’s wrong with this rule. @rlkoshak has helped out a lot but, somehow I’m just not able to get this one to work right. Sometimes it works others it just don’t. Now I have split the rule op in two rules-file ‘Notify_GarageDoor1.rules’ and ‘Notify_GarageDoor2.rules’:

It’s these rules that are making me pull my hair out.

rule “Send telegram Notification | Garage door 1 open for 30 min.”
rule “Cancel telegram Notification | Garage door 1 open for 30 min.”

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.java.math.*
import org.joda.time.DateTime
import org.joda.time.*
import org.openhab.model.script.actions.Timer


// Timers
var Timer tGarageDoor1Snapshot = null
var Timer tGarageDoor1 = null

// TelegramBots
var String TelegramBots =			'Soeren'

// URLs and login information for IP-CAMs
var String IP_Cam_Garage_URL =		'http://192.168.10.51/Streaming/channels/1/picture'
var String IP_Cam_User =			'user'
var String IP_Cam_PW =				'password'

// Messages used in the following rules
var String Message1 =				'Garage | Port 1 blev ĂĽbnet! -OH1'
var String Message2 =				'Garage | Port 1 har stĂĽet ĂĽbent i 30 minutter! -OH1'


// This rule sends a telegram notification when garagedoor is opened, with a snapshot delayed 18 secs.
rule "Send telegram Notification | Garage door 1 opened"
when
    Item Garage_Port_1_State_Closed changed to CLOSED
then
    if(tGarageDoor1Snapshot == null || tGarageDoor1Snapshot.hasTerminated) {
    	tGarageDoor1Snapshot = createTimer(now.plusSeconds(18), [|
    		tGarageDoor1Snapshot = null
    	sendTelegramPhoto((TelegramBots), (IP_Cam_Garage_URL), null, (IP_Cam_User), (IP_Cam_PW))
    	]) 
    	sendTelegram((TelegramBots), (Message1))   	
	}
end


// This rule sends a telegram notification if garagedoor has been open for 30 min.
rule "Send telegram Notification | Garage door 1 open for 30 min."
when
	Item Garage_Port_1_State_Closed changed to CLOSED
then
	if(tGarageDoor1 == null || tGarageDoor1.hasTerminated) {
		tGarageDoor1 = createTimer(now.plusMinutes(30), [|
			tGarageDoor1 = null
		sendTelegram((TelegramBots), (Message2))
		])
	}
end

rule "Cancel telegram Notification | Garage door 1 open for 30 min."
when
	Item Garage_Port_1_State_Closed changed to OPEN
then
	if(tGarageDoor1 != null) tGarageDoor1.cancel() //Terminate timer if door is closed before the timer ends
end

Hope someone are able to pinpoint my errors.

I just tried my modified rules and this error shows in the console

2016-05-31 21:49:35.603 [ERROR] [org.quartz.core.JobRunShell   ] - Job DEFAULT.2016-05-31T21:49:35.579+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: org.eclipse.xtext.xbase.impl.XClosureImplCustom@35602d (explicitSyntax: true) threw an unhandled Exception: 
org.eclipse.emf.common.util.WrappedException: org.eclipse.xtext.util.PolymorphicDispatcher$NoSuchMethodException: Couldn't find method ''_assignValue'' for objects [JvmVoid:  (eProxyURI: Notify_GarageDoor1.rules#xtextLink_::0.2.1.2.0.0.1.0.0.8.7.1.1.0.0::0::/1), <null> <unkown> <XNullLiteralImpl>, null, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@71f899, org.eclipse.xtext.util.CancelIndicator$1@781eae]
	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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_75]
	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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_75]
	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.$Proxy78.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]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-all-2.1.7.jar:na]
Caused by: org.eclipse.xtext.util.PolymorphicDispatcher$NoSuchMethodException: Couldn't find method ''_assignValue'' for objects [JvmVoid:  (eProxyURI: Notify_GarageDoor1.rules#xtextLink_::0.2.1.2.0.0.1.0.0.8.7.1.1.0.0::0::/1), <null> <unkown> <XNullLiteralImpl>, null, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@71f899, org.eclipse.xtext.util.CancelIndicator$1@781eae]
	... 24 common frames omitted
2016-05-31 21:49:35.603 [ERROR] [org.quartz.core.ErrorLogger   ] - Job (DEFAULT.2016-05-31T21:49:35.579+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: org.eclipse.xtext.xbase.impl.XClosureImplCustom@35602d (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 objects [JvmVoid:  (eProxyURI: Notify_GarageDoor1.rules#xtextLink_::0.2.1.2.0.0.1.0.0.8.7.1.1.0.0::0::/1), <null> <unkown> <XNullLiteralImpl>, null, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@71f899, org.eclipse.xtext.util.CancelIndicator$1@781eae]
	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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_75]
	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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_75]
	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.$Proxy78.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: Notify_GarageDoor1.rules#xtextLink_::0.2.1.2.0.0.1.0.0.8.7.1.1.0.0::0::/1), <null> <unkown> <XNullLiteralImpl>, null, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@71f899, org.eclipse.xtext.util.CancelIndicator$1@781eae]
	... 24 common frames omitted
2016-05-31 21:49:48.614 [ERROR] [org.quartz.core.JobRunShell   ] - Job DEFAULT.2016-05-31T21:49:48.605+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: org.eclipse.xtext.xbase.impl.XClosureImplCustom@77a1bc (explicitSyntax: true) threw an unhandled Exception: 
org.eclipse.emf.common.util.WrappedException: org.eclipse.xtext.util.PolymorphicDispatcher$NoSuchMethodException: Couldn't find method ''_assignValue'' for objects [JvmVoid:  (eProxyURI: Notify_GarageDoor2.rules#xtextLink_::0.2.1.2.0.0.1.0.0.8.7.1.1.0.0::0::/1), <null> <unkown> <XNullLiteralImpl>, null, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@92d0a8, org.eclipse.xtext.util.CancelIndicator$1@781eae]
	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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_75]
	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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_75]
	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.$Proxy78.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]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-all-2.1.7.jar:na]
Caused by: org.eclipse.xtext.util.PolymorphicDispatcher$NoSuchMethodException: Couldn't find method ''_assignValue'' for objects [JvmVoid:  (eProxyURI: Notify_GarageDoor2.rules#xtextLink_::0.2.1.2.0.0.1.0.0.8.7.1.1.0.0::0::/1), <null> <unkown> <XNullLiteralImpl>, null, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@92d0a8, org.eclipse.xtext.util.CancelIndicator$1@781eae]
	... 24 common frames omitted
2016-05-31 21:49:48.614 [ERROR] [org.quartz.core.ErrorLogger   ] - Job (DEFAULT.2016-05-31T21:49:48.605+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: org.eclipse.xtext.xbase.impl.XClosureImplCustom@77a1bc (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 objects [JvmVoid:  (eProxyURI: Notify_GarageDoor2.rules#xtextLink_::0.2.1.2.0.0.1.0.0.8.7.1.1.0.0::0::/1), <null> <unkown> <XNullLiteralImpl>, null, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@92d0a8, org.eclipse.xtext.util.CancelIndicator$1@781eae]
	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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_75]
	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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_75]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_75]
	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.$Proxy78.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: Notify_GarageDoor2.rules#xtextLink_::0.2.1.2.0.0.1.0.0.8.7.1.1.0.0::0::/1), <null> <unkown> <XNullLiteralImpl>, null, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@92d0a8, org.eclipse.xtext.util.CancelIndicator$1@781eae]
	... 24 common frames omitted

Thanks,
Søren

I am no expert on this topic but I see you not doing something I am used to with timers.

Some demo example I used cancelled any timer before it was recreated. Perhaps if you explicitly cancel timers some errors will disappear?

Try setting the timer to null as the last thing in the Timer block instead of the first.

As it reads it looks like the rule is:

When the garage door opens (i.e. state changes to CLOSED) you immediately send a text message and then 18 seconds later you send the picture. If by chance the door closes within that 18 seconds the timer is cancelled so the picture is not sent.

I see no syntax errors or anything obviously wrong.

@rlkoshak The rule you are referring to “Send telegram Notification | Garage door 1 opened” I have not had any issues with, so far It has worked every time, also if the garage door is closed before the timer ends it sends a picture.

I’m using two different timers in this rule.

It’s these two rules I’m having issues with.
rule "Send telegram Notification | Garage door 1 open for 30 min."
rule “Cancel telegram Notification | Garage door 1 open for 30 min.”

@digineut are you thinking doing it like this:

// This rule sends a telegram notification if garage door has been open for 30 min.
rule "Send telegram Notification | Garage door 1 open for 30 min."
when
	Item Garage_Port_1_State_Closed changed to CLOSED
then
	if(tGarageDoor1 != null) tGarageDoor1.cancel()  {          //Terminate timer just for good measure before it is created
		tGarageDoor1 = createTimer(now.plusMinutes(30), [|
			tGarageDoor1 = null
		sendTelegram((TelegramBots), (Message2))
		])
	}
end

rule "Cancel telegram Notification | Garage door 1 open for 30 min."
when
	Item Garage_Port_1_State_Closed changed to OPEN
then
	if(tGarageDoor1 != null) tGarageDoor1.cancel() //Terminate timer if door is closed before the timer ends
end

Is it currently assumed that timers within a given rules-file are only valid in that particular rules-file?

BR Søren

While global vals and vars are only accessible in the one rule file, the Rules wiki page does say there is a potential issue if you have vals and vars of the same name in multiple files and should avoid that.

Alright, thanks. Edit: I’ve just read up on it :slight_smile:

If the vals and vars have the same name and value in multiple rules-files, do you think that could potential cause any issues?

For instance URLs to my IP-cams are always the same.

Or would it be best to only use unique names in all rules-files?

BR Søren

It’s probably best if they had unique names. Though if you use them across multiple files you might consider either putting the values into an Item, reorganizing your files so they only need be defined in one, or create a proxy item and a rule to implement the camera/notification stuff. I use this later method for my notifications.

That sounds as a good way to do it. Would it be too much asking to see some examples from your openHAB, how you have done? That would likely make it easier for me to understand how things are done.

Btw. I have modified my rule “Send telegram Notification | Garage door 1 open for 30 min.” a bit and initial testings seems positive. Hopefully the “fix” will be stable.

Changed the following - can’t figure out why that should make a difference:

(now.plusMinutes(30)

To

(now.plusSeconds(1800)

BR Søren

I posted this somewhere but can’t find it right not.

Items:

Switch T_Notify_Test
String Notification_Proxy_Info
String Notification_Proxy_Alarm

Rules:

// shows how to use it, useful for testing
rule "Test dispatch notifications"
when
        Item T_Notify_Test received command
then
        Notification_Proxy_Info.postUpdate("This is an Info test")
        Notification_Proxy_Alarm.postUpdate("This is an Alarm test")
end

rule "Dispatch Info Notification"
when
        Item Notification_Proxy_Info received update
then
        val String msg = Notification_Proxy_Info.state.toString
        logInfo("Notification", msg)
        if(TimeOfDay.state != "Night") sendPushToDefaultDevice(msg)
end

rule "Dispatch Alarm Notification"
when
        Item Notification_Proxy_Alarm received update
then
        val String msg = Notification_Proxy_Alarm.state.toString
        logError("Notification", msg)
        if(TimeOfDay.state == "Night") sendPushToDefaultDevice(msg) else sendNotification("my email", msg)
end

I can’t either. They should be the same.

Looking at your log files, java is losing its mind because it’s trying to set something that it doesn’t know how to set. Typically I’ve found that (for myself) that happens when I try and set something that doesn’t exist to something. (For example, trying to reschedule a cancelled timer.)

So if I were you, I’d go with the tried-and-true method of spitting a lot of info to the logs. My suspicion is that your code is getting executed when you’re not expecting it to (PIR doing something unexpected, maybe?), so all the logic we’re using to analyze things doesn’t apply.

i.e. I’d re-write your rules to look something like this:

// This rule sends a telegram notification if garage door has been open for 30 min.
rule "Send telegram Notification | Garage door 1 open for 30 min."
when
	Item Garage_Port_1_State_Closed changed to CLOSED
then
        logInfo("openhab","garage door 1 open for 30 minutes entered.  timer: " + tGarageDoor1)
	if(tGarageDoor1 != null) tGarageDoor1.cancel()            //Terminate timer just for good measure before it is created

       {
                logInfo("openhab","creating timer for garage door 1")
		tGarageDoor1 = createTimer(now.plusMinutes(30), [|
                        logInfo("openhab","destroying timer for garage door 1")
			tGarageDoor1 = null
                        logInfo("openhab","sending telegram for garage door 1")
      		        sendTelegram((TelegramBots), (Message2))
    		   ])
	}
end

rule "Cancel telegram Notification | Garage door 1 open for 30 min."
when
	Item Garage_Port_1_State_Closed changed to OPEN
then
        logInfo("openhab","killing garage door 1 timer (#2).  timer: " + tGarageDoor1)
	if(tGarageDoor1 != null) tGarageDoor1.cancel() //Terminate timer if door is closed before the timer ends
end

then run it for a bit. I’m suspecting you’ll find an instance where you cancel a timer twice in a row, and then java loses its mind immediately after that.

Also when cleaning up your formatting a bit, I noticed you had this:

then
	if(tGarageDoor1 != null) tGarageDoor1.cancel()  {          //Terminate timer just for good measure before it is created
		tGarageDoor1 = createTimer(now.plusMinutes(30), [|
			tGarageDoor1 = null
		sendTelegram((TelegramBots), (Message2))
		])
	}
end

which should run OK, but why do you have a block markers ({}) before tGarageDoor1’s timer creation? There doesn’t seem to be any need for them. As a style thing, I put block markers around all my code in a rule; helps me spot errors and compartmentalizes things. But mixing both block style and non-block style just bugs me, mainly because it can lead to unintended code execution! (i.e. pick a style and stick with it! :wink: )

(In general I don’t like to comment on purely style issues, but since you’re getting odd code execution I thought I’d mention it on the offhand it leads you to find the source of your problem. Forgive me for bringing it up in advance!)

Thanks @rlkoshak I’ll look into this and try and learn from you example how :slight_smile:

Oh well, my “fix” didn’t work.

But I think I found a solution. Been doing some debugging using ‘infoLog’. It is the createTimer that seems to not work everytime but after changing some code, it seems to have become stable.

Replaced this

if(tGarageDoor1 == null || tGarageDoor1.hasTerminated)

With

if(tGarageDoor2 != null) tGarageDoor2.cancel()  {          //Terminate timer if one is already started

So now the complete rule lookes like this

// This rule sends a telegram notification if garage door has been open for 30 min.
rule "Send telegram Notification | Garage door 2 open for 30 min."
when
	Item Garage_Port_2_State_Closed changed to CLOSED
then
	if(tGarageDoor2 != null) tGarageDoor2.cancel()  {          //Terminate timer if one is already started
		tGarageDoor2 = createTimer(now.plusMinutes(1), [|
			tGarageDoor2 = null
		sendTelegram((TelegramBots), (Message4))
		logInfo("TimerEnded", "Send telegram Notification | Garage door 2 open for 30 min.")
		])
		logInfo("TimerStarted", "Will send telegram Notification if garage door 2 is not closed within 30 min.")
	}
end

rule "Cancel telegram Notification | Garage door 2 open for 30 min."
when
	Item Garage_Port_2_State_Closed changed to OPEN
then
	if(tGarageDoor2 != null) tGarageDoor2.cancel() 		//Terminate timer if door is closed before the timer ends
end

I’ll keep an eye on things :slight_smile:

Thanks @TheKorn
I absolutely like the use of ‘logInfo’ you have showed - Been trying to use it myself (as you can see in the above post) to debug and to some extent it was a success. :slight_smile:

I’ll try your code and see what happens :slight_smile:

That I can answer very easy: I do not know what I’m doing. I work with SAP IT operations for a living but do not know anything about coding/programming at all.

In general I have been picking bits and pieces of code found on this forum - and from answers to my posts - and trying to putting it all together to get a working openHAB system.

So in other words I do not (yet) have a “style” on how code should “look”. But all good advice are very welcome, I’m all ears and do not get offended :slight_smile:

BR Søren

ROFLOL! Hey, points for being honest! :smiley:

Here’s a pretty clean example of my style for rules. I religiously use indenting (helps me see what my intent was when editing and I wind up with mismatched ()s, s, and {}s), and I wrap every rule in block markers ( {} ) because I feel that it makes very readable code. I also make all my items in ALL CAPS so they jump out at me when I’m trying to manipulate things.

You’ll find (or steal… :wink: ) your own style soon enough!

I should use logDebug instead. If you set the logging level for the script to DEBUG you can lower the logging level to INFO after troubleshooting. This will prevent flooding your logs after the issue has been resolved and there’s no need to change the code afterwards.

For the label use the rule name to remember where to look for. In this case:

// This rule sends a telegram notification if garage door has been open for 30 min.
rule "Send telegram Notification | Garage door 2 open for 30 min."
when
	Item Garage_Port_2_State_Closed changed to CLOSED
then
	if(tGarageDoor2 != null) tGarageDoor2.cancel()  {          //Terminate timer if one is already started
		tGarageDoor2 = createTimer(now.plusMinutes(1), [|
			tGarageDoor2 = null
		sendTelegram((TelegramBots), (Message4))
		logDebug("GaragePort2Closed30Mins", "Send telegram Notification | Garage door 2 open for 30 min.")
		])
		logDebug("GarageDoor2Closed30Mins", "Will send telegram Notification if garage door 2 is not closed within 30 min.")
	}
end

logback.xml

<logger name="org.openhab.model.script.GarageDoor2Closed30Mins" level="DEBUG"/>

I’m of exactly the opposite opinion. Changing the logging level requires restarting openhab, and that’s the last thing I ever want to do! Changing the rule is a lot easier and rules reload on the fly, so that’s my highly preferred method.