Release Candidate and Support: Amazon Echo Control Binding


Would it be possible to add something to be able to act on alarm start/stop. And know the time of theses

And be able to create alarm from this binding to the alexa app.

Please have a look at post #1377 in this thread.

It´s currently only possible to get this information as json within a rule.
But i´m not sure if it´s really json, the result looks like plain text.

@michi Could it be that the result from
is just text in json format and not a real json?
As i´m not able to parse this correctly in a rule for json.

Hi Michael.
I get “bad requests” when I send TTS commands to 5 or 6 Echos at the same time in a rule. A part of the commands doesn’t work, but the rest is okay. Is there a solution for this problem?
Thanks and greetings,

Thank you Rainer15 for this! I made a few modifications with a HUE Bulb, only runs between 4 - 7 am, offset of 45 seconds and less logging during those checks.

rule "Guest Bedroom Echo Alarm controling HUE bed side table light"
		Time cron "45 0/1 4-7 * * ?"		// run every 45 secs between 4 - 7 am
		// read Alexa notifications - alarm, reminders, timers
		// logInfo("ECHO", "Echo reading notifications set")		

        	var String json = sendHttpGetRequest("http://openhab.XXXXX:8080/amazonechocontrol/account1/PROXY/api/notifications")
        	// get number of notifications read
        	var String length = transform("JSONPATH", "$.notifications.length()", json)
			if (json !== null && length !== null){

	        	// logInfo("ECHO", json)
	        	// logInfo("ECHO", "-----------")
	        	// logInfo("ECHO", "Number of notifications found: " + length)
	        	var i = 0
	        	var String status
	        	var String deviceSerialNumber
	        	var String type
	        	var String alarmtime = "NULL"
	        	var String alarmdate = "NULL"
	        	var int count = Integer::parseInt(length)
	        	// for all notifications, identify ...
	        	while(i <= (count - 1)) {
	            	status = transform("JSONPATH", "$.notifications[" + i +"].status", json)
	            	deviceSerialNumber = transform("JSONPATH", "$.notifications[" + i + "].deviceSerialNumber", json)
	            	type = transform("JSONPATH", "$.notifications[" + i + "].type", json)
	            	// logInfo("ECHO", "Count: " + i)
	            	// logInfo("ECHO", "Notification status: " + status)
	            	// logInfo("ECHO", "Device serial number: " + deviceSerialNumber)
	            	// An ALARM that is ACTIVE and belongs to the GUEST BEDROOM echo device
	            	if (type == "Alarm" && status == "ON" && deviceSerialNumber == "G090LF09715401NW") {
	                	alarmtime = transform("JSONPATH", "$.notifications[" + i + "].originalTime", json)
	                	alarmdate = transform("JSONPATH", "$.notifications[" + i + "].originalDate", json)
	                	logInfo("ECHO", "Guest Bedroom Alarm found: " + alarmtime + " " + alarmdate)
	                	i = count 	// only the first one is considered - exit while loop
	            	i = i + 1
	        	// An active alarm has been found
	        	if (alarmtime != "NULL") {
	            	var DateTime setAlarmTime = new DateTime(alarmdate + "T" + alarmtime)
	            	// logInfo("ECHO", "Guest Bedroom set alarm time used for Hue control: " + setAlarmTime.toString)		// uncomment this one to determine what alarm time was used
	            	if (now.isBefore(setAlarmTime) && now.plusMinutes(20).isAfter(setAlarmTime)) {
	               	 logInfo("ECHO", "Guest Bedroom Alarm is within 20 minutes range")
	                	if (now.isBefore(setAlarmTime) && now.plusMinutes(15).isAfter(setAlarmTime)) {
	                    		logInfo("ECHO", "Guest Bedroom Alarm is within 15 minutes range")
	                    		if (now.isBefore(setAlarmTime) && now.plusMinutes(10).isAfter(setAlarmTime)) {
										logInfo("ECHO", "Guest Bedroom Alarm is within 10 minutes range")
										GuestBedLamp_Dimmer.sendCommand(new PercentType(80))			// 80%
										GuestBedLamp_ColorTemp.sendCommand(new PercentType(100))		// Full White
	                    		} else {
										GuestBedLamp_Dimmer.sendCommand(new PercentType(50))			// 50%
										GuestBedLamp_ColorTemp.sendCommand(new PercentType(100))		// Full White
	                	} else {
										GuestBedLamp_Dimmer.sendCommand(new PercentType(30))			// 30%
										GuestBedLamp_ColorTemp.sendCommand(new PercentType(100))		// Full White

Best, Jay

Can I call this adress from homeseer ? If my openhab server is on the serve pc as Homeseer?

I had the same issue when sending too many commands to the binding or more precisely the binding to the Amazon servers.
My only solution was a group with every echo as a member or use GroupItem Methods to build something like a dynamic group.
I don´t know why but this works…

I also noticed that sending commands too fast will end in bad request errors.
For example: Triggering a rule with only one TTS command multiple times one after the other.

This shouldn´t be a problem.
I already called this address from other machines than openHAB where the binding is running.

I’m getting this Error currently:

org.glassfish.jersey.server.internal.process.MappableException: org.openhab.binding.amazonechocontrol.internal.HttpException: GET url '' failed: Bad Request

	at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo( ~[?:?]

	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed( ~[171:org.glassfish.jersey.core.jersey-common:2.22.2]

	at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo( ~[171:org.glassfish.jersey.core.jersey-common:2.22.2]

	at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse( [172:org.glassfish.jersey.core.jersey-server:2.22.2]

	at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse( [172:org.glassfish.jersey.core.jersey-server:2.22.2]

	at org.glassfish.jersey.server.ServerRuntime$Responder.process( [172:org.glassfish.jersey.core.jersey-server:2.22.2]

	at org.glassfish.jersey.server.ServerRuntime$ [172:org.glassfish.jersey.core.jersey-server:2.22.2]

	at org.glassfish.jersey.internal.Errors$ [171:org.glassfish.jersey.core.jersey-common:2.22.2]

	at org.glassfish.jersey.internal.Errors$ [171:org.glassfish.jersey.core.jersey-common:2.22.2]

	at org.glassfish.jersey.internal.Errors.process( [171:org.glassfish.jersey.core.jersey-common:2.22.2]

	at org.glassfish.jersey.internal.Errors.process( [171:org.glassfish.jersey.core.jersey-common:2.22.2]

	at org.glassfish.jersey.internal.Errors.process( [171:org.glassfish.jersey.core.jersey-common:2.22.2]

	at org.glassfish.jersey.process.internal.RequestScope.runInScope( [171:org.glassfish.jersey.core.jersey-common:2.22.2]

	at org.glassfish.jersey.server.ServerRuntime.process( [172:org.glassfish.jersey.core.jersey-server:2.22.2]

	at org.glassfish.jersey.server.ApplicationHandler.handle( [172:org.glassfish.jersey.core.jersey-server:2.22.2]

	at org.glassfish.jersey.servlet.WebComponent.serviceImpl( [169:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

	at org.glassfish.jersey.servlet.WebComponent.service( [169:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

	at org.glassfish.jersey.servlet.ServletContainer.service( [169:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

	at org.glassfish.jersey.servlet.ServletContainer.service( [169:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

	at org.glassfish.jersey.servlet.ServletContainer.service( [169:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

	at com.eclipsesource.jaxrs.publisher.internal.ServletContainerBridge.service( [20:com.eclipsesource.jaxrs.publisher:]

	at org.eclipse.jetty.servlet.ServletHolder.handle( [85:org.eclipse.jetty.servlet:9.4.11.v20180605]

	at org.eclipse.jetty.servlet.ServletHandler.doHandle( [85:org.eclipse.jetty.servlet:9.4.11.v20180605]

	at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle( [186:org.ops4j.pax.web.pax-web-jetty:7.2.3]

	at org.eclipse.jetty.server.handler.ScopedHandler.handle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at []

	at org.eclipse.jetty.server.handler.HandlerWrapper.handle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.session.SessionHandler.doHandle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.handler.ContextHandler.doHandle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle( [186:org.ops4j.pax.web.pax-web-jetty:7.2.3]

	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.servlet.ServletHandler.doScope( [85:org.eclipse.jetty.servlet:9.4.11.v20180605]

	at org.eclipse.jetty.server.session.SessionHandler.doScope( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.handler.ContextHandler.doScope( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.handler.ScopedHandler.handle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle( [186:org.ops4j.pax.web.pax-web-jetty:7.2.3]

	at org.eclipse.jetty.server.handler.HandlerWrapper.handle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.Server.handle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.HttpChannel.handle( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at org.eclipse.jetty.server.HttpConnection.onFillable( [84:org.eclipse.jetty.server:9.4.11.v20180605]

	at$ReadCallback.succeeded( []

	at []

	at$ []

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask( [87:org.eclipse.jetty.util:9.4.11.v20180605]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce( [87:org.eclipse.jetty.util:9.4.11.v20180605]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce( [87:org.eclipse.jetty.util:9.4.11.v20180605]

	at [87:org.eclipse.jetty.util:9.4.11.v20180605]

	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ [87:org.eclipse.jetty.util:9.4.11.v20180605]

	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob( [87:org.eclipse.jetty.util:9.4.11.v20180605]

	at org.eclipse.jetty.util.thread.QueuedThreadPool$ [87:org.eclipse.jetty.util:9.4.11.v20180605]

	at [?:?]

Caused by: org.openhab.binding.amazonechocontrol.internal.HttpException: GET url '' failed: Bad Request

	at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequest( ~[?:?]

	at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequestAndReturnString( ~[?:?]

	at org.openhab.binding.amazonechocontrol.internal.Connection.getMusicProviders( ~[?:?]

	at org.openhab.binding.amazonechocontrol.internal.statedescription.AmazonEchoDynamicStateDescriptionProvider.getStateDescription( ~[?:?]

	at org.eclipse.smarthome.core.thing.internal.ChannelStateDescriptionProvider.getDynamicStateDescription( ~[?:?]

	at org.eclipse.smarthome.core.thing.internal.ChannelStateDescriptionProvider.getStateDescription( ~[?:?]

	at org.eclipse.smarthome.core.thing.internal.ChannelStateDescriptionProvider.getStateDescriptionFragment( ~[?:?]

	at org.eclipse.smarthome.core.internal.service.StateDescriptionServiceImpl.mergeStateDescriptionFragments( ~[?:?]

	at org.eclipse.smarthome.core.internal.service.StateDescriptionServiceImpl.getStateDescription( ~[?:?]

	at org.eclipse.smarthome.core.items.GenericItem.getStateDescription( ~[?:?]

	at ~[?:?]

	at ~[?:?]

	at ~[?:?]

	at$0( ~[?:?]

	at$3$1.accept( ~[?:?]

	at java.util.HashMap$KeySpliterator.tryAdvance( ~[?:?]

	at$WrappingSpliterator.lambda$initPartialTraversalState$0( ~[?:?]

	at$AbstractWrappingSpliterator.fillBuffer( ~[?:?]

	at$AbstractWrappingSpliterator.doAdvance( ~[?:?]

	at$WrappingSpliterator.tryAdvance( ~[?:?]

	at java.util.Spliterators$1Adapter.hasNext( ~[?:?]

	at ~[?:?]

	at ~[?:?]

	at ~[?:?]

	at ~[?:?]

	at org.glassfish.jersey.message.internal.ReaderWriter.writeTo( ~[?:?]

	at org.glassfish.jersey.message.internal.AbstractMessageReaderWriterProvider.writeTo( ~[?:?]

	at org.glassfish.jersey.message.internal.InputStreamProvider.writeTo( ~[?:?]

	at org.glassfish.jersey.message.internal.InputStreamProvider.writeTo( ~[?:?]

	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo( ~[?:?]

	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo( ~[?:?]

	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed( ~[?:?]

	at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo( ~[?:?]

	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed( ~[?:?]

	at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo( ~[?:?]

	... 53 more

And can someone share their .sitemap for all Bluetooth Items? not quite sure how I should use them!
I can see all bluetooth Devices under:
But I’m not able to see any of those under:
within the bluetoothMAC section

New Beta 2.5 (2) Release

This version supports new channels for the next reminder, alarm and timer event.
It fixes a problem with wrong character encoding for french sites and I’am proudly to present:


Download from the top most posting


Thanks for your work.

How do we use the SSML with openHAB?

Have you tried the SSML documentation from the post above?

I tried to add <break> to a TTS but Alexa just says the word break instead of doing a break.
When addind <speak> before and </speak> after the text with a <break Alexa just says the part before break and not part after break.

Doesn´t work:
echo_TTS.sendCommand('Dies ist <break> ein Test.')

Stops at the break:
echo_TTS.sendCommand('<speak>Dies ist <break> ein Test.</speak>')

echo_TTS.sendCommand('<speak>Dies ist <break/> ein Test.</speak>')

Some tags need to be closed directly with a /> at the end.
This isn´t clearly described in the Amazon docs.

Some things like <amazon:effect name=”whispered”></amazon:effect> doesn´t work at all.

This works for me:
<speak>I want to tell you a secret.<amazon:effect name="whispered">I am not a real human.</amazon:effect>.Can you believe it?</speak>

Information Request:

  1. Please give me feedback on which amazon domain the SSML works with the binding (Because the call in the alexa app was introduced in weeks after, so maybe it works not on all domains yet) is the only one tested.

  2. It would be nice if one with a lot of echos test, if a SSML call have the same problems for many multiple calls at the same time as it was the case for plain text.

Thank you for testing!

Thank you for integrating the timer and alarm channels. I don’t want to be impertinent, but I miss one thing. The Music Alarm. So, if you are woken up with music. Unfortunately, this is not intercepted by the Next Alarm Channel.

Here’s another reference for using SSML with short example audio clips. Also look toward the bottom for the speechcon’s, select your region, and you will get a list of all with example audio. The first in the list is “abracadabra” maybe the kids will like it.:laughing:

How to use example:

    Here is an example of a speechcon. 
    <say-as interpret-as="interjection">abracadabra!</say-as>.

    I think were gonna have fun with this. 
    <say-as interpret-as="interjection">bada bing bada boom!</say-as>.

Great work @michi

    I think this is 
    <say-as interpret-as="interjection">dynomite!</say-as>, thanks Michael.
1 Like

Hi @michi, the SSML is fantastic! I’ve been hoping you would add this feature since I heard of it.

I tested with my group of 12 echos (in the US) and see the same issue that we’ve been having with plain text. The following message repeats several times corresponding to random devices that don’t play after any given command.

2019-01-12 09:07:34.554 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.handleCommand()' on 'org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler@1ff50d0': POST url '' failed: Bad Request
org.openhab.binding.amazonechocontrol.internal.HttpException: POST url '' failed: Bad Request
	at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequest( ~[?:?]
	at org.openhab.binding.amazonechocontrol.internal.Connection.executeSequenceNode( ~[?:?]
	at org.openhab.binding.amazonechocontrol.internal.Connection.executeSequenceCommand( ~[?:?]
	at org.openhab.binding.amazonechocontrol.internal.Connection.executeSequenceCommandWithVolume( ~[?:?]
	at org.openhab.binding.amazonechocontrol.internal.Connection.sendAnnouncement( ~[?:?]
	at org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler.startTextToSpeech( ~[?:?]
	at org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler.handleCommand( ~[?:?]
	at sun.reflect.GeneratedMethodAccessor27086.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke( ~[?:?]
	at java.lang.reflect.Method.invoke( ~[?:?]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect( [102:org.eclipse.smarthome.core:]
	at org.eclipse.smarthome.core.internal.common.InvocationHandlerSync.invoke( [102:org.eclipse.smarthome.core:]
	at com.sun.proxy.$Proxy194.handleCommand(Unknown Source) [265:org.openhab.binding.amazonechocontrol:2.5.0.Beta_02]
	at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand( [109:org.eclipse.smarthome.core.thing:]
	at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem( [109:org.eclipse.smarthome.core.thing:]
	at sun.reflect.GeneratedMethodAccessor174.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke( ~[?:?]
	at java.lang.reflect.Method.invoke( ~[?:?]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect( [102:org.eclipse.smarthome.core:]
	at [102:org.eclipse.smarthome.core:]
	at [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker( [?:?]
	at java.util.concurrent.ThreadPoolExecutor$ [?:?]
	at [?:?]

This is an interesting little quirk… On the Echo show it displays the text command:

This does not happen with the plain text.

I keep seeing discussions about calling a bunch of echo’s at once with the same message. I haven’t figure out how to do this w/o writing a rule that has 1 echo - one after another - saying the same thing.

Can you provide a rule example that calls all 12 echo’s at the same time to send the same message? I also have 12 echo’s (US) and I’m very interested in this rule.

Best, Jay

Thank you for the information, I think I have to implement a queue for this. But it’s a lot of work, so do not await in the next days.

This is a simple issue. I have to remove the xml tokens for the display json element.

@jwiseman: It would be nice, If you could test one more thing, the new api calls needs the customerId in two places and I’am not sure if they are both the account customer id or device customer id. Could you test an SSML text with one of your echos with the other owner?

Oh, thank you for this hint, I have not seen yet, that there is another alarmType for this. I will provide an additional channel for this is the next version.

1 Like