Alexa Smart Home Skill V3 is now live!

Vote submitted.
Very nice solution, I have around 80 commands on OH that I currently have setup using the AmazonEchoControl binding but I have each command exactly specified not like you have done which is way cooler using regex.

Off to play

I have the following setup

rule "Alexa local fan Updates"
when
	Member of EchoCmds received update
then
	logInfo("alexa-enabled-groups","Running local Fan state change")	
	val String sourceRoom = triggeringItem.name.split("_").get(0)
	val String FanPowerState = transform("REGEX", "turn (on|off) (?:the )?fan", triggeringItem.state.toString)

	if (FanPowerState !== null)
	try {sendCommand(sourceRoom + "_Fan", FanPowerState.toUpperCase)}
		catch(Throwable t) {sendCommand(sourceRoom+"_Echo_TTS","Something went wrong.")}
	logInfo("alexa-enabled-groups",sourceRoom+"_Fan changed to "+FanPowerState.toUpperCase)	
end

And this works great, one small issue is how do you get over her saying “A few things share the name fan, which one do you want?” I have so far always added a routine on the alexa app for every specific phrase I have used where all she does is say either checking for status requests or roger that for commands. How do you deal with it?
Regards
Paul

Good Morning, I have some problem to fully configure my daikin split.
That’s my item file:
clima.items

//Clima Salone
Group    gClima_Sala                    "Clima Sala"                                                            {alexa="Endpoint.Thermostat"}
Switch   Power_Clima_Sala               "Power"                                 <switch>        (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:power", alexa="PowerController.powerState"}
Number   SetPoint_Clima_Sala            "Setpoint [%.0f °C]"                    <temperature>   (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:settemp", alexa="ThermostatController.targetSetpoint"}
Number   IndoorTemp_Clima_Sala          "Temperatura Interna  [%.1f °C]"        <temperature>   (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:indoortemp", alexa="TemperatureSensor.temperature"}
Number   OutdoorTemp_Clima_Sala         "Temperatura Esterna  [%.1f °C]"        <temperature>   (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:outdoortemp"}
String   Mode_Clima_Sala                "Mode "                                 <climate>       (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:mode", alexa="ThermostatController.thermostatMode"}
String   FanSpeed_Clima_Sala            "Fan"                                    <fan>          (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:fanspeed"}

It work nice but I still cannot handle Fan and Mode.
I tried to add the tag according with the daikin documentation:

String  Mode_Clima_Sala         "Mode [%s]"     <climate>       (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:mode", alexa="ThermostatController.thermostatMode" [HEAT=HEAT,COOL=COLD,AUTO=AUTO]}

but when I add the tags the group got an error and all item is unlinked

Create a routine: if Alexa receives commons “turn in the fan” then reply with “ok”. You’ll have to make one for off as well.

As @omatzyo mentioned, you could certainly use routines to cover the turn on/off requests.

However, in my initial response, I mentioned about the use of an Alexa activity device.

Switch RoomAwarenessActivityFan "Fan" {alexa="Activity", autoupdate="false"}

The main advantage of using activities or even scenes is that they are stateless from Alexa perspective, thus autoupdate="false. Another point is that it covers all the different variation you would request the command (e.g. “power on/off” or “switch on/off”) that you could incorporate in the command regex.

val String FanPowerState = transform("REGEX", "(?:power|switch|turn) (on|off) (?:the )?fan", triggeringItem.state.toString)

If going that route, make sure to name the device exactly how you would call it otherwise you will get the device name conflict message response.

1 Like

You need to make sure to quote the parameter setting string-typed values. You should have gotten a syntax error in your openhab logs.

String  Mode_Clima_Sala         "Mode [%s]"     <climate>       (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:mode", alexa="ThermostatController.thermostatMode" [HEAT="HEAT",COOL="COLD",AUTO="AUTO"]}

Hopefully, you are connected to the US because this is a perfect usage of the ModeController interface. This is how it would look like.

//Clima Salone
Group    gClima_Sala                    "Clima Sala"                                                            {alexa="Endpoint.Thermostat"}
Switch   Power_Clima_Sala               "Power"                                 <switch>        (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:power", alexa="PowerController.powerState"}
Number   SetPoint_Clima_Sala            "Setpoint [%.0f °C]"                    <temperature>   (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:settemp", alexa="ThermostatController.targetSetpoint"}
Number   IndoorTemp_Clima_Sala          "Temperatura Interna  [%.1f °C]"        <temperature>   (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:indoortemp", alexa="TemperatureSensor.temperature"}
Number   OutdoorTemp_Clima_Sala         "Temperatura Esterna  [%.1f °C]"        <temperature>   (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:outdoortemp"}
String   Mode_Clima_Sala                "Mode "                                 <climate>       (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:mode", alexa="ThermostatController.thermostatMode" [HEAT="HEAT",COOL="COLD",AUTO="AUTO"]}
String   FanSpeed_Clima_Sala            "Fan"                                   <fan>           (gClima_Sala)   {channel="daikin:ac_unit:192_168_1_84:fanspeed", alexa="ModeController.mode" [supportedModes="AUTO=@Setting.Auto,SILENCE=@Setting.Quiet,LEVEL_1=Level One:@Value.Low,LEVEL_2=Level Two,LEVEL_3=Level Three:@Value.Medium,LEVEL_4=Level Four,LEVEL_5=Level Five:@Value.High",friendlyNames="@Setting.FanSpeed,@DeviceName.Fan",ordered=true]}

And you can change the fan speed like this:
Alexa, set the fan speed on Clima Sala to level two
Alexa, set the fan on Clima Sala to high

If you don’t have access to that capability, then you will need to use a proxy item such as a dimmer not part of the group endpoint set as PercentageController and update your device fan speed levels based on the percentage level via a rule.

1 Like

Is this still not possible with v3? @digitaldan

The workaround via Alexa app is a pain with many blinds
:slight_smile:

Unfortunately we can’t add a capability that Amazon hasn’t provided yet in their Smart Home Skill API.

Make sure to vote for the blinds integration feature request on the Alexa user voice website

I was just starting to add voice control to my devices using the new v3 application and struggling a little bit with how to name all of my devices differently, but still make it simple enough to use.

This seems like a brilliant way to deal with identical devices controlled by different echo units. One question I have, would you be able to share the MAP file for the example? Do you need to list every potential command, or can that be put together like the REGEX in the rule?

Thanks,

Steve

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