Release Candidate and Support: Amazon Echo Control Binding

Hey guys - sorry, but I can’t figure it out, how to do the following steps before alexa speaks.

  1. Save the actual volume
  2. set the volume to 30
  3. Play a alarm tone
  4. play the message
  5. reset the volume to the prior state.

When this is my actual rule:


rule "Heat turned on while window open"

when
    Item EG_Vi_hkpump changed from OFF to ON
then
    if(gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN) {
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd, Ober und Dachgeschoss offen.')
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Ober und Dachgeschoss offen.')    
        }  
        else if(gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd und Dachgeschoss offen.') 
        }
        else if(gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd und Obergeschoss offen.') 
                }
        else if(gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erdgeschoss offen.') 
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Obergeschoss offen.') 
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Dachgeschoss offen.') 
        }
        else
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Fenster sind geschlossen.')

My Items for Alexa:

String Echo_TTS "Text to Speech" (gAlexa) {channel="amazonechocontrol:echo:account1:123456789:textToSpeech"}
Dimmer Echo_Volume  "Volume [%.0f %%]" <soundvolume> (gAlexa) {channel="amazonechocontrol:echo:account1:123456789:volume"}

I read post 736 (thanks to H102 !), but I can’t get this working.
Some genius willing to help me with this adjustment?

Try this and see if it works on the first part of the rule. I didn’t use a text editor so there may be a typo or something small thats missing. Just check the logs for what the problem is and correct.

val EchoVolume = 50
rule "Heat turned on while window open"

when
    Item EG_Vi_hkpump changed from OFF to ON
then
    if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
      Echo_Volume.sendCommand(EchoVolume)
}
var VolumeStates = storeStates(Echo_Volume)
    if(gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN) {
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd, Ober und Dachgeschoss offen.')
   createTimer(now.plusSeconds(15)) [ | 
   restoreStates(VolumeStates)
   ]
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Ober und Dachgeschoss offen.')    
        }  
        else if(gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd und Dachgeschoss offen.') 
        }
        else if(gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd und Obergeschoss offen.') 
                }
        else if(gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erdgeschoss offen.') 
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Obergeschoss offen.') 
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Dachgeschoss offen.') 
        }
        else
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Fenster sind geschlossen.')

You can move this to the end of the rule if you want 50% volume for everything, or everything above it in the rule.

createTimer(now.plusSeconds(15)) [ | 
   restoreStates(VolumeStates)
   ]
1 Like

Beautiful! No errors and the volume is set and restored afterwards! (only if it was set by command. If it was set with the ring by hand, the restore does not work)
Honestly - Thank you SO much!
Further Ideas for the alarm tone?
Post 744 looks so complicated to me - I don’t know how to integrate this.

I think you may want to visit the post 736 again and copy the rule for trapping the state of your echo. If not and alexa is disconnected then nothing in the rule will run. On the other hand if everything in the rule is dependent on alexa only then it shouldn’t make a difference.

First I try to adapt this to my other rule:

rule "Window open while heat is on"

when
    Item gEGContacts changed to OPEN or
    Item gOGContacts changed to OPEN or
    Item gDBContacts changed to OPEN
then
    if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL && EG_Vi_hkpump.state == ON) {
      Echo_Volume.sendCommand(EchoVolume)


    if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        stopMotionTimer = createTimer(now.plusMinutes(1)) [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd, Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
    }
    else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        stopMotionTimer = createTimer(now.plusMinutes(1)) [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        stopMotionTimer = createTimer(now.plusMinutes(1)) [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Dachgeschoss.')
        stopMotionTimer = null
        ]
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        stopMotionTimer = createTimer(now.plusMinutes(1)) [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Obergeschoss.')
        stopMotionTimer = null
        ]
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){
        stopMotionTimer = createTimer(now.plusMinutes(1)) [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erdgeschoss.')
        stopMotionTimer = null
        ]
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        stopMotionTimer = createTimer(now.plusMinutes(1)) [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Obergeschoss.')
        stopMotionTimer = null
        ]
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        stopMotionTimer = createTimer(now.plusMinutes(1)) [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Dachgeschoss.')
        stopMotionTimer = null
        ]
    }
}
createTimer(now.plusSeconds(15)) [ | 
restoreStates(VolumeStates)
]
end

But it does not work - I think this has something to do with the timer?

2018-09-26 22:44:15.690 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2018-09-26T22:44:15.666+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  restoreStates(<XFeatureCallImplCustom>)
} ] threw an unhandled Exception: 
java.lang.reflect.UndeclaredThrowableException: null
	at com.sun.proxy.$Proxy152.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]
Caused by: org.eclipse.smarthome.model.script.engine.ScriptExecutionException: The name 'VolumeStates' cannot be resolved to an item or type; line 63, column 15, length 12
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:133) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
	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.evaluateArgumentExpressions(XbaseInterpreter.java:1115) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1045) ~[?:?]
	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:901) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
	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) ~[?:?]
	... 4 more
2018-09-26 22:44:15.794 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2018-09-26T22:44:15.666+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  restoreStates(<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.reflect.UndeclaredThrowableException
	at com.sun.proxy.$Proxy152.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: The name 'VolumeStates' cannot be resolved to an item or type; line 63, column 15, length 12
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:133) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
	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.evaluateArgumentExpressions(XbaseInterpreter.java:1115) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1045) ~[?:?]
	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:901) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
	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.$Proxy152.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
2018-09-26 22:46:15.223 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2018-09-26T22:46:15.164+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  restoreStates(<XFeatureCallImplCustom>)
} ] threw an unhandled Exception: 
java.lang.reflect.UndeclaredThrowableException: null
	at com.sun.proxy.$Proxy152.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]
Caused by: org.eclipse.smarthome.model.script.engine.ScriptExecutionException: The name 'VolumeStates' cannot be resolved to an item or type; line 63, column 15, length 12
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:133) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
	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.evaluateArgumentExpressions(XbaseInterpreter.java:1115) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1045) ~[?:?]
	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:901) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
	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) ~[?:?]
	... 4 more
2018-09-26 22:46:15.304 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2018-09-26T22:46:15.164+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  restoreStates(<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.reflect.UndeclaredThrowableException
	at com.sun.proxy.$Proxy152.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: The name 'VolumeStates' cannot be resolved to an item or type; line 63, column 15, length 12
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:133) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
	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.evaluateArgumentExpressions(XbaseInterpreter.java:1115) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1045) ~[?:?]
	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:901) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
	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.$Proxy152.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

If you place a timer at each of the if and else if statements there is no need to put in on the end of the rule. So remove this from the end:

createTimer(now.plusSeconds(15)) [ | 
restoreStates(VolumeStates)
]

Also looks like you will need to put **var VolumeStates = storeStates(Echo_Volume) before each if and else if
EDIT: The global val is needed on the top of the rule like:
val EchoVolume = 50

I made the adjustments with no luck:

rule "Window open while heat is on"

when
    Item gEGContacts changed to OPEN or
    Item gOGContacts changed to OPEN or
    Item gDBContacts changed to OPEN
then

if(EG_Vi_hkpump.state == ON){
    if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        stopMotionTimer = createTimer(now.plusMinutes(1)) 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        var VolumeStates = storeStates(Echo_Volume)

        [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd, Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]

        createTimer(now.plusSeconds(15)) [ | 
        restoreStates(VolumeStates)
        ]
    }
    else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        stopMotionTimer = createTimer(now.plusMinutes(1)) 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        var VolumeStates = storeStates(Echo_Volume)

        [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]

        createTimer(now.plusSeconds(15)) [ | 
        restoreStates(VolumeStates)
        ]
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        stopMotionTimer = createTimer(now.plusMinutes(1)) 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        var VolumeStates = storeStates(Echo_Volume)
        
        [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Dachgeschoss.')
        stopMotionTimer = null
        ]

        createTimer(now.plusSeconds(15)) [ | 
        restoreStates(VolumeStates) 
        ]       
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        stopMotionTimer = createTimer(now.plusMinutes(1)) 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        var VolumeStates = storeStates(Echo_Volume)
                
        [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Obergeschoss.')
        stopMotionTimer = null
        ]

        createTimer(now.plusSeconds(15)) [ | 
        restoreStates(VolumeStates) 
        ]        
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){
        stopMotionTimer = createTimer(now.plusMinutes(1)) 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        var VolumeStates = storeStates(Echo_Volume)
               
        [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erdgeschoss.')
        stopMotionTimer = null
        ]

        createTimer(now.plusSeconds(15)) [ | 
        restoreStates(VolumeStates) 
        ]      
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        stopMotionTimer = createTimer(now.plusMinutes(1)) 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        var VolumeStates = storeStates(Echo_Volume)
                
        [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Obergeschoss.')
        stopMotionTimer = null
        ]

        createTimer(now.plusSeconds(15)) [ | 
        restoreStates(VolumeStates)  
        ]         
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        stopMotionTimer = createTimer(now.plusMinutes(1)) 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        var VolumeStates = storeStates(Echo_Volume)
                  
        [|
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Dachgeschoss.')
        stopMotionTimer = null
        ]

        createTimer(now.plusSeconds(15)) [ | 
        restoreStates(VolumeStates) 
        ]         
    }
}
end


2018-09-27 00:21:14.131 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model ‘rules.rules’

2018-09-27 00:23:01.460 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Window open while heat is on’: An error occurred during the script execution: index=1, size=1


@pbogocz maybe like this will work

val EchoVolume = 50
var Timer stopMotionTimer = null
rule "Window open while heat is on"

when
    Item gEGContacts changed to OPEN or
    Item gOGContacts changed to OPEN or
    Item gDBContacts changed to OPEN
then

val VolumeStates = storeStates(Echo_Volume) 

if(EG_Vi_hkpump.state == ON){
    if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
		stopMotionTimer = createTimer(now.plusMinutes(1))
		[ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd, Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
		createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)
        ]
    }
    else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
		stopMotionTimer = createTimer(now.plusMinutes(1))
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)
        ]
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
		}
		stopMotionTimer = createTimer(now.plusMinutes(1))
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]       
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        stopMotionTimer = createTimer(now.plusMinutes(1))       
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Obergeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]        
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
        stopMotionTimer = createTimer(now.plusMinutes(1))       
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erdgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]      
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
		stopMotionTimer = createTimer(now.plusMinutes(1))        
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Obergeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)  
        ]         
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
            Echo_Volume.sendCommand(EchoVolume)
            }
		stopMotionTimer = createTimer(now.plusMinutes(1))          
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]         
    }
}
end

This rule works but is not like expected.
Alexa first sets the volume to 50 and after a minute, sets it back to the prior state. But the message which is played comes afterwards.
So we need to change the order somehow. First set the volume to 50, than play the message and than reset the volume to the prior state.

Try it now

val EchoVolume = 50
var Timer stopMotionTimer = null
rule "Window open while heat is on"

when
    Item gEGContacts changed to OPEN or
    Item gOGContacts changed to OPEN or
    Item gDBContacts changed to OPEN
then

val VolumeStates = storeStates(Echo_Volume) 

if(EG_Vi_hkpump.state == ON){
    if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {       
		stopMotionTimer = createTimer(now.plusMinutes(1))
		[ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd, Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
		createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)
        ]
		}
    }
    else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
		stopMotionTimer = createTimer(now.plusMinutes(1))
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)
        ]
		}
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
		stopMotionTimer = createTimer(now.plusMinutes(1))
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}       
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
        stopMotionTimer = createTimer(now.plusMinutes(1))       
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Obergeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){ 
	    if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
        stopMotionTimer = createTimer(now.plusMinutes(1))       
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erdgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}      
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {   
		stopMotionTimer = createTimer(now.plusMinutes(1))        
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Obergeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)  
        ]
		}         
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
		stopMotionTimer = createTimer(now.plusMinutes(1))          
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}
    }
}
end

Stange…
Exactly after 10 seconds after opening the window, Alexa sets the volume to a new value but does not say anything. After 1 Minute, the message comes and no reset of the volue happens…

2018-09-27 22:26:27.194 [GroupItemStateChangedEvent] - gDBContacts changed from CLOSED to OPEN through DB_fe_bu
2018-09-27 22:26:27.198 [vent.ItemStateChangedEvent] - DB_fe_bu changed from CLOSED to OPEN
2018-09-27 22:26:37.287 [ome.event.ItemCommandEvent] - Item 'Echo_Volume' received command 25
2018-09-27 22:27:27.277 [ome.event.ItemCommandEvent] - Item 'Echo_Volume' received command 25
2018-09-27 22:27:27.290 [ome.event.ItemCommandEvent] - Item 'Echo_TTS' received command Die Heizung ist an. Bitte Fenster schließen im Ober und Dachgeschoss.
2018-09-27 22:27:27.303 [vent.ItemStateChangedEvent] - Echo_TTS changed from  to Die Heizung ist an. Bitte Fenster schließen im Ober und Dachgeschoss.

Maybe there is a mismach with the first rule from yesterday?
Here both rules I have for this:


var Timer stopMotionTimer = null
val EchoVolume = 25

rule "Window open while heat is on"

when
    Item gEGContacts changed to OPEN or
    Item gOGContacts changed to OPEN or
    Item gDBContacts changed to OPEN
then

val VolumeStates = storeStates(Echo_Volume) 

if(EG_Vi_hkpump.state == ON){
    if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {       
		stopMotionTimer = createTimer(now.plusMinutes(1))
		[ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd, Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
		createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)
        ]
		}
    }
    else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
		stopMotionTimer = createTimer(now.plusMinutes(1))
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)
        ]
		}
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
		stopMotionTimer = createTimer(now.plusMinutes(1))
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}       
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
        stopMotionTimer = createTimer(now.plusMinutes(1))       
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Obergeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){ 
	    if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
        stopMotionTimer = createTimer(now.plusMinutes(1))       
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erdgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}      
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {   
		stopMotionTimer = createTimer(now.plusMinutes(1))        
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Obergeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)  
        ]
		}         
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
		stopMotionTimer = createTimer(now.plusMinutes(1))          
        [ |
		Echo_Volume.sendCommand(EchoVolume)
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}
    }
}
end

rule "Heat turned on while window open"

when
    Item EG_Vi_hkpump changed from OFF to ON
then
    if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
      Echo_Volume.sendCommand(EchoVolume)
}
var VolumeStates = storeStates(Echo_Volume)
    if(gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN) {
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd, Ober und Dachgeschoss offen.')
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Ober und Dachgeschoss offen.')    
        }  
        else if(gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd und Dachgeschoss offen.') 
        }
        else if(gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erd und Obergeschoss offen.') 
                }
        else if(gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Erdgeschoss offen.') 
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Obergeschoss offen.') 
        }
        else if(gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Es sind Fenster im Dachgeschoss offen.') 
        }
        else
        Echo_TTS.sendCommand('Die Heizung ist angesprungen. Fenster sind geschlossen.')

createTimer(now.plusSeconds(15)) [ | 
restoreStates(VolumeStates)
]
end

See if this one works.

val EchoVolume = 50
var Timer stopMotionTimer = null
rule "Window open while heat is on"

when
    Item gEGContacts changed to OPEN or
    Item gOGContacts changed to OPEN or
    Item gDBContacts changed to OPEN
then

val VolumeStates = storeStates(Echo_Volume) 

if(EG_Vi_hkpump.state == ON){
    if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == OPEN){
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {       
		stopMotionTimer = createTimer(now.plusMinutes(1))
		Echo_Volume.sendCommand(EchoVolume)		
		[ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd, Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
		createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)
        ]
		}
    }
    else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
		stopMotionTimer = createTimer(now.plusMinutes(1))
		Echo_Volume.sendCommand(EchoVolume)
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Ober und Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)
        ]
		}
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
		stopMotionTimer = createTimer(now.plusMinutes(1))
		Echo_Volume.sendCommand(EchoVolume)
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}       
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
        stopMotionTimer = createTimer(now.plusMinutes(1))
		Echo_Volume.sendCommand(EchoVolume)       
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erd und Obergeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}
    }
        else if(stopMotionTimer === null && gEGContacts.state == OPEN && gOGContacts.state == CLOSED && gDBContacts.state == CLOSED){ 
	    if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {    
        stopMotionTimer = createTimer(now.plusMinutes(1))
		Echo_Volume.sendCommand(EchoVolume)       
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Erdgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}      
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == OPEN && gDBContacts.state == CLOSED){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {   
		stopMotionTimer = createTimer(now.plusMinutes(1))
		Echo_Volume.sendCommand(EchoVolume)        
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Obergeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates)  
        ]
		}         
    }
        else if(stopMotionTimer === null && gEGContacts.state == CLOSED && gOGContacts.state == CLOSED && gDBContacts.state == OPEN){ 
        if(Echo_Volume.state!=UNDEF && Echo_Volume.state!=NULL) {
		stopMotionTimer = createTimer(now.plusMinutes(1)) 
		Echo_Volume.sendCommand(EchoVolume)         
        [ |
        Echo_TTS.sendCommand('Die Heizung ist an. Bitte Fenster schließen im Dachgeschoss.')
        stopMotionTimer = null
        ]
        createTimer(now.plusSeconds(10)) [ | 
        restoreStates(VolumeStates) 
        ]
		}
    }
}
end

No, this does not work at all

2018-09-27 23:41:31.142 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Window open while heat is on': An error occurred during the script execution: index=1, size=1

i would make a new thread for that rule issue, easier to get help that way and it’s not cluttering this binding related thread :slight_smile:

1 Like

Hey @michi ,

I’m using the Beta 2.4 (3) version of this binding…

Everything works fine so far…but is it possible to change the logger from INFO to DEBUG for these log entries in the next (beta-)release?

2018-09-28 11:56:49.200 [INFO ] [control.internal.WebSocketConnection] - Send Ping
2018-09-28 11:56:49.219 [INFO ] [control.internal.WebSocketConnection] - Send message with length 98
2018-09-28 11:56:49.341 [INFO ] [control.internal.WebSocketConnection] - Pong received
2018-09-28 11:56:53.563 [INFO ] [control.internal.WebSocketConnection] - Message received: {"payload":"{\"destinationUserId\":\"XX\",\"mediaReferenceId\":\"xx\",\"dopplerId\":{\"deviceSerialNumber\":\"XX\",\"deviceType\":\"XX\"}}","command":"PUSH_MEDIA_CHANGE"}

Thanks :slight_smile:

The Amazon Echo Control Binding becomes not installed every time I restart the openhab service or restart my Raspberry pi. When I reinstall it works right away, It used to work fine. How can I keep this binding installed?

@michi

any news about the binding? there are still some minor issues with it and i’d love to see it integrated into OpenHAB or at least have it available in the Eclipse Marketplace

  • lastVoiceCommand seems to stop working every now and then, only resolved by an OpenHAB restart
  • log spam about Captcha/Login etc (it does work now without having to re-login, but keeps logging warnings about it for some reason)
  • can we turn off the rather verbose logging in the next version?
    2018-09-28 21:10:58.681 [INFO ] [control.internal.WebSocketConnection] - Message received: {“payload”:"{“destinationUserId”:"… etc
    2018-09-28 21:09:15.147 [INFO ] [control.internal.WebSocketConnection] - Send Ping
    2018-09-28 21:09:15.164 [INFO ] [control.internal.WebSocketConnection] - Send message with length 98

Keep up the good work! :+1:t3:

For the WebSocketConnection messages, i’m not sure if those are controllable from the binding because they are from the OH runtime I believe. I took them out by adding the following to my org.ops4j.pax.logging.cfg file in /var/lib/openhab2/etc (Ubuntu/Raspbian)

# custom filter 
log4j2.appender.out.filter.uselessjunk.type = RegexFilter
log4j2.appender.out.filter.uselessjunk.regex = .*(Send message|Send Ping|Pong received|Message received).*
log4j2.appender.out.filter.uselessjunk.onMatch = DENY
log4j2.appender.out.filter.uselessjunk.onMisMatch = ACCEPT

Edit: for clarity, I put them just under this section:

# Rolling file appender
log4j2.appender.out.type = RollingRandomAccessFile
log4j2.appender.out.name = LOGFILE
log4j2.appender.out.fileName = ${openhab.logdir}/openhab.log
log4j2.appender.out.filePattern = ${openhab.logdir}/openhab.log.%i
log4j2.appender.out.immediateFlush = true
log4j2.appender.out.append = true
log4j2.appender.out.layout.type = PatternLayout
log4j2.appender.out.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5.5p] [%-36.36c] - %m%n
log4j2.appender.out.policies.type = Policies
log4j2.appender.out.policies.size.type = SizeBasedTriggeringPolicy
log4j2.appender.out.policies.size.size = 16MB
1 Like

Is it possible to automate the new “Alexa, I’m leaving” and “Alexa, I’m home” security features using this binding?

Also this binding is awesome!

Does the marketplace version of this work for Australia.
I have tried typing over the Amazon site field in the configuration but it doesn’t seem to save it.
I tried amazon.com.au and alexa.amazon.com.au but neither seemed to work.

I had tried this a while ago under 2.2 and it worked when I typed over the top but I haven’t tried it for a while so I wanted to test it under 2.4