Control 3 speed ceiling fan with amazon binding

Tags: #<Tag:0x00007f616cd92068>

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