Control 3 speed ceiling fan with amazon binding

Hello,
How would you control an infrared ceiling fan with amazon alexa ?
I have an infrared controlled celing fan with 3 speed + off. (4 button on the remote)
I’m using a broadlink RM3 mini to send the signal (with the broadlink binding).
Is there a way to give an order like ‘Alexa, set the parent’s fan speed to 3’ or something like that ?
Or using the PowerLevelController.powerLevel metadata, but how do you translate a percentage to a fixed value ?
Thank you

EDIT:
Solution below

Hey,

i had the similar challenge.
i did it with

  • Alexa changing the percentage at speed item
  • Rule mapping percentage of proxy item to best suitable mode
  • add alexa mapping to fan mode as well

my items

Group gVallox        "Lüftung"  {homekit="Fan" , alexa="Endpoint.Fan"}
Number fan_mode      "Profil : [%d]" (gVallox)   {channel="valloxmv:valloxmv:ventilation:state", alexa="ModeController.mode" [supportedModes="2=Nacht,3=Normal,4=Party",friendlyNames="Status", language="de"] }
Number fan_speed     "Ventilatorleistung [%d %%]" (gVallox)   {homekit="RotationSpeed", channel="valloxmv:valloxmv:ventilation:fanspeed", alexa="RangeController.rangeValue" [supportedRange="1:100:1",presets="1=@Value.Minimum:@Value.Low:Lowest,100=@Value.Maximum:@Value.High:Highest",friendlyNames="@Setting.FanSpeed,Speed"]}

my rule

rule "Map fan speed to mode"
when
     Item fan_speed received update
then
     if (fan_speed.state < 40) {
                if (fan_mode.state != 2) {
                        fan_mode.sendCommand(2)
                }
     } else {
        if (fan_speed.state < 70) {
                if (fan_mode.state != 3) {
                        fan_mode.sendCommand(3)
                }
        } else {
                if (fan_speed.state < 95)  {
                        if (fan_mode.state != 4) {
                                fan_mode.sendCommand(4)
                        }
                }
        }
     }
end
1 Like

More or less the same rule:

rule "Map fan speed to mode"
when
    Item fan_speed received update
then
    var Number nSpeed = 4
    if(fan_speed.state < 70) nSpeed = 3
    if(fan_speed.state < 40) nSpeed = 2
    if(fan_mode.state != nSpeed) fan_mode.sendCommand(nSpeed)
end

But maybe a bit more radable :wink:

Also, it’s possible that a postUpdate(nSpeed) would suffice.

1 Like

It all depends on how you are modeling your ceiling fan in OH. If you could share your item definition, that would make it easier to give you a more suited answer to your setup. Assuming you are using a Number item, using a RangeController to control the speed should do the work as @yfre’s example above. If you need to have power on/off control, you can use a group endpoint adding a proxy switch item modeled as PowerController and change setting via rules in OH.

items

Group gFan "Fan" {alexa="Endpoint.Fan"}
Number FanSpeed "Fan Speed" (gFan) {alexa="RangeComponent" [supportedRange="0:3:1",presets="1=@Value.Low,2=@Value.Medium,3=@Value.High",friendlyNames="@Setting.FanSpeed,Speed"]}
Switch FanPower "Fan Power" (gFan) {alexa="PowerController.powerState"}

rules

rule "Fan Power Command"
when
  Item FanPower received command
then
  if (receivedCommand == ON)
    FanSpeed.sendCommand(1)
  else
    FanSpeed.sendCommand(0)
end

rule "Fan Speed Update"
when
  Item FanSpeed received update
then
  if (FanSpeed.state == 0)
    FanPower.postUpdate(OFF)
  else
    FanPower.postUpdate(ON)
end

uterrances

Alexa, turn off the fan
Alexa, turn on the fan
Alexa, set the fan speed to medium
Alexa, set the fan speed to 3
Alexa, increase the fan speed

1 Like

Thank you, exactly what I was hoping for :slight_smile:

What are the @Value.Low, @Value.Medium useful for ?
and also

friendlyNames="@Setting.FanSpeed,Speed"

Aymeric

@Value.Low, @Value.Medium => preset friendly names allowing to request certain presets by name. The fact that there are prefixed with @ means that these are asset ids opposed to localized text labels. My utterance examples above show the difference between requesting a fan speed by name and by value. When requesting “medium” speed, Alexa will convert it to preset 2 in the background and send that value in the request to the skill.

friendlyNames="@Setting.FanSpeed,Speed" => similar to the explanation above, these represent the functionality names allowing you to refer to the relevant items. Using the above utterance examples, requesting a change with “fan speed” basically is composed of two parts. “Fan” being the group endpoint name and “Speed” being the specific function friendly name of that group.

Thank you, I don’t grasp all the extent of it … but it’s working …
If I understood correctly, I should write ‘Vitesse’ instead of ‘Speed’ in the line below (to use french)

friendlyNames="@Setting.FanSpeed,Vitesse"

in my case ?
All the @… being automatically translated by the alexa engine.

Correct as long as your regional settings are configured properly.

Exactly :+1:

I have a Z-wave 3-speed fan control that it is represented as a Dimmer. I can tell Alexa to turn it on and off. 0=off, 1-33=low,34-66=medium,67-100=high. But I haven’t been able to use the presets or values. Do I need to set up a group endpoint or is this sufficient below?

I get “Ceiling Fan doesn’t support that” if I say “set the ceiling fan to medium” or “set the ceiling fan to 5”.

Dimmer CeilingFan "Ceiling Fan" <fan> (gPubItems) {alexa="PowerController.powerState, RangeController.rangeValue" [supportedRange="0:100:1",presets="1=@Value.Low,50=@Value.Medium,100=@Value.High"]}

Replying to myself. Making a group endpoint worked fine. This seems a little more complicated than I would expect, but I’m happy enough with it. Is there an easier way to do this?

Here are my items:

Group CeilingFanGroup     "Ceiling Fan"          {alexa="Endpoint.Fan"}
Number CeilingFanSpeed  "Ceiling Fan Speed"  (CeilingFanGroup) {alexa="RangeController.rangeValue" [supportedRange="0:100:
1",presets="1=@Value.Low,50=@Value.Medium,100=@Value.High",friendlyNames="@Setting.FanSpeed,Speed"]}
Switch CeilingFanPower  "Ceiling Fan Power"  (CeilingFanGroup) {alexa="PowerController.powerState"}
Dimmer CeilingFan "Ceiling Fan Proxy" <fan> (gPubItems)

and here are the rules:

from core.rules import rule
from core.triggers import when

@rule("Cabin Ceiling Fan", description="Cabin ceiling fan proxy", tags=[])
@when("Item CeilingFanPower received command")
@when("Item CeilingFanSpeed received command")
def CeilingFan(event):
    CeilingFan.log.info("received command {}".format(event.itemCommand))
    events.sendCommand("CeilingFan",str(event.itemCommand))

This should have worked as you intended. I just run a test and there seems to be a bug on the Alexa end recognizing either numerical-based modes for ModeController or presets for RangeController as you experienced. However, I was still able to set to a specific value and turn on and off.

I raised a support case with the Alexa developer team so they can investigate.

Based on what I mentioned above, I am surprised that preset requests are working with your updated configuration.

The Alexa developer support team fixed the issue I raised. There was an issue with using @Value.Low, @Value.Medium and @Value.High asset ids when mapped to a numerical value causing RangeController presets along with ModeController numerical modes using these ids to be ignored on their end.

2 Likes

Hello OH experts there,

A complete newbie to OH here.
Im trying to get my homebrew IR blaster ( ESP86 Wemo board ) that can control a ceiling fan through http requests. IR Blaster is working perfectly thorough a small MIT appinventer app that I built.

Next I tried to get it working through Alexa. I have OH3.0.1 running on Rpi4.

Here is my item definition and rules - Just copied from examples in this thread.


Group Fan     "Fan"          {alexa="Endpoint.Fan"}
Number Speed  "Speed"  (Fan) {alexa="RangeController.rangeValue" [supportedRange="1:5:1",presets="1=@Value.Minimum:@Value.Low:Lowest,5=@Value.Maximum:@Value.High:Highest",friendlyNames="@Setting.FanSpeed,Speed"]}
Switch Power  "Power"  (Fan) {alexa="PowerController.powerState"}

And rules


rule "Bedroom FanSpeed"
    when
        Item Speed changed
    then
        switch(Speed.state) {
            case 0 : sendHttpGetRequest("http://192.168.1.3/speed=0")
            case 1 : sendHttpGetRequest("http://192.168.1.3/speed=1")
            case 2 : sendHttpGetRequest("http://192.168.1.3/speed=2")
            case 3 : sendHttpGetRequest("http://192.168.1.3/speed=3")
            case 4 : sendHttpGetRequest("http://192.168.1.3/speed=4")
            case 5 : sendHttpGetRequest("http://192.168.1.3/speed=5")
        }
    end
rule "Bedroom FanPower"
    when
        Item Power received command
    then
        switch(receivedCommand) {
            case ON : sendHttpGetRequest("http://192.168.1.3/on")
            case OFF : sendHttpGetRequest("http://192.168.1.3/off")
        }

   end


I could get Alexa discover the item , and I can change the speed through Alexa app, and I can see rules running.

I can switch on and off the fan by uttering “Alexa switch off/on the fan”

However when I utter “Alexa set fan speed to 2” she tells me that “fan doesn’t support that”.
I tried by adding below metadata but still Alexa doesn’t seem to recognise any other capability of the fan.


Group gFan "machine" {alexa="Fan" [type="oscillating",speedSteps=5]}

I have tried everything I can think of - creating the item through paper ui, adding the item through text and adding all meta data through UI and so on. This is driving me nuts and Im at the verge giving up this project and just thinking of using my App!. Just thought I will seek help here before packing up.
Any pointers to fix this would help. Thanks in advance.

Sometimes it could get tricky when the device name is included in capability name. You could try asking Alexa, set the fan to 2. This should work because there is only one capability in your group endpoint that supports setting to a give range value.

If you want to have utterance Alexa, set the fan speed to 2, you should remove the @Setting.FanSpeed capability name to prevent that conflict.

The metadata parameters you listed are only supported by the Google Assistant actions.

However, a new metadata syntax for the skill will be released shortly, including new fan capabilities that will match your setup. Feel free to join the beta test.

Jeremy,

I could get it working by adding making below change.

Number Speed  "Speed [%d]"  (Fan) {alexa="RangeController.rangeValue" [supportedRange="1:5:1",presets="1=@Value.Minimum:@Value.Low:Lowest,5=@Value.Maximum:@Value.High:Highest",friendlyNames="@Setting.FanSpeed,Speed"]}

ie by adding [%d] formatter to Speed. After this Alexa is not complaining “Fan doesnt support that”.
Im not exactly sure if thats whats fixing the problem, but thats the onl change I made. Im a complete newbie to openhab. Does this makes sense?.

The Alexa API considers the validity of a given range value if is within min/max ranges and is a multiple of range precision. This means that if the precision is set to 1, then all values should be integers.