Alexa Smart Home Skill V3 is now live!

I am not sure to fully understand your question. I am not using any mapping in my example. Everything is based of the triggering voice command item name for the location and regex matching of its state for the fan power state.

Keep in mind, this example provides a workaround for categories that aren’t supported by the Alexa-enabled groups feature as of yet. For the ones that are supported, you should be able to call the device category (e.g. turn on the lights or turn off the TV) as long as you linked your echo device to the relevant group.

Ahh, I see now. I did not understand the transform statement, but now I see it. I have just enough programming skills to do a few simple things and I could not figure out how that was working.

I have 2 rooms with entertainment systems and I was thinking that I would have trouble addressing the TV, cable box, or other devices without getting interference between the rooms even though I have an echo in each room and have the devices assigned to that room. I will continue working on my setup and see how it works. I still think this is a great idea on how to handle some of the voice commands. I was actually thinking since I have all of my devices connected to OpenHab, that I could use a single virtual player device to receive the commands from Alexa and a rule to interpret and send the command to the currently operating device, but it would be helpful if I could identify which Alexa device is sending the command so I would only need a single set of rules for both rooms. I was thinking that this looked like it would be able to make that happen.

Thanks for the reply.

Steve

Now I think about it. Using a mapping file in place of a complex regex to get the proper state may not be that bad of any idea and probably easier to maintain.

val String FanPowerState = transform("MAP", "alexa_cmds_fan.map", triggeringItem.state.toString)

if (FanPowerState != "")
    sendCommand(Location + "FanPower", FanPowerState)

alexa_cmds_fan.map

turn\ off\ the\ fan=OFF
turn\ on\ the\ fan=ON
...

I did not realise that routines could solve that issue, good to know.
Thanks
Paul

So I have had a little play with the ‘alexa=“activity”’ now you have explained it, that makes it very interesting as a viable alternative to using routines.

I did try adding switch as an alternative to turn and it did not like it, spat out this error in the log

Cannot convert 'SWITCH' to a command type which item 'BR4_Heater' accepts: [OnOffType, RefreshType]

Is this an Amazon limitation?
As normally I can use switch or turn to control on/off devices.

I have converted eight routines across to “activitys” and think it is better way to go, I have made a single rule that deals with multiple devices, rather than a separate rule each that I used to use with exact matching. There are still many cases where I am going to keep the routine approach for now, but I will be looking through my long list of routines to see which can be converted.

Regards

Paul

You probably forgot to set your first regexp group as a lookahead instead it is capturing the value and returned as the result .

(?:power|switch|turn) (on|off) (?:the )?fan

As I mentioned above, I think using a mapping file may be easier in this case especially if you want to add all the different permutations.

Update

I went back to the drawing board as I felt my original rule wasn’t manageable on the long run and didn’t support all the various permutations. Also, having all the exact permutations in a mapping file wasn’t sustainable as well. I have posted the below tutorial to cover the changes I made.

1 Like

Awesome!
I am looking to sort something else out first but will certainly be updating my current approach to match your pattern. Great work. :slight_smile:
Thanks
Paul

I try to integrate my custom Thermostat.

This item config works:

String  Therm_Manual  "Modus überschrieben" <thermostat>      (Thermostat) {alexa="ThermostatController.thermostatMode" [OFF=0,HEAT=1,COOL=2,AUTO=3] }

But I need this:

String  Therm_Manual  "Modus überschrieben" <thermostat>      (Thermostat) {alexa="ThermostatController.thermostatMode" [OFF=OFF,HEAT=ON,AUTO=AUTO] }

and then get this error:

2019-08-25 23:50:10.582 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'thermostat.items' has errors, therefore ignoring it: [5,126]: Number expected.
[5,135]: Number expected.
[5,143]: Number expected.

My sitemap uses this values and works:

Selection   item=Therm_Manual mappings=[AUTO="automatisch", ON="Normalbetrieb", OFF="Absenkbetrieb"]

Is there an issue with the alexa skill or am I doing something wrong?

You need to make sure to quote the parameter setting string-typed values OFF="OFF",HEAT="ON",AUTO="AUTO".

Also, make sure that your Thermostat group is set as an endpoint alexa="Endpoint.Thermostat", if not already done.

While on the subject of thermostats, I have something like 8 rooms each with their own thermostat groups and sensors. There are two that will not work when I ask “Alexa, What is the temperature in the living room” the response returned is the living room does not support that.

If I ask the same question of the bedroom, 'Alexa, what is the temperature in the bedroom" she responds with “The bedroom temperature is 22.7 degrees”.

I am listing the different configuration elements for both of the example rooms in case someone can see a problem

ITEM

Group gTemperature																["Temperature"]
Group gLR_Temp
Group gBR1_Temp 
Group gLivingroomThermostat "Livingroom Thermostat" 		(chartpersist)  ["Thermostat"]
Group gBedroomThermostat	"Bedroom Thermostat" 			(chartpersist)  ["Thermostat"]


Number LR_Max_Temp 		"LR Max Temperature" 				(gLR_Temp, statepersist, gRoundup_1, gTempMax)		{ alexa="ThermostatController.upperSetpoint" }
Number BR1_Max_Temp 	"BR1 Max Temperature" 				(gBR1_Temp, statepersist, gRoundup_1, gTempMax)		{ alexa="ThermostatController.upperSetpoint" }

Number LR_Tgt_Temp 		"LR Target Temperature" 			(gLR_Temp,  statepersist, gLivingroomThermostat, 	gRoundup_1, gTempTgt) 	["TargetTemperature"]
Number BR1_Tgt_Temp 	"BR1 Target Temperature" 			(gBR1_Temp, statepersist, gBedroomThermostat, 		gRoundup_1, gTempTgt) 	["TargetTemperature"]

Number LR_Min_Temp 		"LR Min Temperature" 				(gLR_Temp, statepersist, gRoundup_1, gTempMin)		{ alexa="ThermostatController.lowerSetpoint" }
Number BR1_Min_Temp 	"BR Min Temperature" 				(gBR1_Temp, statepersist, gRoundup_1, gTempMin)		{ alexa="ThermostatController.lowerSetpoint" }

Number	BR1_Temp					"Temperature [%.1f °C]"		(gTemperature, gBR1_Temp, chartpersist, gBR_Temp, gBedroomThermostat) ["CurrentTemperature"] 	{ alexa="TemperatureSensor.temperature", channel="mihome:sensor_weather_v1:158d00027342e8:temperature" }
Number  LR_Temp						"Temperature [%.1f °C]"		(gTemperature, gLR_Temp, chartpersist, gLivingroomThermostat) 			["CurrentTemperature"] 	{ alexa="TemperatureSensor.temperature", channel="mihome:sensor_weather_v1:158d0002789d07:temperature" }


REST gLivingroomThermostat

{
  "members": [
    {
      "link": "http://192.168.0.4:8080/rest/items/LR_Temp_Mode",
      "state": "ON",
      "editable": false,
      "type": "Switch",
      "name": "LR_Temp_Mode",
      "label": "Livingroom Temperature Mode",
      "tags": [],
      "groupNames": [
        "statepersist",
        "gTempMode",
        "gLivingroomThermostat"
      ]
    },
    {
      "link": "http://192.168.0.4:8080/rest/items/LR_Tgt_Temp",
      "state": "19",
      "editable": false,
      "type": "Number",
      "name": "LR_Tgt_Temp",
      "label": "LR Target Temperature",
      "tags": [
        "TargetTemperature"
      ],
      "groupNames": [
        "gLR_Temp",
        "statepersist",
        "gLivingroomThermostat",
        "gRoundup_1",
        "gTempTgt"
      ]
    },
    {
      "link": "http://192.168.0.4:8080/rest/items/LR_DTgt_Temp",
      "state": "23.0",
      "editable": false,
      "type": "Number",
      "name": "LR_DTgt_Temp",
      "label": "Day Target Temperature",
      "tags": [],
      "groupNames": [
        "gLR_Temp",
        "statepersist",
        "gLivingroomThermostat",
        "gRoundup_1",
        "gTempTgt"
      ]
    },
    {
      "link": "http://192.168.0.4:8080/rest/items/LR_NTgt_Temp",
      "state": "19.0",
      "editable": false,
      "type": "Number",
      "name": "LR_NTgt_Temp",
      "label": "Night Target Temperature",
      "tags": [],
      "groupNames": [
        "gLR_Temp",
        "statepersist",
        "gLivingroomThermostat",
        "gRoundup_1",
        "gTempTgt"
      ]
    },
    {
      "link": "http://192.168.0.4:8080/rest/items/LR_Temp",
      "state": "24.49",
      "stateDescription": {
        "pattern": "%.1f °C",
        "readOnly": true,
        "options": []
      },
      "editable": false,
      "type": "Number",
      "name": "LR_Temp",
      "label": "Temperature",
      "tags": [
        "CurrentTemperature"
      ],
      "groupNames": [
        "gTemperature",
        "gLR_Temp",
        "chartpersist",
        "gLivingroomThermostat"
      ]
    }
  ],
  "link": "http://192.168.0.4:8080/rest/items/gLivingroomThermostat",
  "state": "NULL",
  "editable": false,
  "type": "Group",
  "name": "gLivingroomThermostat",
  "label": "Livingroom Thermostat",
  "tags": [
    "Thermostat"
  ],
  "groupNames": [
    "chartpersist"
  ]
}

REST:gBedroomThermostat

{
  "members": [
    {
      "link": "http://192.168.0.4:8080/rest/items/BR1_Temp_Mode",
      "state": "ON",
      "editable": false,
      "type": "Switch",
      "name": "BR1_Temp_Mode",
      "label": "Bedroom Temperature Mode",
      "tags": [],
      "groupNames": [
        "statepersist",
        "gTempMode",
        "gBedroomThermostat"
      ]
    },
    {
      "link": "http://192.168.0.4:8080/rest/items/BR1_Tgt_Temp",
      "state": "19.5",
      "editable": false,
      "type": "Number",
      "name": "BR1_Tgt_Temp",
      "label": "BR1 Target Temperature",
      "tags": [
        "TargetTemperature"
      ],
      "groupNames": [
        "gBR1_Temp",
        "statepersist",
        "gBedroomThermostat",
        "gRoundup_1",
        "gTempTgt"
      ]
    },
    {
      "link": "http://192.168.0.4:8080/rest/items/BR1_DTgt_Temp",
      "state": "19.5",
      "editable": false,
      "type": "Number",
      "name": "BR1_DTgt_Temp",
      "label": "Day Target Temperature",
      "tags": [],
      "groupNames": [
        "gBR1_Temp",
        "statepersist",
        "gBedroomThermostat",
        "gRoundup_1",
        "gTempTgt"
      ]
    },
    {
      "link": "http://192.168.0.4:8080/rest/items/BR1_NTgt_Temp",
      "state": "18.5",
      "editable": false,
      "type": "Number",
      "name": "BR1_NTgt_Temp",
      "label": "Night Target Temperature",
      "tags": [],
      "groupNames": [
        "gBR1_Temp",
        "statepersist",
        "gBedroomThermostat",
        "gRoundup_1",
        "gTempTgt"
      ]
    },
    {
      "link": "http://192.168.0.4:8080/rest/items/BR1_Temp",
      "state": "22.55",
      "stateDescription": {
        "pattern": "%.1f °C",
        "readOnly": true,
        "options": []
      },
      "editable": false,
      "type": "Number",
      "name": "BR1_Temp",
      "label": "Temperature",
      "tags": [
        "CurrentTemperature"
      ],
      "groupNames": [
        "gTemperature",
        "gBR1_Temp",
        "chartpersist",
        "gBR_Temp",
        "gBedroomThermostat"
      ]
    }
  ],
  "link": "http://192.168.0.4:8080/rest/items/gBedroomThermostat",
  "state": "NULL",
  "editable": false,
  "type": "Group",
  "name": "gBedroomThermostat",
  "label": "Bedroom Thermostat",
  "tags": [
    "Thermostat"
  ],
  "groupNames": [
    "chartpersist"
  ]
}

Hopefully that covers what you want to asee, if not please ask.

All rooms will answer correctly if I ask “Alexa, what is the current thermostat”.

Thanks
Paul

Great.
No error this time. :+1:

String  Therm_Manual  "Modus überschrieben" <thermostat>      (Thermostat) {alexa="ThermostatController.thermostatMode" [OFF="OFF",HEAT="ON",AUTO="AUTO"] }

I guess the documentation needs an update then.

https://www.openhab.org/docs/ecosystem/alexa/#item-state

Have you tried to add a space to your group label? ("Living room Thermostat"). If that doesn’t fix your problem, you can remove the functionality from the label ("Living room")

Good point.

1 Like
4 Likes

Well I must confess as all my other devices are known as Livingroom I did not hold out much hope for the label change. To show how finicky these labels can be I have provided some examples and PASS/FAIL them.

  • Livingroom Thermostat - Fail
  • Diningroom Thermostat - Pass
  • Bedroom Thermostat - Pass
  • Hallway Theromstat - Fail
  • Living room thermostat - Fail
  • Living room - Pass
  • Hallway - Pass

Thanks once again.
Paul

Related to users having image items or a very high number of items in their configuration. We have just released a change to the live skill improving the discovery request performance.

Hopefully that will narrow down the number of users still not able to use the v3 skill.

1 Like

First of all, thank you for all of the hard work on this. I’m happy to see that I’m getting started with OpenHab just after such a major improvement.

I had a minor comment on the documentation – I believe the documentation reverses the concept of cool and heat for ThermostatController.upperSetpoint and .lowerSetpoint.

ThermostatController.upperSetpoint: Items that represent a upper or HEAT setpoint for a thermostat…

In my Alexa app, I see the “cool to” temp shown as the item linked as upperSetpoint and vice versa – intuitively, this also makes sense as if you want the temp to stay within a certain range, you would cool at the upper temp and heat at the lower temp.

Secondly, I am a little confused on what I can say to the thermostat controller. Here is my current test setup:

Group     gThermostat       "Thermostat"               (gHome)        {alexa="Endpoint.Thermostat"}
Number    ThermostatTemp    "Temperature [%.1f F]"     (gThermostat)  {alexa="TemperatureSensor.temperature" [scale="Fahrenheit"]}
Number    CoolSetpoint      "Cool Setpoint [%.0f F]"   (gThermostat)  {alexa="ThermostatController.upperSetpoint"  [scale="Fahrenheit"]}
Number    HeatSetpoint      "Heat Setpoint [%.0f F]"   (gThermostat)  {alexa="ThermostatController.lowerSetpoint"  [scale="Fahrenheit"]}
Number    ThermostatMode    "Mode [%s]"                (gThermostat)  {alexa="ThermostatController.thermostatMode" [OFF=0,HEAT=1,COOL=2,AUTO=3]}
Number    ThermostatFan     "Fan Mode [%s]"            (gThermostat)  {alexa="ModeController.mode" [supportedModes="0=Auto,1=Auto Circulate,2=On"]}

My thermostat is a Radio Thermostat CT50 that I am driving via HTTP requests in Node-Red. I am using OH 2.5 snapshot. What works:

  • Alexa can see the thermostat and tell me ThermostatTemp
  • “Alexa, what is the thermostat fan mode” → “The thermostat’s fan mode is…”
  • The thermostat mode and heat/cool setpoints show correctly in the Alexa Android app.
  • Everything seems to work as expected when controlling the thermostat from my OH sitemap.

What doesn’t seem to work:

  • Asking or telling Alexa to set the thermostat mode or any of the target temperatures
  • “Alexa, what is the thermostat mode” → “The thermostat’s fan mode is…” (tells me fan mode again)
  • “Alexa, what is the thermostat cool setpoint” → “Hmm, I don’t know that”
  • “Alexa, what is the thermostat target temperature?” → “The thermostat temperature is 72.5 degrees” (it says the actual temperature, not the set point - do I need to bind a dummy variable to ThermostatController.targetSetpoint and update it as the thermostat changes modes from COOL to HEAT and back?)

I’m probably doing something obviously wrong here, but I can’t figure out what. Any comments or ideas would be appreciated!

EDIT: Ha. “Alexa, set the thermostat to 73 degrees” sets the upper and lower setpoints to 74 and 72. Not my 100% desired behavior but it at least gives me a way to control temp for now.

  • “Alexa, what is the thermostat mode” → “The thermostat’s fan mode is…” (tells me fan mode again)

Having a ModeController.mode on a thermostat is not something we probably tested, i’m not sure how Alexa would respond to that as it seems to conflict with the “Mode” of the thermostat (ThermostatMode in your case). When using just the “ThermostatController.thermostatMode” , asking Alexa what the thermostat is set to will result in both the mode and target temperature being reported if the thermostat is ON (auto, heat, cool), or will just report that its off if set to OFF (no temperature). We don’t have any control over this, the only thing we can do is send commends and reports values when Alexa asks us to.

  • “Alexa, what is the thermostat cool setpoint” → “Hmm, I don’t know that”

Requesting thermostat set points like this do not seem to be supported by Alexa,

Alexa, set the thermostat to 73 degrees” sets the upper and lower setpoints to 74 and 72. Not my 100% desired behavior but it at least gives me a way to control temp for now.

From our Documentation:

comfortRange=<number>. When dual setpoints (upper, lower) are used this is the amount over the requested temperature when requesting Alexa to set or adjust the current temperature. Defaults to comfortRange=1 if using Fahrenheit and comfortRange=.5 if using Celsius. Ignored if a targetSetpoint is included in the thermostat group.

@heycmo Based on my previous testing, there are some issues around utterances when having both of these capabilities setup in the same endpoint group causing some conflicts. I noticed that using the term “mode” would always point to the ModeController device, or having some of the supported modes named the same between the two (e.g. Auto) would always point to the thermostat mode.

I think that Amazon didn’t push the support for ModeController that far and their expectation seems to be to use that capability for all modes of a given device. My recommendation would be to either setup a separate endpoint for your fan mode or you could try to convert the thermostat mode to ModeController but you would loose some of the thermostat integration especially in the app.

As @digitaldan mentioned, the comfort range is used to define the setpoints spread based on a given target setpoint. Out of curiosity, what would be your expected behavior when making that request?

hi, having some issues since v3 of the Skill.
i removed all my items on Amazon to rediscover my openhab items with the new metadata feature.
however i can’t get Amazon Alexa to discover any openhab items now.

what i did till now:

  • restart of openhab
  • remove. re-add and re-linked openhab Skill

running openhab on the last stable 2.4 version
my items look like this:

Group:Switch:OR(ON, OFF) H_Lamps_S "All Lights" <light>	(PR_All_OFF)    {alexa="Lighting"}
Dimmer S_BR_LIGHT_Ceiling_D "Bedroom Ceiling" (R_BR_LIGHT_D, R_BR_LIGHT, gLights)  	{channel="hue:0220:0017884e88f5:12:brightness", alexa="Lighting"}
Switch network_device_nas_switch "NAS" {alexa="Switchable"}

Based on the skill logs, I can see that your last discovery attempt was successful, while previous ones were timing out along with one of them failing due to the Echo Control binding known issue with 2.4 release.

Anyway, you should be able to see your devices in your Alexa account. You may have to refresh the device page.