Release Candidate and Support: Amazon Echo Control Binding

I answered on @Kfm as he said that only one out of three “echos” perform the TTS.
As he didn´t mentioned which one is an real echo and which one is a sonos i recommend to wait a second between multiple TTS commands.

I don´t have an sonos but this limitation seems to apply to anything controlled by this binding.
@michi do you know something about issues when sending to many commands through the binding without a pause?

My next steps would be:

  • Build an dummy switch that can be triggered through the sitemap
  • Write a simple rule that sends an TTS to one speaker
  • Trigger the switch and hear if the speaker says the TTS text
  • Change the speaker and repeat

As i haven´t found any info about kfm´s setup i can only guess which of his three “echos” are sonos speakers.

kind regards
Michael

Hi @Bredmich, thanks for your reply.

Yes, @Kfm `s Post about his Sonos problem was very old, I answered him and he directly answered me and didn’t use the quote method. And then you answered and missed the Sonos part. Doesn’t matter, a lot of posts going on here. You tried to help, thanks for it!!! :slight_smile:

TTS is working fine, also if you send all three requests in a row or to a group w/o any problem. Just the Implementation from Sonos’s Alexa doesn’t handle TTS call’s. That was the problem we talked about. Also in my opinion it has nothing to do with the binding, its just Sonos Alexas implementation or restrictions from Amazon to use it on third party devices.

I thing @Kfm thought, you mean TTS is for Sonos not handled because of the three calls in a row. But that is not the case. It just doesn’t work because it’s a Sonos. And because of that only the real amazon echo is talking.

Happy new Year.
Greets Udo

I love this binding and use it also for controlling that my kids don’t listen to music after their bedtime.
As there is no general on/off-Channel I use the player channel to check whether an Echo plays music.What I am not able to check for is if there is a skill (like the many quiz skills available) being actively used. Is there a channel or a method to check, whether a given Echo is currently using a Skill?

No, because the trigger does not know about a routine in the alexa app. And anyway, you should see the last command in the channel. Have you tried to bind it to an GUI element, so that you can see what happen?

Currently it seems, the the user Information is not available. So I see no way to provide this as a channel

Does it depend on the device?

The binding trigger the preview of a routing, anything else is done in the amazon server or echo software. I also have no feedback, if the TTS is already finished. I currently think about the possibility to send a routing with a set volume command at the end. This will fire a notification to the binding, regardless if the volume was changed or not, and so this can be used as workaround. Then it would be possible to build a queue, but unfortunately this is a lot of work. So I do not know, if nor when this will be done.
Maybe there are some java programers here, who want help me?

I do not think, that this is possible. Could you check the alexa app, if you see the information somewhere? If so, it would be possible, otherwise not.

Yes i see the trigger and made a typo…
The rules have to look for lowercase and i typed one uppercase letter into the lookup :slight_smile:

Do you know where to contact Amazon about new features?

As i get a lot of errors in the openhab.log i think there´s atleast a feedback from the Amazon servers to the binding.
I´m going to do some tests and post the logs here.

kind regards
Michael

Sorry that I missed to get some clarification earlier.

I’m using 2 Sonos One, with one Sonos Beam and an Amazon dot in 3 different rooms.

In the meantime I can play notifications on all of this devices without any problem. I’m doing this by sending the voice Command to a group of speakers. This group contains all my Amazon and Sonos devices.

So the solution to play a notification on several devices at the same time by grouping them is working fine here.

Thanks for this great binding!

@michi
Here´s my test.

rule:

rule "Test"
when
	Item itmTestSwitch changed
then
	echoKueche_TTS.sendCommand('Test Küche')
	echoWohnen_TTS.sendCommand('Test Wohnzimmer')
	echoFlur_TTS.sendCommand('Test Flur')
	echoArbeit_TTS.sendCommand('Test Arbeitszimmer')
end

logfile:

2019-01-02 17:15:37.094 [vent.ItemStateChangedEvent] - itmTestSwitch changed from OFF to ON
2019-01-02 17:15:37.105 [ome.event.ItemCommandEvent] - Item 'echoKueche_TTS' received command Test Küche
2019-01-02 17:15:37.134 [ome.event.ItemCommandEvent] - Item 'echoWohnen_TTS' received command Test Wohnzimmer
2019-01-02 17:15:37.142 [ome.event.ItemCommandEvent] - Item 'echoFlur_TTS' received command Test Flur
2019-01-02 17:15:37.158 [ome.event.ItemCommandEvent] - Item 'echoArbeit_TTS' received command Test Arbeitszimmer
2019-01-02 17:15:37.164 [vent.ItemStateChangedEvent] - echoKueche_TTS changed from  to Test Küche
2019-01-02 17:15:37.173 [vent.ItemStateChangedEvent] - echoWohnen_TTS changed from  to Test Wohnzimmer
2019-01-02 17:15:37.200 [vent.ItemStateChangedEvent] - echoFlur_TTS changed from  to Test Flur
2019-01-02 17:15:37.202 [vent.ItemStateChangedEvent] - echoArbeit_TTS changed from  to Test Arbeitszimmer
==> /var/log/openhab2/openhab.log <==
2019-01-02 17:15:38.384 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.handleCommand()' on 'org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler@1a506d3': POST url 'https://alexa.amazon.de/api/behaviors/preview' failed: Bad Request
org.openhab.binding.amazonechocontrol.internal.HttpException: POST url 'https://alexa.amazon.de/api/behaviors/preview' failed: Bad Request
	at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequest(Connection.java:549) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.Connection.executeSequenceNode(Connection.java:1067) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.Connection.executeSequenceCommand(Connection.java:1052) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.Connection.textToSpeech(Connection.java:1043) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler.startTextToSpeech(EchoHandler.java:640) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler.handleCommand(EchoHandler.java:527) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at sun.reflect.GeneratedMethodAccessor149.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:153) [101:org.eclipse.smarthome.core:0.10.0.oh230]
	at org.eclipse.smarthome.core.internal.common.InvocationHandlerSync.invoke(InvocationHandlerSync.java:59) [101:org.eclipse.smarthome.core:0.10.0.oh230]
	at com.sun.proxy.$Proxy176.handleCommand(Unknown Source) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java:75) [108:org.eclipse.smarthome.core.thing:0.10.0.oh230]
	at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem(SystemDefaultProfile.java:49) [108:org.eclipse.smarthome.core.thing:0.10.0.oh230]
	at sun.reflect.GeneratedMethodAccessor148.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:153) [101:org.eclipse.smarthome.core:0.10.0.oh230]
	at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:53) [101:org.eclipse.smarthome.core:0.10.0.oh230]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
	at java.lang.Thread.run(Thread.java:748) [?:?]
2019-01-02 17:15:38.591 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.handleCommand()' on 'org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler@506fc4': POST url 'https://alexa.amazon.de/api/behaviors/preview' failed: Bad Request
org.openhab.binding.amazonechocontrol.internal.HttpException: POST url 'https://alexa.amazon.de/api/behaviors/preview' failed: Bad Request
	at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequest(Connection.java:549) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.Connection.executeSequenceNode(Connection.java:1067) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.Connection.executeSequenceCommand(Connection.java:1052) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.Connection.textToSpeech(Connection.java:1043) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler.startTextToSpeech(EchoHandler.java:640) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler.handleCommand(EchoHandler.java:527) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at sun.reflect.GeneratedMethodAccessor149.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:153) [101:org.eclipse.smarthome.core:0.10.0.oh230]
	at org.eclipse.smarthome.core.internal.common.InvocationHandlerSync.invoke(InvocationHandlerSync.java:59) [101:org.eclipse.smarthome.core:0.10.0.oh230]
	at com.sun.proxy.$Proxy176.handleCommand(Unknown Source) [252:org.openhab.binding.amazonechocontrol:2.4.0.201812011454]
	at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java:75) [108:org.eclipse.smarthome.core.thing:0.10.0.oh230]
	at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem(SystemDefaultProfile.java:49) [108:org.eclipse.smarthome.core.thing:0.10.0.oh230]
	at sun.reflect.GeneratedMethodAccessor148.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:153) [101:org.eclipse.smarthome.core:0.10.0.oh230]
	at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:53) [101:org.eclipse.smarthome.core:0.10.0.oh230]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
	at java.lang.Thread.run(Thread.java:748) [?:?]
==> /var/log/openhab2/events.log <==
2019-01-02 17:15:39.724 [vent.ItemStateChangedEvent] - echoArbeit_TTS changed from Test Arbeitszimmer to 
2019-01-02 17:15:39.792 [vent.ItemStateChangedEvent] - echoFlur_TTS changed from Test Flur to 

This is the reason i´m using Thread::sleep(1000) between multiple Commands or try to use groups instead.

kind regards
Michael

Have you tried using a timer instead of thread sleep?

Example:

rule "Test"
when
	Item itmTestSwitch changed
then
	echoKueche_TTS.sendCommand('Test Küche')
	createTimer(now.plusSeconds(1))
	echoWohnen_TTS.sendCommand('Test Wohnzimmer')
	createTimer(now.plusSeconds(1))
	echoFlur_TTS.sendCommand('Test Flur')
	createTimer(now.plusSeconds(1))
	echoArbeit_TTS.sendCommand('Test Arbeitszimmer')
end

EDIT:
I forgot to add the lambda part to this example,:roll_eyes: thanks to @scottk for posting below the correct way. I would edit the rule but I think Scott has it covered here Released: Openhab2 Amazon Echo Control Binding (controlling alexa from openhab2)

I don´t understand why i should do this.
It´s still a workaround and doesn´t matter if i use a timer or Thread::sleep.

It´s working with Thread::sleep but not without, that´s the point

kind regards
Michael

For why it’s a bad idea, It’s worth reading this:

1 Like

Thanks for the link Scott and H102 for the hint!
I´m currently just using Thread::sleep in small Alexa rules that needs a pause between multiple commands.
It´s still a good idea to change this from sleep to timers.

Anyway it´s just workaround because the Amazon servers have trouble with too many commands :slight_smile:

kind regards
Michael

See the link that @scottk provided above. Thanks for that Scott.:+1:

I have no idea how many rules you have or how often they run but if your using thread sleep for something like TTS I hope it’s not many and not often.:wink:

I just had a look and only three out of 35 rules use Thread::sleep while only two are using a value greater 500ms.
Just to understand the timer…
In your example the timer waits one second before executing the next TTS, basically the same as a Thread::sleep(1000).
But the timer will terminate the rule thread for one second and then create another thread to run the rest of the rule?
I just want to understand what´s more “stress” for the system.
Work with one thread that´s in use for atleast 5 seconds or use atleast 4 threads that are only used for one or two seconds.

And things inside the timer will be executed after the timer is done?
Example, the TTS will be send 5 seconds after the rule started:

rule "Test"
when
	Item itmTestSwitch changed
then
        createTimer(now.plusSeconds(5),  [ |
	   echoKueche_TTS.sendCommand('Test Küche')
        ])
end

kind regards
Michael

Actually, the createTimer() examples won’t work as desired, they spin off threads that come from a different thread pool from that used by Thread::sleep() and immediately return, which is to say there is effectively no delay to the calling thread when createTimer() is called. Your rule could actually be coded something like this:

rule "Test"
when
    Item itmTestSwitch changed
then
    echoKueche_TTS.sendCommand('Test Küche')
    createTimer(now.plusSeconds(1), [|
        echoWohnen_TTS.sendCommand('Test Wohnzimmer')
        createTimer(now.plusSeconds(1), [|
            echoFlur_TTS.sendCommand('Test Flur')
            createTimer(now.plusSeconds(1), [|
                echoArbeit_TTS.sendCommand('Test Arbeitszimmer')
            ])
        ])
    ])
end

Warning, the above may have typos and is untested, but should serve to illustrate the use of createTimer() in your rule.

[Updated to correct missing right paren at each plusSeconds() method call. Thanks for spotting that, @H102! ]

2 Likes

@scottk I just realized that I left out the [ | lambda part on my post above.:roll_eyes: I edited the post to point to yours.:wink:

1 Like

Hi @schaze ,

Could you check it with the beta 2.5 (1). It should fix this problem.

Best,
Michael

No, there is not public API to control the echo. The binding is build on the API calls done from the alexa web site.