HomeKit fan speed support

First off, I’m a Python newbie and only started learning on my own to help implement some features to the Abode component and now this. I recently paired a GE Z-Wave Plus Fan control switch to a ceiling fan and noticed there’s no speed control in HomeKit, so I’m attempting to implement it. Here are the things I’ve observed:

  • HomeKit allows for controlling a fan from 0 to 100% in the iOS Home app with a definable minStep value as low as 1%.
  • Home Assistant implements fan speed control with four speeds: off, low, medium and high (typical for most generic ceiling fans).
  • Some ceiling fans have more speed settings.

With this in mind, I’d imagine we would want to expand Home Assistant’s fan speed supported features options to support the various different speed settings fans can have. It appears the majority (at least in the United States) of generic ceiling fans just support off/low/medium/high but I’ve seen other users post about fans with an additional speed. How to implement this is beyond me but just something of note.

That being said, I’ve still attempted to add fan speed control to the HomeKit component which you can find here:


I’ve tested this on my Hassio setup and everything works. Currently it’s setup with a minStep: 25 so when you slide the speed control in the iOS Home app, it increases/decreases in 25% increments. The issue here is this obviously results in five speed settings, 0%, 25%, 50%, 75% and 100%. Right now 75% and 100% both just command a fan speed of high. I suppose the other option would be to set minStep: 33 so you essentially get just four speeds.

One other minor issue is if I toggle the fan on from an off state, the fan turns on to the last speed setting but the iOS Home app always shows 100%. I’m sure it’s because I’m screwing something up in the update_state method which I don’t entirely understand.

Anyways, if anyone that actually understands python better than I can help review the code and provide inputs/additions/edits, any help would be greatly appreciated.

1 Like

I love that your spending time exploring the options here.

However this is something we already considered a while back when we first added the fan support. The issue is that (as you know) each component uses their own speed list. There are some common values which could allow for a general mapping but it isn’t ideal.

The idea then was to change the internal mapping from a speed list to percentage to be compatible with HomeKit https://github.com/home-assistant/architecture/issues/27 but that also turned out not to be the best solution, which is the reason this issue has staled for so long.

Recently I’ve been thinking if some kind of templating inside the entity_config section of homekit could solve this. You need to define the mapping, but then it just works. Haven’t had the time yet to work on it though.

Here I am still using the hombridge ha plugin with legacy password. Still works I use a template fan with 6 speed that outputs the slider in steps of 17%.

Thanks for your work on this.

But this fork commit, Not yet merge to master

I had a feeling that was the case, hehe.

Well, it appears Home Assistant utilizes low/medium/high speed settings. As a default, why not have the HomeKit component support the three speed settings for now? Or does Home Assistant support other fan speed settings, such as 1% increments? I thought it was just low/medium/high.

If we were to add support for only these three, users will post bug reports that their fan speed setting doesn’t work. This is to fragmented at the moment to work properly.

I agree that the fan implementation in Home Assistant needs to easily accommodate various fan speeds for different fan types, but I thought how it’s implemented right now is simply low/medium/high. I guess my point is if that’s how it’s implemented right now, then adding HomeKit support to match that would make sense to me. I could be wrong though about the fan component in Home Assistant. This is just based off my experience and quickly looking through the code.

It seems this is a highly requested feature. I might not have been right to block this for so long: https://github.com/home-assistant/home-assistant/pull/19767


If you use a template fan you can have more speeds. My ceiling fan is rf controlled and has 6 speeds. I use template fan. In HomeKit I can increase speed steps if 17%, using homebridge ha old plugin.

Sorry if I’m missing something here. I’ve read the HomeKit documentation and there is reference to “All fans that support speed and speed_list through value mapping…”, so it would seem what was discussed here has been implemented. However, I don’t see how to use it. My 3 speed ceiling fan in HomeKit is a vertical slide switch from 0 to 100% vs. Off, Low, Med, High.

The example in the HomeKit documentation says: (Example: speed_list = [ off , low , high ]; off -> <= 33 ; low -> between 33 and 66 ; high -> > 66 )

When I look at the state of my switch in HA it includes: speed_list: off,low,medium,high. If this is not automatically picked up by HomeKit, then it would seem I need to create an entity_config: section based on the example, but I don’t see how to do that; speed_list is not listed as one of the entity_config sections (the documentation says the feature_list section is, “Only for media_player entities.”).

So if this has been implemented I’m having trouble making the connections on how to use it. Appreciate any guidance.

@VdkaShaker You shouldn’t need to add anything to homekit: entity_config. The homekit component should handle this automatically. Depending on the time you first added this fan to HomeKit, you might need to temporarily exclude your fan (via the filter option), restart Home Assistant, include it and restart again.

If that doesn’t work, please post a screenshot of your fan entity in the states panel.

@cdce8p Thanks for the tips. I followed them and there does not seem to be any change to how the fan is represented (the fan was removed and re-added as expected by the procedure). Perhaps it’s working as expected, but I’m expecting something different?

My Alarm system made possible by the HomeKit component of HA shows as 4 options:

I was expecting that my fan would show up looking similar, with 4 options from the speed_list: Off, Low, Medium, High. Instead it shows up as a slider:

Here’s the state info from HA:

speed: off
speed_list: off,low,medium,high
node_id: 4
value_index: 0
value_instance: 1
value_id: 72057594109853697
friendly_name: Ceiling Fan
supported_features: 1

What is the purpose of the example I cited from the HomeKit documentation about fans? It seems to be saying code is needed somewhere to get the options as I was expecting.

Let me know if further detail is needed. Thanks for your assistance.

@VdkaShaker If you get a slider, the HomeKit component is working as intended. Unfortunately it isn’t possible to display specific speed options in the Home App at the moment. That’s nothing we can change about it.

When you move the slider in the app, you should notice that it “snaps” to certain positions. That’s the best we can do for now.

1 Like

Ok. That helps. I was expecting something different in the interface so I appreciate getting that cleared up.

It seems to be working fine then, but I’m still not clear on what the fan example in the documentation is intended for, if anyone has additional clarification on that.

@VdkaShaker That might be a bit cryptic. What it comes down to is that it’s an explanation of how the assignment works. (From Home App values to speeds and vice versa)

1 Like

Hi, I can vouch that for me, i am using the same GE fan control and it does NOT latch to specific percentages. So, what you say is not actual unfortunately :frowning:

Hi there, very stupid question but in order to implement this, would I be right to download these two py files and save them in a homekit folder under my custom_components folder? (I have homekit integration installed but I don’t have this folder already in my custom_components folder). I’ve got a fan linked into HA via a broadlink RM pro 4 and also want to get the fan recognised in HomeKit Bridge.

Thank you!