hello , since few days all Things have changed their ID and things a very frequently going offline.
Am I alone in this ?
The issue is the same treated in this discussion:
https://community.openhab.org/t/amazon-amazonechocontrol-smarthomedevice-things-in-unknown-state/110156/8
I seem to be having a similar error too, on OpenHab 2.5.12 and that version of the Amazon Echo Control Binding. Have you figured out a solution to the issue? It seemed to have started maybe two weeks ago, but I haven’t made any recent changes to my OpenHab configuration. Actually, I was on 2.5.9 for a while, then upgraded to 2.5.12 today to see if it would fix the issue, but no luck.
13:20:57.929 [ERROR] [rnal.common.AbstractInvocationHandler] - An error occurred while calling method ‘ThingHandler.handleCommand()’ on ‘org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler@2c6275’: GET url ‘https://alexa.amazon.com/api/behaviors/automations?limit=2000’ failed: Not Found
org.openhab.binding.amazonechocontrol.internal.HttpException: GET url ‘https://alexa.amazon.com/api/behaviors/automations?limit=2000’ failed: Not Found
at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequest(Connection.java:691) ~[?:?]
at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequestAndReturnString(Connection.java:555) ~[?:?]
at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequestAndReturnString(Connection.java:550) ~[?:?]
at org.openhab.binding.amazonechocontrol.internal.Connection.getRoutines(Connection.java:1840) ~[?:?]
at org.openhab.binding.amazonechocontrol.internal.Connection.startRoutine(Connection.java:1770) ~[?:?]
at org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler.handleCommand(EchoHandler.java:640) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_251]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_251]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_251]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_251]
at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
at org.eclipse.smarthome.core.internal.common.InvocationHandlerSync.invoke(InvocationHandlerSync.java:59) [bundleFile:?]
at com.sun.proxy.$Proxy164.handleCommand(Unknown Source) [?:?]
at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java:74) [bundleFile:?]
at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem(SystemDefaultProfile.java:48) [bundleFile:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_251]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_251]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_251]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_251]
at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:52) [bundleFile:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_251]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_251]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_251]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_251]
You have a different issue that is already fixed.
Yes, I think it’s a different issue. I manually updated to the 2.5.13 echo control and it seems to be working now.
I’m getting the same error as @jlekhter with the DateTimeParseException
I’m using openHAB 2.5.7, and this continues with the 2.5.13 Binding that I’ve just updated to (which seems to have fixed the routines issue!
)
But I must say a huge thank you for writing this Binding, it’s become a core part of my home automation!
I‘ll check the other error.
Can you please tell me from what version that stacktrace is? Otherwise it‘s a bit difficult to find it.
Thank you @J-N-K
Im on 2,.5.12 snapshot of the binding now but 2,5.3 version on OpenHAB.
Is there another module version that might be helpful?
Thanks again,
Jerry
Last fix for 2.5.x from me.
Hi Jan where can we download the latest for 2.4 or 2.5?
Thank you! This fix was requested by the original developer of the binding @michi
Here’s the direct down JAR URL → https://janessa.me/esh/org.openhab.binding.amazonechocontrol-2.5.13-SNAPSHOT.jar
The actual 2.5.x build process on the Echo binding for bug fixes has been broken and nobody is addressing it so we have to go to 3rd party URL to get the fix now.
PR-openHAB-Addons #2437 [Jenkins]
PR-openHAB-Addons #2512 [Jenkins]
Best, Jay
Thanks jwiseman, I take it no one ever fixed the websockets fail errors ![]()
15:16:12.909 [WARN ] [ntrol.internal.handler.AccountHandler] - handling of websockets fails
org.openhab.binding.amazonechocontrol.internal.HttpException: GET url ‘https://alexa.amazon.com.au/api/activities?startTime=1612239360623&size=10&offset=1’ failed: Bad Request
at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequest(Connection.java:691) ~[272:org.openhab.binding.amazonechocontrol:2.5.13.202101281939]
at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequestAndReturnString(Connection.java:555) ~[272:org.openhab.binding.amazonechocontrol:2.5.13.202101281939]
at org.openhab.binding.amazonechocontrol.internal.Connection.makeRequestAndReturnString(Connection.java:550) ~[272:org.openhab.binding.amazonechocontrol:2.5.13.202101281939]
at org.openhab.binding.amazonechocontrol.internal.Connection.getActivities(Connection.java:1099) ~[272:org.openhab.binding.amazonechocontrol:2.5.13.202101281939]
at org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler.handlePushActivity(AccountHandler.java:816) ~[272:org.openhab.binding.amazonechocontrol:2.5.13.202101281939]
at org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler.handleWebsocketCommand(AccountHandler.java:760) ~[272:org.openhab.binding.amazonechocontrol:2.5.13.202101281939]
at org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler.webSocketCommandReceived(AccountHandler.java:747) [272:org.openhab.binding.amazonechocontrol:2.5.13.202101281939]
at org.openhab.binding.amazonechocontrol.internal.WebSocketConnection$AmazonEchoControlWebSocket.onWebSocketBinary(WebSocketConnection.java:415) [272:org.openhab.binding.amazonechocontrol:2.5.13.202101281939]
at sun.reflect.GeneratedMethodAccessor1997.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
at org.eclipse.jetty.websocket.common.events.annotated.CallableMethod.call(CallableMethod.java:71) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.events.annotated.OptionalSessionCallableMethod.call(OptionalSessionCallableMethod.java:72) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.events.JettyAnnotatedEventDriver.onBinaryMessage(JettyAnnotatedEventDriver.java:124) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.message.SimpleBinaryMessage.messageComplete(SimpleBinaryMessage.java:68) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.events.AbstractEventDriver.appendMessage(AbstractEventDriver.java:66) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.events.JettyAnnotatedEventDriver.onBinaryFrame(JettyAnnotatedEventDriver.java:116) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.events.AbstractEventDriver.incomingFrame(AbstractEventDriver.java:157) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.WebSocketSession.incomingFrame(WebSocketSession.java:476) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.extensions.ExtensionStack.incomingFrame(ExtensionStack.java:220) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.Parser.notifyFrame(Parser.java:220) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.Parser.parse(Parser.java:245) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.readParse(AbstractWebSocketConnection.java:560) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:391) [92:org.eclipse.jetty.websocket.common:9.4.11.v20180605]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
@jwiseman would you happen to know where I could get the latest nightly build for this binding?
I’m looking for the fix right after the one completed by @J-N-K
Thanks,
Jerry
It doesn’t exist, the 2.5.x build process is broken. I asked @Kai about it w/o a response yet.
I agree its frustrating.
Sorry, Jay
ok thanks – I broke down and installed everything I needed to compile the binding. I now have the latest copy of this binding in my environment. It seems like its working as expected and the issue I had with parsing DateTime is now fixed.
If anyone needs the binding, let me know where to put it and I’m happy to send it to you.
Thank you,
Jerry
I’d like the latest copy when you can.
Thanks! Jay
ok – here is a public dropbox link
BTW – I have rules in place to allow you to say things like “turn on the (device)” in any room in the house and have alexa turn on the correct device. Alexa only turns on the lights natively through the app, but this allows you to have generic names for lamps, TVs, fans, etc. Its a lot more natural than having to remember the specific name of the device.
If anyone is interested, I can post my configs.
Even if you feel like on “Groundhog Day”: i raise my hand up!
Hopefully you don’t mind to post your configs again after they 've got lost in one of these parallel digital universes. ![]()
very strange about what happened to the post – here it is again.
Here is the item file. For each device you want to control you will need to create a Generic_Item and Timer Item. The format of the items are used in the rules files to control the real item in the correct room. Also, your Alexa will need to be configured to turn on/off this Generic_Item whenever you want to turn on the appropriate item. I do this through ha-bridge which is HUE emulation app but you can certainly use openHab for this configuration.
In the future, if you ever need to add another device you want to control, you simply create these two items and get Alexa to discover the generic item and everything will simply work. No other changes are required.
group_items.items
Group:DateTime:LATEST gLastCommandTime
// Group:DateTime:MAX gMaxCommandTime
Group gLastPhrase
Group gGenericDevices
Group:Switch:OR(ON, OFF) gGenericTimers
Switch Generic_Fan (gGenericDevices)
Switch TimerGeneric_Fan (gGenericTimers) {expire="5S, command=OFF"}
Switch Generic_Lamp (gGenericDevices)
Switch TimerGeneric_Lamp (gGenericTimers) {expire="5S, command=OFF"}
Switch Generic_LedLight (gGenericDevices)
Switch TimerGeneric_LedLight (gGenericTimers) {expire="5S, command=OFF"}
Switch Generic_PlayShanana (gGenericDevices)
Switch TimerGeneric_PlayShanana (gGenericTimers) {expire="5S, command=OFF"}
Dimmer Generic_Heat (gGenericDevices)
Switch TimerGeneric_Heat (gGenericTimers) {expire="5S, command=OFF"}
Dimmer Generic_Air (gGenericDevices)
Switch TimerGeneric_Air (gGenericTimers) {expire="5S, command=OFF"}
Each Alexa that you own has to have the lastvoice command be a member of the gLastPhrase group. And a DateTime item has to be created to store the last time this alexa received a command. The name of the item is used in the rules file so stick to the format (or update the rules). I think I missed this the last time I posted. Here is an example from my Kitchen Alexa:
String Echo_Kitchen_LastVoiceCommand "Last voice command" (Alexa_Kitchen, gLastPhrase) {channel="amazonechocontrol:echo:account1:echoshow1:lastVoiceCommand"}
// Time of Last voice command
DateTime Echo_Kitchen_LastVoiceCommandTime (gLastCommandTime)
Because I copied the demo config and the configs from this binding when I first created my items the room names are not entirely consistent. Therefore, I created a map file to find the correct room the Alexa is in and get to the correct device. Here is the map file I use. You will most likely need something similar to find the right room and the correct device to activate.
echo-to-room.map
Echo_Family_Room = FF_FamilyRoom
Echo_Living_Room = FF_LivingRoom
Echo_Dinning_Room = FF_Dining
Echo_Office = FF_Office
Echo_Guest_Room = FF_GuestRoom
Echo_EFL_Room = FF_EmiliaSRoom
Echo_ACL_Room = F2_AmandaSRoom
Echo_Kitchen = FF_Kitchen
Echo_SEL_Room = F2_SophieSRoom
Echo_MasterBed_Room = F2_MasterBedroom
=UNDEF
So if I say turn on the fan in the Kitchen, Alexa will turn on the Generic_Fan item and the rules will find that voice command came from the Kitchen Alexa. Once the rules know it was the Kitchen, they will know that Echo_Kitchen is mapped to FF_Kitchen and will ultimately turn on the FF_Kitchen_Fan
The part after the underscore in the Generic_Item identifies the device that will be turned on/off. I parse out the name of the item and look for it in the phrase. For some of my items the item name doesnt match the phrase that I say to Alexa. For those items I have another map file that maps the item name to the phrase I use with Alexa. For instance, I have an item called PlayShanana but I say “sophies bedtime music” to Alexa. If you have those types of situations, you can use the following map file to ensure the correct item maps to the phrase you use with Alexa. If you dont have this situation, you can ignore this file and the code in the rules that reference it.
item-utterance.map
LedLight = l. e. d.
PlayShanana = sophie's bedtime music
= UNDEF
Once you have the items and maps setup, all you need are the rules that make this work. There shouldnt be any changes needed here.
echo.rules
import org.eclipse.smarthome.model.script.ScriptServiceUtil
rule "Get Last Echo Command TimeStamp"
when
Member of gLastPhrase changed
then
val String itemName = triggeringItem.name + "Time"
val currentTime = new DateTimeType()
postUpdate(itemName, currentTime.toString )
// if the timer is on, we're waiting for the utterance to catch up to the switch
gGenericTimers.members.filter( item | item.state == ON ).forEach[ item |
// var GenericItem deviceItem = null
item.postUpdate(OFF) // cancel the timer
val deviceItem = ScriptServiceUtil.getItemRegistry.getItem("Generic_" + item.name.split('_').get(1)) as GenericItem //by convention the item is xxxTimer _device
logInfo("Amazon Echo","Sending a Command to {} with value {} to trigger the rule again", deviceItem.name, deviceItem.state )
deviceItem.sendCommand(deviceItem.state.toString) //retrigger my device rule since the phrase just caught up
]
end
rule "find alexa that changed device state"
when Member of gGenericDevices received command
then
val String device = triggeringItem.name.split('_').get(1)
val String tmpMapping = transform("MAP","item-utterance.map", device)
val String deviceUtterance = if (tmpMapping == "UNDEF") device else tmpMapping
// find the room that spoke most recently, but check only the ones where the word 'turn', 'set' and the triggering device is in the phrase
val turnList = gLastPhrase.members.filter( i | i.state.toString.contains(deviceUtterance.toLowerCase) && (i.state.toString.contains("turn") || i.state.toString.contains("set")))
val mostRecentItem = turnList.sortBy[ i | (ScriptServiceUtil.getItemRegistry.getItem(i.name + "Time").state as DateTimeType).zonedDateTime.toInstant.toEpochMilli ].last
val Number maxEpoch = if (mostRecentItem !== null) (ScriptServiceUtil.getItemRegistry.getItem(mostRecentItem.name + "Time").state as DateTimeType).zonedDateTime.toInstant.toEpochMilli else 0
val Number timeNow = now.millis
// logInfo ("Amazon Echo", "The most recent echo utterance happened in {} at {}", mostRecentItem.name, maxEpoch)
// logInfo ("Amazon Echo", "The time now is {} and the time difference is {}", timeNow, (maxEpoch + 5000 - timeNow))
if ((maxEpoch + 5000) > timeNow) { //the oldest voice command is less than 5s old
val String maxItem = mostRecentItem.name.replace("_LastVoiceCommand","")
var String commandDevice = transform("MAP","echo-to-room.map",maxItem) + "_" + device
// a device item doesnt exist
if (ScriptServiceUtil.getItemRegistry.getItems(commandDevice).isEmpty) {
logInfo("Amazon Echo", "No such device: {}; Checking thermostat", commandDevice)
// check to see if a tstat item was changed
val String tstatDevice = transform("MAP","echo-to-thermostat.map", maxItem) + "_" + device
if (ScriptServiceUtil.getItemRegistry.getItems(tstatDevice).isEmpty) {
logInfo("Amazon Echo", "No such thermostat: {}", tstatDevice)
ScriptServiceUtil.getItemRegistry.getItem(maxItem +"_TTS").sendCommand("This room does not have a controllable " + deviceUtterance.toLowerCase)
return;
}
// found a thermostat
commandDevice = tstatDevice
}
// logInfo("Amazon Echo", "Device: {} , ReceivedCommand: {}, FinalCommand: {}", commandDevice, receivedCommand, finalCommand)
sendCommand(commandDevice, receivedCommand.toString)
}
else {
// state change happened first or last voice command happened too long ago or someone used controller to change status
// start a timer to let the voice utterance happen, if timer finishes before utterance the command was too far in the past
sendCommand("TimerGeneric_" + device, "ON")
// logInfo("Amazon Echo", "Starting Timer on {} to see if the utterance catches up", device)
}
end
After getting this working for fans, lamps, leds, I decided I wanted to be able to say turn on the heat or turn off the air from anywhere in the house and the correct thermostat would be set. In order to do that I needed to add a few items and configurations. This shows you what I added, but feel free to not use and comment out the parts that have to do with tstats in the rules file.
echo-to-thermostat.map
Echo_Family_Room = FF_FR_Tstat
Echo_Living_Room = FF_FR_Tstat
Echo_Dinning_Room = FF_FR_Tstat
Echo_Office = FF_Hall_Tstat
Echo_Guest_Room = FF_Hall_Tstat
Echo_EFL_Room = FF_Hall_Tstat
Echo_ACL_Room = F2_Hall_Tstat
Echo_Kitchen = FF_FR_Tstat
Echo_SEL_Room = F2_Hall_Tstat
Echo_MasterBed_Room = F2_Hall_Tstat
=UNDEF
This says that when I’m in a some room, I want to control the specific thermostat.
I also created an Air and Heat Dimmer item for each thermostat as such:
Dimmer FF_Hall_Tstat_Air (gTstatSwitch)
Dimmer FF_Hall_Tstat_Heat (gTstatSwitch)
Number FF_Hall_Tstat_HeatSetPoint "Heat [%d °F]" <heating> (FF_Hall_Tstat) {channel="omnilink:thermostat:2c8fef01:3:heat_setpoint"}
Number FF_Hall_Tstat_CoolSetPoint "Cool [%d °F]" <snow> (FF_Hall_Tstat) {channel="omnilink:thermostat:2c8fef01:3:cool_setpoint"}
Number FF_Hall_Tstat_SystemMode "Mode [%s]" <airconditioner> (FF_Hall_Tstat) {channel="omnilink:thermostat:2c8fef01:3:system_mode"}
Do the same for each thermostat and add these items to the group item gTstatSwitch. I use a Dimmer so that I can set the temperature to a specific value.
These items get turned on/off or set to a specific value from the Generic_Air or Generic_Heat item after you tell Alexa to do something like set the heat to 70. Or turn the heat off.
I have Omni Thermostats, but the code should be similar to any other thermostat. The rules determine if we’re calling for air or heat, then set the cool set point or heat set point appropriately based on how my thermostats work. This is a rule file you will most likely need to modify based on your thermostats.
import org.eclipse.smarthome.model.script.ScriptServiceUtil
rule "air or heat turned on or off"
when
Member of gTstatSwitch received command
then
var String device = triggeringItem.name.split('_').get(3) // contains "Air" or "Heat"
var String itemPrefixName = triggeringItem.name.replace("_" + device,"") // tstat prefix
var Number multiplier = 1
var Number newTemp = triggeringItem.state as DecimalType
var String itemSuffix = ""
if (receivedCommand.toString == "ON" || receivedCommand.toString == "100") multiplier = 1
else multiplier = -1
var Number currentTemp = (ScriptServiceUtil.getItemRegistry.getItem(itemPrefixName +"_Temperature").state as DecimalType).intValue
var Number heatSPTemp = (ScriptServiceUtil.getItemRegistry.getItem(itemPrefixName +"_HeatSetPoint").state as DecimalType).intValue
var Number coolSPTemp = (ScriptServiceUtil.getItemRegistry.getItem(itemPrefixName +"_CoolSetPoint").state as DecimalType).intValue
var Number currentState = ScriptServiceUtil.getItemRegistry.getItem(itemPrefixName +"_SystemMode").state as DecimalType
if (device == "Heat") {
itemSuffix = "_HeatSetPoint"
if (newTemp == 0 || newTemp == 100) {
if (heatSPTemp > currentTemp) currentTemp = heatSPTemp
newTemp = (currentTemp + (2.75 * multiplier)).intValue
}
}
else {
itemSuffix = "_CoolSetPoint"
if (newTemp == 0 || newTemp == 100 ) {
if (coolSPTemp > currentTemp) currentTemp = coolSPTemp
newTemp = (currentTemp - (2.75 * multiplier)).intValue
}
}
if (currentState != 3)
ScriptServiceUtil.getItemRegistry.getItem(itemPrefixName +"_SystemMode").sendCommand(3)
logInfo("TStat Rules", "currentTemp: {} , newTemp: {}, multiplier: {}", currentTemp, newTemp, multiplier)
ScriptServiceUtil.getItemRegistry.getItem(itemPrefixName + itemSuffix).sendCommand(newTemp)
end
Like I said in my last post, I’m happy to help explain any of the code or logic so that you can get your house working like this. This has really been a huge improvement to what Alexa can do on its own.
Now that this is all working in OH 2.5.x, it looks like I need to start thinking about porting it to OH3.
Best wishes,
Jerry