Rule optimization: Window OPEN reminder

OK, never done this before.
So I added this

.........      
  openWins = openWins.replaceLast(", ", "und ") // replace the last comma with "und"
        logDebug("Window open NEW.rules", "gHContacts")

But nothing comes in openhab.log except:

2019-02-27 20:04:31.812 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Window open NEW': An error occurred during the script execution: index=1, size=1

I’m sure, I don’t get the syntax correctly - maybe also my poor english could be a reason…sorry

Or I need to add something into org.ops4j.pax.logging.cfg?
I don’t understand this:

You need to use logInfo or change your logging level.

Now that you know how to log:

Add logging to the Rule and the Timer and log out all the relevant values and Item states. Compare those with the code so you can see what it is actually doing.

So split that line into multiple lines and log out what each part returns so you can figure out if the error is coming from the filter, the map, or the reduce.

The “that line” is the filter, map, reduce line.

Honestly - I don’t know how to log. I don’t understand this.
You say, I need to use logInfo:
So you mean, the line should not be logDebug(…) but logInfo(…) within the rule, right?
But what are this 2 parameters for? I even saw more parameters in some examples which I also did not understand. And what is this “log:set DEBUG org.eclipse.smarthome.model.script.kitchen” for? And where do I have to enter this?
Change my logging level? Where can I do this?
You see - NOOB :cry:
I think I give up.

That’s it. If you do that, you don’t need to fiddle with logging levels, keep it simple.

Put this in a rule -
logInfo ( "some label", "some text that I want")
and it writes into openhab.log
The “text that I want” can be made up from things like
"some text " + someItem.state.toString
which is after all, just a string.

Example -

rule "Fenster_Wohnen_links"
when
        Item EG_wo_fe_li2 changed or
         Item EG_wo_fe_li1 changed
then
        logInfo( "test", "EG-li1 state " + EG_wo_fe_li1.state.toString)
        logInfo( "test", "EG-li2 state " + EG_wo_fe_li2.state.toString)
        if (EG_wo_fe_li2.state == CLOSED && EG_wo_fe_li1.state == CLOSED) {
...

Correct

In each case, the loggerName parameter is combined with the string org.eclipse.smarthome.model.script. to create the log4j logger name.

With the logger name one can configure how and how these log statements get logged out.

The second parameter is the information you want to log out. The statement you want to appear in the logs.

We need more information to understand what the problem is. The only way we can get more information is to print it to the logs, then compare what is printed to the actual code.

There are other ways to format what gets logged that you don’t have to worry about. For details see

If you are looking at openhab.log, you need to edit the log file config. See Log4j2 Sample Config.

But you don’t have to mess with any of that. Just use logInfo instead of logDebug.

rule "Window open NEW"
when
    Member of gHContacts changed to OPEN
then
    logInfo("Test", "Running Window openNEW Rule: EG_Vi_hkpump == " + EG_Vi_hkpump.state.toString)

    if(EG_Vi_hkpump.state == OFF) return;
    if(stopMotionTimer !== null) return;

    logInfo("Test", "stopMotionTimer is null, proceeding to create the timer")

    // Set the timer
    stopMotionTimer = createTimer(now.plusMinutes(1) [|
        logInfo("Test", "Inside the timer")
        // Generate a list of all the open windows
        var openWins = gHContacts.members.filter[ w | w.state == OPEN ]
        logInfo("Test", "Open window Items: " + openWins)
        var openWinsNames = openWins.map[ transform("MAP", "windows.map", name) ]
        logInfo("Test", "Open window names: " + openWinsNames)
        var openWinsMsg = openWinsNames.reduce[ msg, winName | msg + ", " + winName ]
        logInfo("Test", "Open window message: " + openWinsMsg)

        openWinsMsg = openWinsMsg.replaceFirst(", ", "") // delete the first comma
        logInfo("Test", "Deleted the first comma: " + openWinsMsg)
        openWinsMsg = openWinsMsg.replaceLast(", ", "und ") // replace the last comma with "und"
        logInfo("Test", "Replaced last comma with und: " + openWinsMsg)

        Echo_TTS.sendCommand("Die Heizung ist an. Bitte Fenster schließen im "/* + openWinsMsg + "."/*/)
        logInfo("Test", "Sent message to the Echo")
        stopMotionTimer = null
        logInfo("Test", "Set the Timer to null")
    ])

    logInfo("Test", "Rule is done")
end

Log everything.

Break up the long lines and log it at each stage.

The line with the error will be the line right after the last line logged. If you see “Set the Timer to null” in the log then the Rule and the Timer completed successfully.

1 Like

Thank you for still helping me - honestly, thanks!
And for still explaining all the details…thanks!

I made the changes you coded into the rule.
Here is the result:
Event.log:

2019-02-27 23:22:24.771 [GroupItemStateChangedEvent] - gDBContacts changed from CLOSED to OPEN through DB_ve
2019-02-27 23:22:24.774 [vent.ItemStateChangedEvent] - DB_ve changed from CLOSED to OPEN

Openhab.log:

2019-02-27 23:22:17.893 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'rules.rules'
2019-02-27 23:22:40.255 [INFO ] [.eclipse.smarthome.model.script.Test] - Running Window openNEW Rule: EG_Vi_hkpump == ON
2019-02-27 23:22:40.262 [INFO ] [.eclipse.smarthome.model.script.Test] - stopMotionTimer is null, proceeding to create the timer
2019-02-27 23:22:40.265 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Window open NEW': An error occurred during the script execution: index=1, size=1

Looks like the rule did not get inside the timer, right?

Yes. You are missing a comma.

Are you using VSCode? It would have caught this error as you typed it.

stopMotionTimer = createTimer(now.plusMinutes(1), [|

I’m usually replying from my phone so don’t have the benefit of using VSCode.

I do use VSCode - but there was no Info regarding the comma.
You honestly just told me, you type this into your cellphone? Programming is your job, right? Sound unbelivable to me…
Well, now we get inside the timer but than things become strange. First of all, the first comma you delete - what is the reason for this? I mean, the names of the first window and the second are put together.
And than the error:

2019-02-27 23:33:35.567 [INFO ] [.eclipse.smarthome.model.script.Test] - Running Window openNEW Rule: EG_Vi_hkpump == ON
2019-02-27 23:33:35.574 [INFO ] [.eclipse.smarthome.model.script.Test] - stopMotionTimer is null, proceeding to create the timer
2019-02-27 23:33:35.585 [INFO ] [.eclipse.smarthome.model.script.Test] - Rule is done
2019-02-27 23:34:35.581 [INFO ] [.eclipse.smarthome.model.script.Test] - Inside the timer
2019-02-27 23:34:35.672 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window Items: [OG_Sc_fe_li2 (Type=ContactItem, State=OPEN, Label=Schlafen links, Category=window, Groups=[gHFenster, gOG, gSCH, gOGFenster, gOGContacts, gHContacts]), DB_ve (Type=ContactItem, State=OPEN, Label=Dachboden Velux, Category=null, Groups=[gHFenster, gDB, gDBFenster, gBU, gHContacts, gDBContacts]), DB_fe_te (Type=ContactItem, State=OPEN, Label=Technik Fenster, Category=null, Groups=[gHFenster, gDB, gDBFenster, gTE, gHContacts])]
2019-02-27 23:34:35.740 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window names: [Schlafzimmer links, Büro, Velux, Technikraum, Dachboden]
2019-02-27 23:34:35.779 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window message: Schlafzimmer links, Büro, Velux, Technikraum, Dachboden
2019-02-27 23:34:35.785 [INFO ] [.eclipse.smarthome.model.script.Test] - Deleted the first comma: Schlafzimmer linksBüro, Velux, Technikraum, Dachboden
2019-02-27 23:34:35.793 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2019-02-27T23:34:35.576+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  var openWins
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  var openWinsNames
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  var openWinsMsg
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  <null>.openWinsMsg = <XMemberFeatureCallImplCustom>
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  <null>.openWinsMsg = <XMemberFeatureCallImplCustom>
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  <XFeatureCallImplCustom>.sendCommand(<XBinaryOperationImplCustom>)
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  <null>.stopMotionTimer = <XNullLiteralImplCustom>
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
} ] threw an unhandled Exception: 
java.lang.reflect.UndeclaredThrowableException: null
	at com.sun.proxy.$Proxy150.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) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
Caused by: org.eclipse.smarthome.model.script.engine.ScriptExecutionException: 'replaceLast' is not a member of 'java.lang.String'; line 163, column 23, length 37
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:133) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:772) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:220) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:1212) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:216) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:447) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:228) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:190) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]
	... 4 more
2019-02-27 23:34:35.872 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2019-02-27T23:34:35.576+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  var openWins
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  var openWinsNames
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  var openWinsMsg
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  <null>.openWinsMsg = <XMemberFeatureCallImplCustom>
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  <null>.openWinsMsg = <XMemberFeatureCallImplCustom>
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  <XFeatureCallImplCustom>.sendCommand(<XBinaryOperationImplCustom>)
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  <null>.stopMotionTimer = <XNullLiteralImplCustom>
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
} ] 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.oh240]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
Caused by: java.lang.reflect.UndeclaredThrowableException
	at com.sun.proxy.$Proxy150.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
Caused by: org.eclipse.smarthome.model.script.engine.ScriptExecutionException: 'replaceLast' is not a member of 'java.lang.String'; line 163, column 23, length 37
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:133) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:772) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:220) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:1212) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:216) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:447) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:228) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:190) ~[?:?]
	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.$Proxy150.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

Not any more. I miss it. That’s probably why I contribute so much on the forum.

OK, now we are getting somewhere. It is the call to replace the last comma with “und” that is generating the error.

Yep, replaceLast is a new addition to Java and not available in Java 8. We will need to use an alternative. I have to leave soon so it will probably be tomorrow. For now comment it out and see if it works.

Also, it looks like we don’t need the line that delete’s the first comma. So you can remove that too.

You are the man. Generally it works now!
A quick test showed me that it works as long as no other window is opened during the timer runs.
If an other window is opened, it drops an error:

2019-02-28 08:22:54.419 [INFO ] [.eclipse.smarthome.model.script.Test] - Running Window openNEW Rule: EG_Vi_hkpump == ON
2019-02-28 08:22:54.439 [INFO ] [.eclipse.smarthome.model.script.Test] - stopMotionTimer is null, proceeding to create the timer
2019-02-28 08:22:54.466 [INFO ] [.eclipse.smarthome.model.script.Test] - Rule is done
2019-02-28 08:23:54.444 [INFO ] [.eclipse.smarthome.model.script.Test] - Inside the timer
2019-02-28 08:23:54.511 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window Items: [OG_Ba_fe_li (Type=ContactItem, State=OPEN, Label=Bad links, Category=window, Groups=[gHFenster, gOG, gBAD, gOGFenster, gOGContacts, gHContacts]), DB_fe_bu (Type=ContactItem, State=OPEN, Label=Dachboden Fenster, Category=null, Groups=[gHFenster, gDB, gDBFenster, gBU, gHContacts, gDBContacts]), DB_ve (Type=ContactItem, State=OPEN, Label=Dachboden Velux, Category=null, Groups=[gHFenster, gDB, gDBFenster, gBU, gHContacts, gDBContacts]), DB_fe_te (Type=ContactItem, State=OPEN, Label=Technik Fenster, Category=null, Groups=[gHFenster, gDB, gDBFenster, gTE, gHContacts])]
2019-02-28 08:23:54.592 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window names: [Bad links, Büro, Büro, Velux, Technikraum, Dachboden]
2019-02-28 08:23:54.662 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window message: Bad links, Büro, Büro, Velux, Technikraum, Dachboden
2019-02-28 08:23:54.670 [INFO ] [.eclipse.smarthome.model.script.Test] - Sent message to the Echo
2019-02-28 08:23:54.675 [INFO ] [.eclipse.smarthome.model.script.Test] - Set the Timer to null
2019-02-28 08:25:02.706 [INFO ] [.eclipse.smarthome.model.script.Test] - Running Window openNEW Rule: EG_Vi_hkpump == ON
2019-02-28 08:25:02.721 [INFO ] [.eclipse.smarthome.model.script.Test] - stopMotionTimer is null, proceeding to create the timer
2019-02-28 08:25:02.741 [INFO ] [.eclipse.smarthome.model.script.Test] - Rule is done
2019-02-28 08:25:32.055 [INFO ] [.smarthome.model.script.system.rules] - Uptime updated to 1 Tage / 5 Std. / 24 Min.
2019-02-28 08:26:02.728 [INFO ] [.eclipse.smarthome.model.script.Test] - Inside the timer
2019-02-28 08:26:02.786 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window Items: [OG_Ba_fe_li (Type=ContactItem, State=OPEN, Label=Bad links, Category=window, Groups=[gHFenster, gOG, gBAD, gOGFenster, gOGContacts, gHContacts]), DB_fe_bu (Type=ContactItem, State=OPEN, Label=Dachboden Fenster, Category=null, Groups=[gHFenster, gDB, gDBFenster, gBU, gHContacts, gDBContacts]), DB_ve (Type=ContactItem, State=OPEN, Label=Dachboden Velux, Category=null, Groups=[gHFenster, gDB, gDBFenster, gBU, gHContacts, gDBContacts]), DB_fe_te (Type=ContactItem, State=OPEN, Label=Technik Fenster, Category=null, Groups=[gHFenster, gDB, gDBFenster, gTE, gHContacts])]
2019-02-28 08:26:02.879 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window names: [Bad links, Büro, Büro, Velux, Technikraum, Dachboden]
2019-02-28 08:26:03.015 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window message: Bad links, Büro, Büro, Velux, Technikraum, Dachboden
2019-02-28 08:26:03.022 [INFO ] [.eclipse.smarthome.model.script.Test] - Sent message to the Echo
2019-02-28 08:26:03.025 [INFO ] [.eclipse.smarthome.model.script.Test] - Set the Timer to null
2019-02-28 08:27:23.677 [INFO ] [.eclipse.smarthome.model.script.Test] - Inside the timer
2019-02-28 08:27:23.681 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2019-02-28T08:27:23.673+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  var openWins
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  var openWinsNames
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  var openWinsMsg
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  <XFeatureCallImplCustom>.sendCommand(<XBinaryOperationImplCustom>)
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  <null>.stopMotionTimer = <XNullLiteralImplCustom>
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
} ] threw an unhandled Exception: 
java.lang.NullPointerException: null
	at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:66) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:140) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:902) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:865) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:224) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:768) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:220) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1116) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:992) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:772) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:220) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:827) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:264) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:447) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:228) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:190) ~[?:?]
	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.$Proxy150.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) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
2019-02-28 08:27:23.884 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2019-02-28T08:27:23.673+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  var openWins
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  var openWinsNames
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  var openWinsMsg
  logInfo(<XStringLiteralImpl>,<XBinaryOperationImplCustom>)
  <XFeatureCallImplCustom>.sendCommand(<XBinaryOperationImplCustom>)
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  <null>.stopMotionTimer = <XNullLiteralImplCustom>
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
} ] 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.oh240]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
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:140) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:902) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:865) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:224) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:768) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:220) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1116) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:992) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:772) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:220) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:827) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:264) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:447) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:228) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:190) ~[?:?]
	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.$Proxy150.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
2019-02-28 08:29:12.169 [INFO ] [.eclipse.smarthome.model.script.Test] - Running Window openNEW Rule: EG_Vi_hkpump == ON
2019-02-28 08:29:12.176 [INFO ] [.eclipse.smarthome.model.script.Test] - stopMotionTimer is null, proceeding to create the timer
2019-02-28 08:29:12.192 [INFO ] [.eclipse.smarthome.model.script.Test] - Rule is done
2019-02-28 08:29:28.871 [INFO ] [.eclipse.smarthome.model.script.Test] - Running Window openNEW Rule: EG_Vi_hkpump == ON
2019-02-28 08:29:45.050 [INFO ] [.eclipse.smarthome.model.script.Test] - Running Window openNEW Rule: EG_Vi_hkpump == ON
2019-02-28 08:30:12.189 [INFO ] [.eclipse.smarthome.model.script.Test] - Inside the timer
2019-02-28 08:30:12.304 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window Items: [OG_Mi_fe_li (Type=ContactItem, State=OPEN, Label=Mika links, Category=window, Groups=[gHFenster, gOG, gMI, gOGFenster, gOGContacts, gHContacts]), OG_Sc_fe_re (Type=ContactItem, State=OPEN, Label=Schlafen rechts, Category=window, Groups=[gHFenster, gOG, gSCH, gOGFenster, gOGContacts, gHContacts]), OG_Hw_fe (Type=ContactItem, State=OPEN, Label=HWR, Category=window, Groups=[gHFenster, gOG, gHWR, gOGFenster, gOGContacts, gHContacts]), OG_Ba_fe_li (Type=ContactItem, State=OPEN, Label=Bad links, Category=window, Groups=[gHFenster, gOG, gBAD, gOGFenster, gOGContacts, gHContacts]), DB_fe_bu (Type=ContactItem, State=OPEN, Label=Dachboden Fenster, Category=null, Groups=[gHFenster, gDB, gDBFenster, gBU, gHContacts, gDBContacts]), DB_ve (Type=ContactItem, State=OPEN, Label=Dachboden Velux, Category=null, Groups=[gHFenster, gDB, gDBFenster, gBU, gHContacts, gDBContacts]), DB_fe_te (Type=ContactItem, State=OPEN, Label=Technik Fenster, Category=null, Groups=[gHFenster, gDB, gDBFenster, gTE, gHContacts])]
2019-02-28 08:30:12.407 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window names: [Kinderzimmer Mika links, Schlafzimmer rechts, Hauswirtschaftsraum, Bad links, Büro, Büro, Velux, Technikraum, Dachboden]
2019-02-28 08:30:12.513 [INFO ] [.eclipse.smarthome.model.script.Test] - Open window message: Kinderzimmer Mika links, Schlafzimmer rechts, Hauswirtschaftsraum, Bad links, Büro, Büro, Velux, Technikraum, Dachboden
2019-02-28 08:30:12.524 [INFO ] [.eclipse.smarthome.model.script.Test] - Sent message to the Echo
2019-02-28 08:30:12.532 [INFO ] [.eclipse.smarthome.model.script.Test] - Set the Timer to null

But I need to test a little more to give you more details.
So generally it should work like this:
Rule open window
If a window is opened, the timer starts.
If an other window is opened, the timer starts again.
If no window is opened for 15 minutes, the message is send to alexa.

Rule close window
If a window is closed, the timer starts.
If an other window is closed, the timer starts again.
If no window is closed after a minute, the message is send to alexa which windows are still open.

So this is the “aim”.

There should be no error, as the rule takes care of not adding another timer when already created one. That’s the line

if(stopMotionTimer !== null) return;

Inquestion of two rules: What should happen if a window was opened and (maybe another window was) closed. There is a running timer for opening the window and another for closing.
You could simplify the rule by changing the trigger:

// head of rules file
var Timer stopMotionTimer = null


rule "Window state announcement"
when
    Member of gHContacts changed
then
    logInfo("Test", "Running Window openNEW Rule: EG_Vi_hkpump == " + EG_Vi_hkpump.state.toString)
    if(EG_Vi_hkpump.state == OFF) return;
    if(gHContacts.members.filter[ w | w.state == OPEN ].size == 0) {
        stopMotionTimer?.cancel
        stopMotionTimer = null
        logInfo("Test","All windows closed. Ending...")
        Echo_TTS.sendCommand("Alle Fenster sind nun geschlossen. Danke!"
        return;
    }
    var Number TimerLength = 15
    if(triggeringItem.state == CLOSED) 
        TimerLength = 1 
    if(stopMotionTimer !== null) 
        stopMotionTimer.reschedule(now.plusMinutes(TimerLength.intValue))
    else {
        logInfo("Test", "stopMotionTimer is null, proceeding to create the timer")

        // Set the timer
        stopMotionTimer = createTimer(now.plusMinutes(TimerLength.intValue), [|
            logInfo("Test", "Inside the timer")
            // Generate a list of all the open windows
            var openWins = gHContacts.members.filter[ w | w.state == OPEN ]
            logInfo("Test", "Open window Items: " + openWins)
            var openWinsNames = openWins.map[ transform("MAP", "windows.map", name) ]
            logInfo("Test", "Open window names: " + openWinsNames)
            var openWinsMsg = openWinsNames.reduce[ msg, winName | msg + ", " + winName ]
            logInfo("Test", "Open window message: " + openWinsMsg)

            openWinsMsg = openWinsMsg.replaceFirst(", ", "") // delete the first comma
            logInfo("Test", "Deleted the first comma: " + openWinsMsg)
            // openWinsMsg = openWinsMsg.replaceLast(", ", "und ") // replace the last comma with "und"
            // logInfo("Test", "Replaced last comma with und: " + openWinsMsg)

            Echo_TTS.sendCommand("Die Heizung ist an. Bitte Fenster schließen im "/* + openWinsMsg + "."/*/)
            logInfo("Test", "Sent message to the Echo")
            stopMotionTimer = null
            logInfo("Test", "Set the Timer to null")
        ])
    }
    logInfo("Test", "Rule is done")
end

I’ve expanded the rule, so

  1. If the timer is already started, the rule will reschedule the timer instead of silently return.
  2. If a window is closed, the timer will end after 1 minute.
  3. If all windows are already closed, the timer will be cancelled and another message will emerge.
1 Like

Combining this rule is very nice. Works very good. I tested everything and there is only 1 problem left.
Some windows have 2 Contacts.
1 contact is for window on tilt and the other for window wide open.
So I have a String and a rule that gives me 3 states.
0 = window closed
1= window on tilt
2=window open
Here the items for one of this windows:

Contact EG_wo_fe_li1  "Wohnen Links Auf [MAP(de.map):%s]" <window> (gEGContactsOffen, gEGContacts) { channel="knx:device:bridge:Tasterschnittstellen:EG_wo_fe_li1" } 
Contact EG_wo_fe_li2  "Wohnen Links Kippe [MAP(de.map):%s]" <window> (gEGContactsKippe, gEGContacts) { channel="knx:device:bridge:Tasterschnittstellen:EG_wo_fe_li2" } 
String EG_wo_fe_li "Wohnen Links [MAP(de.map):%s]" <contact> (gHFenster, gEG, gEGFenster, gWO, gHContacts)

And this is the rule:

rule Fenster_Wohnen_links
when
        Item EG_wo_fe_li2 changed or
         Item EG_wo_fe_li1 changed
then
        if (EG_wo_fe_li2.state == CLOSED && EG_wo_fe_li1.state == CLOSED) {
          EG_wo_fe_li.postUpdate(0)
        } else if (EG_wo_fe_li2.state == OPEN && EG_wo_fe_li1.state == CLOSED) {
           EG_wo_fe_li.postUpdate(1)
        } else {
           EG_wo_fe_li.postUpdate(2)
        }
end

This windows do not work with this rule because the state is not = OPEN or CLOSED
Is it possible to also introduce this 3 states aditionally or how could this be solved?
As for now, I only took the upper contact into the Group gHContacts beacuse this one is always open wether tilt or open wide.

Why would you not just put both contacts into the group that triggers the reminder?

This is possible too but this would give me 2 messages for 1 window when the window is open wide.

Well, that gives you the one warning. What is it that you want to happen instead?

Well, it would be perfect when Alexa sais " The following windows are open …thereof are the following on tilt…"
I don’t know if possible to also introduce the additionally states (0, 1 and 2) which I have beside OPEN and CLOSED.

Sure. You’d add code to the rule that did this or that for states 0 or 1 or 2 as well as code that does this or that for states OPEN or CLOSED.

I know, I was helped A LOT here but can you maybe get more into detail? I don’t know how to do it.

if (gHContacts.members.filter[ w | w.state == OPEN ].size == 0)

Well this is your first hurdle, it counts OPEN group members. With your string items in the same group, you’d want to check for their state as well.
There’s a shortcut way to do this with numbers, but you decided to use strings for your tilt/turns so we’ll work with that.

if (gHContacts.members.filter[ w | w.state == OPEN || w.state == "1" || w.state == "2" ].size == 0)