Off-the-shelf, consumer home automation has fallen into a pretty standard pattern. You have a smart device (like a lightbulb or door lock) that talks to some kind of hub that you put on your network. It communicates with a cloud service owned by the device vendor, and you interface with that service via a mobile app. This provides an easy out-of-the-box experience and lets the vendor iterate on its service both in the cloud and on mobile; however, this model has a lot of weaknesses and is extremely limiting with what it can do.
This model depends on the cloud for some of its logic, a cloud you aren't paying for upkeep on, which means the economics are entirely based on selling more devices to keep up this cloud. It also means that internet disruptions now degrade your home. You may lose functions inside your house if any part of the path from your home to that cloud service is disrupted. Also, you are taking inbound commands from the internet-at-large that determine how your home functions. Although doing this securely is possible, it creates added risk. And when it's done poorly, you end up with things like the Mirai botnet, which disrupted large chunks of the internet in the United States last fall.
This model also depends on a mobile app, which means your choice of products might be dictated by your choice of mobile device. The kind of automation you can build is dictated by the vendor and what they expose in their mobile app. Having any real integration between different platforms is unlikely. For example, if opening your door triggered your lamps to turn on that would be nice but, more likely than not, your connected doors and connected lights are on entirely different ecosystems.
Why can't it be seamless?
One of the main reasons we have this pattern is that last-foot networking and device discovery are fragmented. There are real reasons for that. At first, we thought Wi-Fi everywhere might be a great idea, but Wi-Fi is terrible in crowded environments. Also, secure Wi-Fi assumes there is someone able to type a Wi-Fi password into every device coming onto the network. That works great for a mobile phone or a laptop, but poorly for a lightbulb. The various workarounds to make that possible include having the lightbulb run a Wi-Fi access point that you attach to. Wi-Fi is also power hungry compared to other technology choices, so it isn't suitable for sensors running on AA batteries. Further, most home routers are configured for no more than 250 devices, which becomes a real consideration when rolling out connected devices.
Alternatives include X10 RF, Zigbee, Z-Wave, and even Bluetooth. All of them have different tradeoffs for security, discoverability, range, power consumption, and networking. Almost all are better than Wi-Fi. Some will do mesh networking out of the box. Some have active acknowledgment of messages, which is extremely important for building automation systems on top of them. To make any of these things accessible to consumers, you need something that bridges them back to the home network, so you must have a hub.
At that point, the vendor's option is writing all the logic into the hub and hoping that consumers upgrade their hubs regularly—which they won't—or keeping as much logic someplace offsite that lets the vendor continue iterating and improving the platform. It all makes a ton of sense from the vendor's perspective. But it extremely limits what you can do with these devices, and honestly, it makes them less appealing.
Enter Home Assistant
This is where Home Assistant comes into play. Home Assistant is an open source home automation hub that can be installed on a variety of devices—from full Linux systems to some network-attached storage (NAS) environments or even a Raspberry Pi. The project made great early decisions, such as writing in Python, which has made it easy for hundreds of people to add device support to the platform. The UI is based on Polymer, the Google library implementing the Web Components standard, so it looks clean and attractive out of the box. The internal state and event model is clean, which makes automating interactions between different components easy.
Out of the box, you get integrations with more than 700 different components, ranging from extremely popular platforms such as Hue, Nest, and Sonos, to a ton of platforms you've never heard of before. As much as possible, the project tries to auto-discover devices on your network and integrate them, using UPnP and other discovery protocols.
My first contribution to the project was a connector for the Proliphix thermostat. Proliphix makes industrial and commercial networked HVAC systems, and 10 years ago it attempted to get into the consumer space with an Ethernet-connected home thermostat, which I bought at the time. The company stopped making the product years ago, but it has a local web services API, so the device continues to function well. With about 100 lines of code, I was able to write a plugin for it to Home Assistant and contributed it upstream, where it was quickly accepted. At the time, it this was a quite old platform and the fact that I might be the only user didn't matter, as the Home Assistant project wants to work with any platform, no matter how obscure. That contribution, d the friendliness of the community got me hooked, and I've been a member of the development community ever since.
Automation in Home Assistant
To get a flavor of the kinds of automations you might have in Home Assistant, consider the following. I've got a screened porch that we use six months of the year as our dining room. I put Hue bulbs in the ceiling, have an Aeotec Z-Wave MultiSensor 6, and run my AV receiver's zone 2 for my outdoor speakers out there. I want the lights to turn on when people go into the porch at night, but not during the day, as that would be a pointless waste of energy. I also sometimes forget to turn off the stereo, so I would really like it if, when no one is out there, zone 2 would shut off as a courtesy to our neighbors.
scene: - name: Porch Lights On entities: script.porch_on: state: on switch.deck_lights_48: state: on - name: Porch Lights Off entities: light.porch_fan_1: state: off light.porch_fan_2: state: off light.porch_3: state: off light.porch_4: state: off switch.deck_lights_48: state: off media_player.living_room_stereo_zone_2: state: off script: porch_on: alias: "Turn On Porch Lights" sequence: - service: light.hue_activate_scene data: group_name: "Porch" scene_name: "Porch Orange" automation: - alias: Turn on porch lights after dark trigger: platform: sun event: sunset offset: "-1:00:00" condition: condition: and conditions: - condition: state entity_id: light.porch_fan_1 state: "off" - condition: state entity_id: binary_sensor.porch_ms6_1_129 state: "on" action: service: scene.turn_on entity_id: scene.porch_lights_on - alias: Turn on porch lights on motion trigger: platform: state entity_id: binary_sensor.porch_ms6_1_129 to: "on" condition: condition: and conditions: - condition: state entity_id: light.porch_fan_1 state: "off" - condition: sun after: sunset after_offset: "-1:00:00" action: service: scene.turn_on entity_id: scene.porch_lights_on - alias: Turn off porch trigger: platform: state entity_id: binary_sensor.porch_ms6_1_129 to: "off" action: service: scene.turn_on entity_id: scene.porch_lights_off
The complexity of this scenario definitely strains the YAML model a bit, but bear with it, as this complicated example shows a number of things.
Automations are triggered by an event, but in my case, I've got two potential triggers: that the motion sensor is tripped, and that it's late enough to turn on the lights. As such, I need to look for either event, and check that other one is in the expected state. I must also check that the lights are currently off, so that if I've manually turned them on, this automation won't randomly change their color or brightness.
The automation calls a scene, which turns on the deck lights (controlled by a Z-Wave switch), and calls a script that uses a scene name embedded in the Hue controller to turn on the lights. That same Hue scene is exposed to my Hue's tap switches and mobile app, so Home Assistant acts like a tap on that scene in either situation. In the off-automation rule, you can see the shutdown of the lights, the switch, and the receiver.
Note that this automation is integrating devices made by five different manufacturers—the Philips Hue light bulbs/hub, the Z-Wave hub, the Z-Wave switch, the Z-Wave sensor, and the audio receiver—and talking over three different networks—Zigbee, Z-Wave, and Ethernet—into one consistent feel. It's all done in a format that I can commit into a Git repository, so that when I make a change, I can easily revert if it breaks my house (which is really critical, because home automation bugs are some of the hardest things to debug and diagnose).
The Home Assistant community is vibrant and growing. The project does a release every two weeks and continues to gather contributors. Some of the challenges of complicated automation scenarios (like the one above) are being addressed by ecosystem projects like App Daemon, which let you write your automation code in Python. Because the Home Assistant daemon exposes the entire event and state structure as a web service, it's really easy to build these kinds of custom add-ons or even your own specialized UI for the environment.
If you are thinking about dipping your toes into the home automation space, make sure to check out the Home Assistant project. Putting open source at the heart of your home automation will let you build it at your pace, adapt over time, and ensure you have control over critical resources like your own home.
This article is based on Sean's OpenWest talk, Why we can't have the Internet of Nice Things: A home automation primer. OpenWest will be held July 12-15, 2017 in Salt Lake City, Utah.