Theoretically, HomeKit supports fans as a smart home accessory. There are some HomeKit ceiling fans already on sale, but what I’ve been holding out for is a HomeKit tower fan for my office. Unfortunately, there aren’t really any to speak of.
After years of waiting, and a particularly hot summer, I gave up and explored the enthusiast route. I bought a standard fan with an IR remote control and set out to induct it into my HomeKit home using Homebridge…
The most obvious route to add a dumb appliance to the HomeKit ecosystem is to use a smart plug. With a HomeKit smart plug, you can very quickly add smarts to a lot of accessories. The smart plug toggles the power on and off at your command, so it’s perfect for things like floor lamps.
Unfortunately, tower fans are not so simple. As they have settings like fan speed and oscillation to manage, they don’t simply turn on when the power turns on. They have a memory of sorts. When you plug them into power, which is what a smart plug is effectively emulating, they just sit there. You then have to press another button to actually start up the fan. This means a smart plug is not the solution.
Instead, I bought a fan with an Infrared remote control specifically because my plan was to use Homebridge. (What is Homebridge? Homebridge is a third-party, unofficial, bridge server that can expose all sorts of accessories to the HomeKit platform.)
The key to all of this is an IR blaster called the Broadlink RM. The RM connects to WiFi, so you can connect to it from an app and beam out Infrared commands remotely. However, the app is terrible and I have no interest in using it. Instead, the plan was to connect the Broadlink RM to Homebridge using this community plugin.
In the end, the blaster will essentially send out the same Infrared codes as the fan’s remote. The fan will see the incoming IR and dutifully perform the commands. All the IR stuff is wrapped up neatly in a Homebridge plugin and this means it will show up in my HomeKit home like any other accessory.
How to set up an Infrared accessory in HomeKit using Homebridge
The first step is to set up a Homebridge server itself if you don’t have one already. You can run Homebridge on a Mac, a Rasberry Pi, pretty much anything that can act as an always-on server. I elected to install Homebridge on my Synology NAS, which is always running as our house’s Plex media server anyway. You can find complete installation instructions for Homebridge on Synology here.
Then, the next step is to install the Homebridge plugin which knows how to connect to the Broadlink RM IR blaster.
Helpfully, the plugin has extensive documentation of its own, so it’s quite easy to follow along. To install the plugin, I opened up a terminal command line in the Homebridge console of the Synology web interface, and typed:
npm install homebridge-broadlink-rm
This downloads the appropriate package and installs it to your system automatically.
At this point, plug in your IR blaster in the same room as the accessory (or accessories) you intend to control. The blaster needs to have line-of-sight to the fan, but it doesn’t have to be dead on. The Broadlink RM is about the size of an Apple TV, so it’s quite small and discreet.
You have to use Broadlink’s app to connect the blaster to the WiFi network, but don’t bother actually setting up any accessories using Broadlink’s app. This is wholly separate to the Homebridge plugin configuration, so you don’t need to bother with it.
Homebridge is managed using a configuration file called config.json. You can access this file through the file system, and edit it using a text editor. (For my Synology setup, the easiest approach was to download the file through the web panel, edit it locally on my Mac, and then upload it back to the NAS’s storage.) This single file lists all the various parameters for all of the HomeKit accessories you want to expose.
For the Broadlink plugin, we need to add an entry to the platforms array of the JSON object and define the accessories inside of that. Again, refer to the plugin’s documentation pages to see example configuration snippets and explore all of the different customization options.
To get started, your platforms entry should look something like this:
Every time you make a change to config.json, you will need to restart the Homebridge server for it to apply the new configuration. For a Synology server, this simply means pressing a Restart button in the Homebridge package interface.
With the initial configuration like the above screenshot, you can now try accessing Homebridge from your Home app on the iPhone for the first time.
Homebridge exposes itself to the Home app as a hub. From within the Home app, press the ‘Add Accessory’ button and select the detected Homebridge hub. Enter the following 8-digit code to confirm: 031-45-154. (You can find this code at the top of your config.json file.)
Now that the Homebridge hub is inside HomeKit, any exported accessories will also be added. Any changes to Homebridge from now on will be reflected automatically inside the Home app.
Now, although we haven’t explicitly added any accessory objects to the config.json file yet, there will be a new accessory in your Home called ‘Learn’. This is added by the RM plugin. This switch is the key to translating the Infrared remote control buttons to actionable items.
What pressing the Learn switch does is puts the IR blaster into a special mode where it looks for any Infrared signals and outputs them to the Homebridge log. You need to write down the Infrared codes as we’ll need them later.
So, let’s say we are trying to record the power button of the remote. What we need to do first is press the Learn switch inside the Home app. Then, point our remote control at the IR blaster and press the power button. Look at the log and copy down the Infrared hex code (this will be a long hexadecimal sequence).
Repeat this process for every relevant button you want to expose to HomeKit. Don’t worry if you forget anything, you can always go back and learn again later. We are going to expose our fan as a basic on/off switch, so we only need the Infrared code that corresponds to the power command.
Once you have got a record of all the Infrared codes, you can go back to the config.json file and change the ‘hideLearnButton’ property from ‘false’ to ‘true’. This will remove the Learn accessory from the home.
Okay, so we have our Infrared code for power. Now what? Once again, we can look at the plugin documentation and work out the accessory object format that we need to put in the JSON.
The plugin can simulate accessories for many different types; outlets, switches, fans, lights, garage doors, locks, air conditioners, and shades. Each type has a different set of optional and required parameters, and it can get quite complicated.
The basic switch is all we need to power on and off the fan, and this requires only four properties: the name of the accessory, the semantic type (“switch”), the Infrared data to send when HomeKit turns the switch on, and the Infrared data to send when HomeKit turns the switch off.
For both the ‘on’ and ‘off’ cases, we just paste into the hex string for power that we learned earlier. The ‘persistState’ option determines what happens if the Homebridge server restarts; should it remember the previous on/off state of the accessory? If ‘persistState’ is ‘true’, it remembers the previous state. If ‘persistState’ is ‘false’, then the switch accessory will be considered off on each reboot of the server. For a fan, it probably makes more sense to persist the state so I set this to ‘true’.
Note that this accessories array goes inside the platform object. For the Broadlink plugin, we do not use the top-level accessories array.
We are finished with our configuration, so to declutter our Home app, we set the ‘hideLearnButton’ parameter to ‘true’ which will remove the Learn switch helper. Our final config.json files look something like this:
Assuming everything was typed in correctly, and there are no syntax errors like missing commas, you can now restart the Homebridge server one more time.
Once it fires up, there will now be a new Tower Fan accessory in your HomeKit home. It will look like a switch, but we can use the ‘Display As’ setting inside the Home app to make it look like a fan. You can freely rename the accessory inside the Home app, by the way, the config.json name is just to identify it inside Homebridge itself.
When the fan tile is pressed, HomeKit sends a message to Homebridge to turn the switch on. The plugin then finds the Infrared code for the ‘on’ state and beams that around the room through the IR blaster. If everything went smoothly, the fan will see the Infrared signal and turn itself on! Success. Tapping the tile again sends the off command and the fan stops spinning.
How well do all these hacks work?
I was a bit skeptical going into this that everything would work without a hitch. However, I have been running this exact arrangement for two weeks now without a single glitch or failure.
Controlling the fan with HomeKit is extremely responsive. I can tap the tile in the Home app or use Siri and toggle the fan immediately. The performance is honestly better than some certified HomeKit accessories I’ve tried. The IR blaster never fails to send its signal, and the fan always receives it and behaves accordingly.
Using Homebridge and an IR blaster to recreate a switch may seem like overkill, but this is just scratching the surface of what is possible.
You may have noticed that the plugin includes support for an actual “fan” accessory. This means you can use Infrared to control things like oscillation and fan speed. I actually got oscillation working but my downfall was the fan speed setting.
Unfortunately, the remote for my Honeywell fan only has one fan speed button. When you press the button, it sends out the same IR signal and the fan rotates through each of the three fan speeds. For the IR blaster to work with fan speed, you need to find a fan/remote combo that sends out a different IR signal for each speed; like one IR code for slow, one IR code for fast.
Because of this issue, I opted to simply expose the fan as a basic switch. If I wanted to, I could expose the fan speed command as a separate ‘toggle switch’ inside HomeKit. However, that is a little elegant, so for the time being, I am using it as a simple on/off switch only.
I sure hope that some company soon will actually make a real HomeKit fan, with certified support for all of HomeKit’s accessory services like power, fan speed, oscillation and swing mode direction. That would be the most ideal solution.
That being said, I have been genuinely surprised at how well the Homebridge community solution has performed. The description of the process makes it sound more difficult than it actually is. And of course, that configuration only has to happen once. I set it all up in a couple of hours. If you don’t have a programming background like me, it may be a bit more of a struggle to wrap your head around things like the JSON file format. But, Google is your friend. Homebridge is a surprisingly popular hack and there are a lot of tutorials and videos online that guide you through it.
Homebridge is an incredible Apple community achievement. Frankly, it is amazing that this stuff exists at all — all for free. The Broadlink RM IR blaster that was the glue of this particular integration is pretty inexpensive too.
If you are feeling adventurous, perhaps give Homebridge a shot.
Check out 9to5Mac on YouTube for more Apple news: