Your own smart hub: Meet Home Assistant

The Internet of Things (IoT) push continues to expand as tens of thousands of different internet-enabled devices from light bulbs to dishwashers reach consumers’ homes. Home Assistant is an open-source project to make the most of all of those devices, potentially with no data being shared with third parties.

Generally speaking, IoT devices are most useful when operating in coordination with each other. While decentralized systems are possible, keeping all of these devices coordinated in the effort to make a “smart house” generally uses a centralized server (or “smart hub”) — a reality not lost on Apple, Amazon, and Google among others, who all provide various solutions to the problem.

For the privacy and security minded however, those solutions are problematic because they send private data to centralized servers for processing simply to turn on your lights. That these solutions are also closed-source black boxes does not help matters. Home Assistant is an Apache-licensed project to address this problem, started by Paulus Schoutsen, to provide a private centralized hub for automation and communication between a home’s various IoT devices. Schoutsen is also founder of Nabu Casa, Inc. providing commercial backing for the project. The platform is popular and active, approaching its 600th release from nearly 2,000 contributors to its core on GitHub. Integrations between various IoT platforms and Home Assistant are provided by its 1,600 available components written by the various contributors.

Meet Home Assistant

Home Assistant strives to be a user-friendly tool, with recent releases investing significantly in ease-of-use and front-end features. This includes technologies like auto-discovery of a wide range of IoT devices, built-in configuration editors, and an interface editing tool called Lovelace. Under the hood, Home Assistant is a Python 3 code base with configurations managed through YAML files for those who prefer to work from their own editor instead.

From a developer’s perspective, Home Assistant has a well-documented API and architecture. It provides a web-based interface to manage the home, and mobile applications for both Android and iOS. Architecturally, it is an event-driven platform and state machine where various “entities” are managed by the system. Entities are arbitrary “things” and take many forms. They can be concrete devices, such as a particular light bulb, internet-based information like a weather report, or even a boolean indicating the presence of a specific phone’s MAC address on the local network.

In Home Assistant, components expose entities and define services. Not to be confused with API web services, Home Assistant services enable actions related to the nature of the component, which may or may not use an underlying API. These components, also written in Python, are really the heart of the Home Assistant ecosystem. Components are responsible for integrating with third-party technologies (such as a smart bulb provider’s API); executing the necessary API calls to make sure the device reflects the desired state as stored in a Home Assistant entity and vice versa. Components are also not limited to remote APIs and devices either; There are components that expose services for shell commands, standalone Python scripts, and other interactions with the local machine as well.

Components are downloaded and installed by Home Assistant on demand from the library managed by the Home Assistant project. If someone hasn’t already written a component for a particular API integration or task, a custom component can be implemented in Python for your specific installation.

Tying together entities and services are automations, which are triggered based on events related to the state of one or more entities. Automations in turn perform actions by calling Home Assistant services to accomplish things such as turning on a light bulb. They also support conditional execution, one example being the creation of an automation that only executes on a weekend.

Getting started

For those who would like to try Home Assistant, the recommended hardware is a Raspberry Pi 4 Model B with one of the provided SD card images available here. For those who would like to install it on an existing, more traditional Linux host, the options available are a Docker image or installation using pip.

As previously stated, configuration values are managed in YAML. Editing the configuration can be done via the provided web interface, or directly editing of the instance’s configuration.yaml. A separate secrets.yaml holds credentials and other sensitive information. Since the configuration is a collection of YAML files, it is convenient and recommended to track changes via a Git repository.

As an example of how configuration works, we are going to use the ecobee component. This component enables the integration of data, as well as API calls, from an Ecobee thermostat into Home Assistant entities and services. It starts with defining the component in configuration.yaml:

    ecobee:
        api_key !secret ecobee_api_key

Where ecobee_api_key is defined in secrets.yaml. Adding the ecobee component and restarting Home Assistant will automatically download and install the necessary packages for the component to function.

With the component enabled, entities for sensors can be created to extract specific pieces of information. For example, below is the definition of a sensor representing the HVAC fan that the Ecobee controls:

    sensor:
      - platform: template
        sensors:
          my_hvac_fan:
            value_template: "{{ states.climate.home.attributes.fan }}"

Above we define a new sensor using the template platform, indicating the value will come from a template. Platforms in Home Assistant categorize the types of configuration options and behaviors expected. For the template platform, it tells Home Assistant to extract the sensor’s value from value_template.

It is worth noting that value_template uses the Jinja2 template engine under the hood, enabling sensors to normalize or implement logic for sensor values. In this example, we extract the value from an attribute of the state provided by the ecobee component. Templates can also be more complicated as needed (taken from my own setup of Home Assistant).

Once defined, this sensor’s value can now be referenced by the entity identifier sensors.my_hvac_fan. Entities can be rendered to the web and mobile interface, their changes can be stored and graphed over time, and they can be used as a trigger for automations. Home Assistant provides a reasonable default rendering for an entity value in most cases and can be customized extensively as desired.

Automations provide the rules and actions to tie entities together. Each automation has three main segments: The trigger(s) for the automation, the condition(s) of the automation, and the action(s) to take if the conditions are met.

A typical automation looks like this:

    automation:
      - alias: 'Light on in the evening'
        trigger:
          - platform: sun
            event: sunset
            offset: '-01:00:00'
          - platform: state
            entity_id: person.john
            to: 'home'
        condition:
          - condition: time
            after: '16:00:00'
            before: '23:00:00'
        action:
          service: homeassistant.turn_on
          entity_id: group.living_room

In this automation we are using the built in sun entity to trigger our automation one hour before sunset (based on the time zone and location information configured in Home Assistant) along with a person entity (me). In Home Assistant a person entity is, among other things, a collection of device trackers used in presence tracking. Like some of the core entities in Home Assistant, the person entity type is an abstraction of values taken from other entity sources. For example the location of a person entity can be sourced from the devices connected to the LAN, the mobile app on a phone, or other similar sources assigned to that person.

Returning to the example, the automation is triggered by two states: At sunset minus an hour, and if the person is home. If both conditions are true, the automation is triggered and a check against the conditions is performed. If the conditions are met (in this case, the current time is within a range), then the action(s) are executed. The action for this automation is the homeassistant.turn_on service, which is given an elsewhere-defined target entity group.living_room to turn on. Note also that automations themselves are entities, and can be interacted with by other automations adding to their versatility. One common technique is to enable and disable one automation based on the actions of another automation.

Privacy and security

A key benefit to Home Assistant is not that it assures privacy for a smart home, rather that it gives the user a choice in the matter unlike commercial alternatives. That said, while Home Assistant provides the framework to implement a smart home hub completely free of the cloud, note that many IoT devices do not provide a way to control them in any other way. Some products are better than others in this regard, so it is an important consideration to keep in mind when choosing the various devices to use on the platform.

The other side of the coin is security, as one cannot have privacy unless they also have security. Various recommendations are provided by the project to ensure that an instance is secure, including keeping pace with releases and security fixes of the code base itself. Since Home Assistant is a web application (using APIs to communicate with the mobile applications over HTTP), all of the standard security practices normally encouraged apply. Accessing Home Assistant remotely requires access to the host machine remotely. In the case of the mobile applications, Home Assistant either must be exposed on a public IP or otherwise accessible by secure tunnel to function.

Home Assistant does make efforts to ensure that the platform is secure. Security fixes are common (but not too common) in releases, and the project advertises how to let it know if a new security vulnerability is discovered.

That being said, Home Assistant is typically not the only technology powering the smart home stack. Message brokers such as a MQTT server and database packages are commonly needed. Due consideration to ensure their security is important as well. Recent reporting of nearly 50,000 MQTT servers being exposed to the public indicates improper configuration of secondary services is a major concern for IoT deployments in general.

Learning more

If Home Assistant looks like a promising solution in the smart home space, then there are plenty of resources to get started with. Home Assistant has a large community of users to learn from and maintains a brisk release cycle of new features. The user documentation is generally acceptable and a great reference as well. For those with the Python skills to get involved, the developer portal has everything needed to get started writing components; and there is a popular Discord chat room if needed.

Home Assistant appears to be a lively project and worth keeping an eye on as a front-runner in the open-source IoT space. At least for the moment, it does also require a meaningful amount of technical know-how to set up. This does, however, seem likely to change considering the investments the project is making to create a more user-friendly experience. Readers who have avoided the home-automation bandwagon due to privacy concerns will find the project worth a look, as will as anyone interested in controlling the technology behind their own smart hub.