How I use Raspberry Pis for HomeKit automation by Adam Argo

(77 views)

I saw a HN post titled How I use my Raspberry Pis to help me work on with my side projects, which to me didn’t really seem to demonstrate the power of the Pi platform, like the GPIO pins — it was all just software you can run on a Linux machine. I thought what I’m doing with my Raspberry Pis is a little more interesting and takes advantage of its unique features, and thought I’d write about that. I use Raspberry Pis to run a few pieces of software to bridge incompatible devices (and homemade devices, including a model railroad switch controller, described below) to my HomeKit home automation system. Some work well, some not as much, but the Pis are great for bridging that compatibility gap. For the stuff I made, I link to GitHub repos that have the code that runs them.

If you’re already familiar with HomeKit and Homebridge and just want to see the meatier projects, I’d recommend skipping to the model train switch or the fireplace sections.

The Three Pis

  • Garage
  • Model Train Switch
  • Fireplace

Why HomeKit?

There are a ton of options to choose from when it comes which home automation platform you want to choose, whether you run your own automation server or use a cloud platform like Alexa. There are pros and cons to each, but ultimately I went with HomeKit because it doesn’t require me to maintain a server (it uses Apple TVs as hubs, and if you have more than one, the others work as standbys), devices talk to the hub vs. a cloud service so they’re faster to respond (but will also work over the Internet), and because my wife and I both use Apple devices, and things usually Just Work with them. It was important to me that she be able to use it, too, because if it was finicky, she wouldn’t. Most MFi (Apple-certified) devices generally Just Work. My HomeKit setup has about 85 separate services registered now (devices expose one or more service), and given that many devices, I wanted to minimize the amount of futzing I had to do with them.

This limits one’s options a little bit (HomeKit isn’t as widely supported as say, Alexa or Google Home), and sometimes there will be devices that just Don’t Work (i.e., they provide no HomeKit interface). While I took care to buy HomeKit-compatible devices where possible (light switches, thermostat, motion sensors, etc.), I had a few things that weren’t compatible at all. Enter Homebridge, a Node app that emulates the HomeKit API and has a large collection of plugins to interface with non-HomeKit devices. I use Raspberry Pis to run Homebridge and control off-the-shelf devices I have already, and also create my own “compatible” devices that integrate seamlessly with my HomeKit setup.

Garage

The garage Pi is admittedly just using the Pi as a Linux machine without making any special use of the board. It runs the Homebridge server, and controls a few different devices. My CenturyLink fiber ONT and router are also out there, so it’s a good spot for another little network appliance box. This could be any Linux machine, really, but in my case it works fine with just a Pi, and controls a few things:

Garage Door Opener

I have a LiftMaster garage door opener with their MyQ WiFi feature. They offer a $70 box that will bridge this into HomeKit, but why pay $70 when you can do it for free with Homebridge? I use the homebridge-liftmaster2 plugin and am overall happy with it.

The caveat with this plugin is that it polls the MyQ service relatively infrequently (default is 5 minutes), so you may miss notifications about your garage door if it’s opened and closed between polling intervals. However, it is still useful to have HomeKit open or close it (like walking out the door and saying “open the garage” to Siri), as well as if you were to run a scene such as “Good Night” that ensured your garage door was actually shut for the night. The device you can purchase from LiftMaster would not have these issues as all state changes would instantly get sent to HomeKit over the local network.

UPDATE: I broke down and bought the device from Chamberlain to make this a legitimate HomeKit device. I found the polling interval to be annoying enough to spend the money on the real accessory.

Security Cameras

I have a Lorex NVR which uses 2K resolution PoE IP cameras. The NVR itself has no HomeKit (or Alexa, or Google, anything else) support, but it does expose an RTSP endpoint for each camera. After doing some extensive Googling to find the right RTSP URL for my device, I used the homebridge-camera-ffmpeg plugin to handle transcoding the video and letting it stream via HomeKit. The Raspberry Pi 3 B is powerful enough to do the transcoding on the device at 720p. Unfortunately, there’s about a 5 second delay when streaming video (as opposed to just watching the cameras directly on the Lorex app), but it is nice to have it show a snapshot of the cameras at a glance in the Home app.

Alarm System

My house came pre-wired with a standard Honeywell/Ademco alarm system, so I couldn’t take advantage of any of the new HomeKit-compatible systems, and just had a company enable monitoring service to it. They provide access to an Alarm.com account, and via the homebridge-node-alarm-dot-complugin, I can not only arm/disarm/check the status of the system, I can also see the status of the hard-wired contact sensors in the doors and windows, so I know if anything was left open. Like the garage door, there’s a little delay updating state with this one (default is 60 seconds, which mostly affects contact sensor polling), but issuing the arm and disarm commands take about the same time as the Alarm.com website (the system communicates via cellular and can take a little time to reach).

AlarmDecoder.com sells a product that lets you use the Pi to interface with the alarm system, which could then talk to Homebridge; I am considering purchasing that as then I would not have any of the delay issues I currently have.

Model Train Switch Pi

The switch in action

The Pi, relay board, and circuit for controlling the turnouts

My dad is a model train buff, and gave me some of his old LGBG-scale trains, which growing up we always put around the tree at Christmas. This year I finally owned a big enough house to have a decent layout to put around our tree, so I dug them out and set it up. One thing bugged me, though — all the turnout switches he gave me were electric, but I had no control unit. To buy one from a model railroad store is about $80, and they only work when you’re in physical proximity to them. Then I wondered: how can I do this from HomeKit?

I did some research on what it would take to energize the switch motors. They are 16V AC, and the OEM control unit uses momentary toggle switches to control them. I used the Pi’s GPIO pins to wire up a circuit to simulate those using a couple relays on a pre-built relay board and some diodes. Then I wrote a small Go app to interface with the GPIO pins and expose an HTTP API. This lets me control four different switches. Each switch looks like a normal light switch in the Home app, and they all work with Siri. The server was written to be compatible with homebridge-http-switch. You can find the code and circuit diagram below. The relay board was only $7 on Amazon. So for about $70 ($40 for the Pi, $7 for the relay board and $20 for the miscellaneous parts in the picture), I can control the train switches from my phone, vs. $80 for just a manual one! And because it’s a 3 B, the built-in WiFi means it Just Works wherever I put it.

What it looks like in the Home app

Fireplace Pi

While having a real fireplace (or even a gas fireplace) would be nice, I have an electric one, which is mostly just for decoration. However, the thing I always disliked about it was that it was only controllable via an IR remote, and I really wanted to be able to use it with HomeKit, so I used a Pi to do this too.

Using a Pi IR transceiver shield with the LIRC package, I was able to learn the commands of the IR remote for the fireplace and then send them via LIRC’s irsend command. This is all wrapped in another Go app exposing an API similar to the train controller above that automates the sending of the IR commands. Overall a pretty straightforward project, but transmitting the IR commands of cheap remotes like this can be a little challenging; you have to capture the signal in raw mode and send it on repeat to get it to register.

This Pi lives on an end table in the living room in an inconspicuous enclosure that has some additional room to house the IR shield. While sending IR commands works with it, I still had one problem to solve…

Device State and IR

The issue with using IR devices — especially ones that don’t have discrete on and off buttons — is that you never know if the device is actually on or off. I thought it would be cool to try to learn something about TensorFlow and train a model that can tell by a photo taken by the Pi whether the fireplace is on or off.

Some of the photos I took for the model

I actually made good progress with this; I was able to train a model using photos I took with my iPhone of the fireplace, and with 97% accuracy it could classify it as being on or off. I used an app that took photos in short intervals and did so from different angles in different light conditions. In all I had about 300 photos (about 150 of on and off) to train it with. I exported the video from my phone to my computer, and used VLC to generate a separate image for every frame. When I started testing it with new pictures I took that weren’t in the training or validation set and it was working properly, I was extremely excited.

My excitement unfortunately didn’t last very long. Beyond the initial pain of getting TensorFlow running on the Pi (an endeavor worthy of its own article), I ran into issues after switching to using the Raspberry Pi camera module. With it, the classifier was totally wrong. The camera is not particularly great, especially in low light situations (like a dim living room). The fake “fire” barely showed up at all in images it captured. I tried tweaking every knob I could on the camera exposure settings, but alas, an $11 camera just doesn’t function that well in poor lighting conditions compared to the iPhone XS.

There are probably a few things I could do differently that might help, like train on images from the Pi vs the iPhone, but I really wanted something that Just Worked (and worked at all, really). Maybe I’ll get back to this another time, but I pivoted to using a different means to monitor the state of the fireplace.

Energy Monitoring

I probably should have gone this route to begin with, but I realized I could use a smart plug with energy monitoring to determine whether the fireplace was on or not. Simple idea: if the outlet says it’s consuming energy, it’s on, otherwise it’s off.

The criteria for the plug I wanted is actually a little difficult to find: I wanted something that I could access programmatically, and could be accessed locally. The vast majority of WiFi smart home devices connect through some sort of cloud service and don’t expose an interface on your home network, which at the very least creates a latency issue, if not security issues as well. After searching for awhile, I came across the TP-LINK HS110Smart Plug. It has energy monitoring built in, supports 15A devices, and can be accessed directly over the LAN (some enterprising individuals reverse-engineered their protocol, which may potentially be concerning for some). Either way, it suited my needs for this.

I modified my little API server to track the state of the fireplace by querying the plug (fortunately, there’s a package for that). The plug API returns power usage in watts, so I use that to effectively make discrete on/off commands. It first checks if the power level is where it would expect to be for the desired state, and if not, sends the IR command and then waits until the energy usage reaches the desired state before returning.

Why not manage the heater too?

The fireplace has a built-in heater that has two modes (low and high) and an off position (i.e., the flame can be turned on without heat for aesthetics). This too is controlled by the IR remote, with no discrete mechanism for telling it which position to be in — it simply cycles through the heat settings. However, with the energy monitoring in place, I realized I can look at the power consumption and use that to determine if just the flame is on, it’s on low, or it’s on high (they all have distinct power usage levels).

I again modified the API to handle state transitions between the various heat modes. If you want to go from low heat to no heat, you have to cycle through high heat first, so I have the app send the heater IR command and ensure it gets to the energy usage that I know indicates high heat is on, and once there cycle it back to off. There’s a little delay going from off to low, as it takes awhile for the heater to kick in (I’m not exactly sure why), but the transition from low to high is immediate, and high to off is also very fast.

Then came the challenge of integrating this into HomeKit. It’s not a typical on/off device — depending on how you look at it, there are four states: off, flame only, low heat, high heat (the flames are always on and can’t be turned off separately from the heater). I played around with some different ideas, including trying to set it up as a dimmer switch where it had a few bucketed ranges (although I couldn’t find a Homebridge plugin that worked). I ended up setting up the different fireplace states as discrete switches, and then letting the code handle whatever necessary state transitions it needs to do to get there. Now I have three switches for the fireplace in HomeKit — lights, low heat, and high heat. This isn’t ideal, but given what it is, I think it works well enough.

This case has some extra space on top for the IR shield; I had to cut out a small hole in it for the IR emitter to be able to “see” the fireplace.

Wrapping Up

The Pi is a great device because it’s so versatile. It’s amazing how convenient having a tiny WiFi-enabled Linux machine with GPIO pins can be. It’s powerful enough to run complex software — even TensorFlow models. It’s also great as just a glue device to stitch together some various parts and pieces to solve a problem. The Pi enables me to use unsupported devices with HomeKit, as well as build completely new devices and make it work with them, too.


Originally posted: https://medium.com/@adamargo/how-i-use-raspberry-pis-for-homekit-automation-ed69df8d8be7

June 21, 2019
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
© HAKIN9 MEDIA SP. Z O.O. SP. K. 2023