Amazon Echo SmartJ Binding Last Voice Command not working anymore

italy don’t work anymore with openhab 4

I hope it magically starts working again for me too! So far no dice :frowning: UK

But what I don’t understand: If Amazon wanted to stop this functionality by intention, then why is the corresponding functionality of home assistant still working? I guess there it’s called last_called_summary and I can’t see any actual discussions that it’s failing.

For the moment I changed my rules to get triggered by dummy-items which are switched by the alexa command. It works but until now I haven’t found a way that openhab knows from which echo it got the command so it can respond to the same.
Does anybody have a workaround for this?

I remembered playing with wemos and alexa at the end of 2019 then disconnected because openhab was more responsive, since last voice comand is no longer seen by openhab I tried to turn wemos back on and it works, on wemos I only have 6 commands, and they work but they are not as fast as last voice comand I’m not very experienced but I modified this a bit for my needs
https://www.instructables.com/Alexa-Controlled-Solenoid-Using-WEMO-D1-Mini/
from what i understand it is because belkin simulation code still works

At least ioBroker is also affected

I have OH 3.4 and the solution I have given it for now has been the following:

You can use the api:
http://openhab:8080/amazonechocontrol/account1/PROXY/api/activities?startTime=&size=1&offset=1
which with size=1 returns the last command in JSON. In that command appears the serial number of the ECHO. Using a rule you extract that serial number and you know which ECHO has been used.
Through the Alexa app I created a routine (voice command: “Alexa, power”) that activates an OH item (Item power3_value_item_tts) and I use that item to trigger the “Alexa LastVoiceCommand” rule. The whole process is very fast, since when the item has changed it is because Alexa has already interpreted the command we have given it by voice:

rule “Alexa LastVoiceCommand”
when
Item potencia3_value_item_tts received command ON
then
val String alexa_LastVoiceCommand = sendHttpGetRequest(“http://192.168.1.19:8080/amazonechocontrol/account1/PROXY/api/activities?startTime=&size=1&offset=1”)
val serialNumber_alexa_LastVoiceCommand = transform(“JSONPATH”,“$.activities[0]sourceDeviceIds[0]serialNumber”,alexa_LastVoiceCommand)
logInfo("Echo, serialNumber: ",serialNumber_alexa_LastVoiceCommand)

< Enter your code here once you know which Echo you are interacting from >
potencia3_value_item_tts.postUpdate(OFF)
end

I have added the item in *.items so that it will recognize it as a switch device in the Alexa APP:

Switch potencia3_value_item_tts “Potencia canal 3” { alexa=“PowerController.powerState” }

1 Like

If this works as described, then the binding could call this url everytime it reaches back to the api and populate the correct echo with last voice command.

The only issue i see is a timing issue on how often the binding calls the api and how many echos received a command within that period. I could easily see it missing updates.

@J-N-K , thoughts?

That’s exactly why we triggered a similar call whenever the websocket reported an activity. In the past the websocket did so AFTER an activity (i.e. a command) was received by Alexa. Then it only reported an equalizer/volume change at the BEGINNING of an activity (that is why I added the 15s delay prior to the query and processed all received voice commands of the last 30s (keeping track of commands that have been processed before to avoid duplicates). Now also the equalizer/volume change reports seem to be missing.

However, the app still seems to be able to detect immediately when a voice command was detected, so most probably Amazon changed the protocols.

2 Likes

@Larsen: what kind of Echo do you have?

@All: mine is on a UK account, it doesn’t work either. Just to add to the list. Additionally I also had “dumb” routines in the Alexa app but it doesn’t help.
Example: when I say “Lights” → the only thing in the Alexa routine is say “Okay” to not to trigger a stupid response of “I don’t know that one”, and OH was handling the rest of it. Yet it doesn’t work anymore for a few weeks already, indeed since around the time I did the OH4->4.0.1->4.0.2 upgrade. I’m looking forward to any solution, will try the .kar later. Thanks for looking into it!

@Mat1: Great, that works! Thanks a lot. This way I could recover my old functionality.
I changed it to JavaScript and added the extraction of the Command. So if anybody is interested here is the code (see square brackets and comments to adjust to your needs). Let me know if things can be solved in a better way…

var lastCommand, serialNumber, echoName, echoMapping;
var HTTP = Java.type("org.openhab.core.model.script.actions.HTTP");
var url = "http://[yourIP]:8080/amazonechocontrol/[yourEchoBridgeName]/PROXY/api/activities?startTime=&size=1&offset=1";
var respJson = "" + HTTP.sendHttpGetRequest(url, 10000);

serialNumber = JSON.parse(respJson).activities[0].sourceDeviceIds[0].serialNumber
lastCommand  = JSON.parse(JSON.parse(respJson).activities[0].description).summary

// replace those with your Echo-IDs and Names. 
echoMapping = {'[serialOfEcho1]': '[NameOfEcho1]', '[serialOfEcho2]': '[NameOfEcho2]', '[serialOfEcho3]': '[NameOfEcho3]'};
echoName = String(echoMapping[serialNumber]) ;

// eliminate the alexa keyword
lastCommand = (lastCommand.toLowerCase()).replaceAll('alexa ','');

if (lastCommand == 'example command' || lastCommand == 'another command') {
...your code...
}
3 Likes

Please correct me if I’m not following the logic here. For now, we have a workaround (thanks @Mat1!) using a dummy routine and retrieving the last command via an API, but eventually this method in theory could be baked into the binding itself as the old method no longer works. Is that a possibility?

Also, does this workaround provide the device which received the command, as that’s crucial in my setup to do all sorts of things?

1 Like

yes, that’s already included.

but you have to enter the mapping of serial-IDs and thing-names as the API only returns the ID

1 Like

That was too early for me to report, now it has stopped for me as well. Last recognized command was 2023-08-30 late evening.

My LastVoiceCommand died also yesterday. The “special” version of the binding doesn’t work for me. So I implemented the workaround. It’s really nice and much better than nothing.
While testing, I recognized, that there is a problem with more than one amazon account. Only the first account which goes online works like expected. When the second account thing is started, I get this log entries:

2023-09-04 21:17:32.388 [WARN ] [trol.internal.handler.AccountHandler] - Failed to create account servlet
java.lang.IllegalStateException: ServletModel{id=ServletModel-76,name='org.smarthomej.binding.amazonechocontrol.internal.AccountServlet',alias='/amazonechocontrol/account2',urlPatterns=[/amazonechocontrol/account2/*],servlet=org.smarthomej.binding.amazonechocontrol.internal.AccountServlet@1f3696b,contexts=[{HS,OCM-69,default,/}]} can't be registered. ServletContextModel{id=ServletContextModel-2,contextPath='/'} already contains servlet named org.smarthomej.binding.amazonechocontrol.internal.AccountServlet: ServletModel{id=ServletModel-74,name='org.smarthomej.binding.amazonechocontrol.internal.AccountServlet',alias='/amazonechocontrol/account1',urlPatterns=[/amazonechocontrol/account1/*],servlet=org.smarthomej.binding.amazonechocontrol.internal.AccountServlet@1921684,contexts=[{HS,OCM-69,default,/}]}
	at org.smarthomej.binding.amazonechocontrol.internal.AccountServlet.<init>(AccountServlet.java:97) ~[?:?]
	at org.smarthomej.binding.amazonechocontrol.internal.handler.AccountHandler.initialize(AccountHandler.java:156) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
	at org.openhab.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:147) ~[?:?]
	at org.openhab.core.internal.common.Invocation.call(Invocation.java:52) ~[?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]

I tested this with the original, the “normal” snapshot and the snapshot from this thread. Always the same behavior.
@J-N-K You may have a look at it, but it is very less important.

Austria. Mine has died too now. openHAB 3.4.0

I was using lastVoiceCommand in a rule for more reliable room aware voice commands. It did work very well.

That is exactly what I did too… Dummy Alexa routines that just say OK to suppress Alexa’s dumb responses with OH then handling the command. It worked very good or I should say did work very good. I have not upgraded to OH4 yet!

A short information about what‘s going on: we found that the activity is no longer reported via websockets but an HTTP/2 stream. We still have some issues with getting this stream initiated in the correct way, but it looks not so bad.

The ugly news is: openHAB 3.4 does not bundle Jetty support for HTTP/2, so it could be that the „solution“ will only work on OH4.

8 Likes

Is it possible to just upgrade Jetty within OH 3.4 to a newer version?

Best, Jay

I figured I’d be better off just by checking my Echo through a bash script and post the result in OpenHAB - so there’s no need for an Alexa routine to trigger the whole thing. The only disadvantage (yet) is that if the same command is given twice after the other it doesn’t do anything. I’ll think about that, but it was just a quick and dirty fix for my problem so that Alexa at least listens (even though it doesn’t even speak anymore triggered from OH).
If you named the last voice command variable differently in your OpenHAB then replace Alexa_LastVoiceCommand with that.

Just copy-paste it and save it as a bash file eg. alexachecker.sh, make it executable.
Then you can start it inside a screen window so you can let it run in the background:
sudo screen -dmS alexa-checker /[your path]/alexachecker.sh

#!/bin/bash
a=0
previouscommand="startroutine"
while a==0; do
	variable=$(curl 'http://localhost:8080/amazonechocontrol/[your echos name]/PROXY/api/activities?startTime=&size=1&offset=1')
	command=$(echo $variable | tr "," "\n" | tr '{' ' ' | tr "}" " " | grep "summary" | sed 's/.*:\\//g;s/\\//g;s/\"//g')
	echo "Command: $command"
	if [[ $command != $previouscommand && $previouscommand != "startroutine" ]]; then
		echo $(date +%Y-%m-%d_%H:%M:%S)
		echo "POST TO OPENHAB"
		curl -m 2 -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "$command" "https://[your OpenHAB IP]:[your OpenHAB port]/rest/items/Alexa_LastVoiceCommand" -k --user [your OpenHAB username]:[your OpenHAB password]
		previouscommand=$command
	else
		if [[ $previouscommand == "startroutine" ]]; then
			previouscommand=$command
		fi
		sleep 10;
	fi

done

I know it’s far from a perfect solution but it works without the need to Alexa routines triggering anything on OpenHAB - until the guys much better in coding create a new binding for us. :slight_smile:

3 Likes

yes, that is a possibility, thank you!
For everybody failing to adapt this, the url is (at least for me) not “[your_echos_name]” but the account ID, that 10digit hexadecimal thing or how you have named your account.

1 Like