Installing Home Assistant, Mosquitto & AppDaemon on Debian

Update 2021-03-24: Since writing this article, the dependencies for Home Assistant haven’t changed much, however new VM images are now being released that have all the work done for you. I’d now reccomend using one of these instead of the steps detailed below.

As part of some hardware upgrades, I’m moving Home Assistant and it’s associated programs off it’s shared box onto a dedicated VM. This means a fresh install of everything. Whilst docker would usually be an ideal candidate for this, I decided against it because I use a few custom components and troubleshooting these is a lot easier without Docker.

Preparing the VM

Nothing too special here, I used the latest network install media for Debian Buster (10). The netinst media is particularly useful if you have a fast internet connection, as the latest version of each package is downloaded before installing). Unfortunately this does mean slowing internet connections or offline installs are out of the question. If you’re doing a large number of installs, a local debian repository should work with the netinst media, but I have yet to test this.

Once this was done there’s the usual routine of adding SSH keys (yay for Ansible), setting up backups (Veeam works nicely), and installing Monitoring (Zabbix is awesome). I didn’t pay much attention to the system Python version, as Debian still ships with 3.5 which Home Assistant no longer supports.

Installing Dependencies

There are a number of global dependencies we can install through Apt to save time in the future. Here’s the command I eventually came up with to get everything up and running

apt install autoconf build-essential libbz2-dev libffi-dev libreadline-dev libsqlite3-dev libssl-dev sudo zlib1g-dev libopenzwave1.5-dev nmap libudev-dev

Installing Home Assistant

By this point, I hope I don’t have to explain what Home Assistant is. In short, it’s some of the best home automation and BMS software out there. Unfortunately the latest versions have some dependency issues with AppDaemon (despite being designed to work together) and has now dropped support for Python 3.5. Because of this, we’ll install a separate version of Python for each of them.

Create a system account

First, we’ll create a new user to run the service. Useradd can do most of the work for us, using these parameters:

  • -r Create a system account, disables password ageing and uses a lower ID
  • -m Create the user’s home directory
  • -d Specify the location of the home directory
  • -s The login shell (or lack thereof) for the user

Overall, that gives us this:

useradd -rmd /var/lib/homeassistant -s /bin/nologin homeassistant

From here on, everything will be run from this user account, because nothing else needs to use it’s version of Python or the libraries. To make this easier, we can use sudo to run bash as Home Assistant’s account:

sudo -u homeassistant bash

Install Python

It’s always handy when people scripts exist to do the work for you, and installing Python is no different. To handle the installation, we turn to PyEnv. Using these commands we can install PyEnv, and then use it to install the latest version of Python.

curl -s -S -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
~/.pyenv/bin/pyenv install 3.8.0

Install Home Assistant

Now we have a working install of Python, Home Assistant can be installed using it’s version of pip

~/.pyenv/versions/3.8.0/bin/pip install homeassistant

Starting automatically with systemd

There are lots of arguments in favour of and against systemd, though from my point of view the benefits outweigh the disadvantages. For example, here we’re going to tell systemd to start home assistant when the system boots, but after the network and Z-Wave adapter are ready this was causing a few issues for me, so I’ve removed it for now.

[Unit]
Description=Home Assistant
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=homeassistant
ExecStart=/var/lib/homeassistant/.pyenv/versions/3.8.0/bin/hass -c /var/lib/homeassistant/config
ExecStartPre=+/bin/chown -R homeassistant:homeassistant /var/lib/homeassistant

[Install]
WantedBy=multi-user.target

Installing Mosquitto

Out of the three Mosquitto is by far the easiest to install, and that’s saying something

apt install mosquitto

And that’s it. Told you it was simple. As with all of these, the configuration will need adjusting to suit your needs, but that’s well covered by the relevent documentation.

Installing AppDaemon

AppDaemon is a companion for home assistant, and is capable of doing much more powerful automations using python modules & scripts.

The first part of this is very similar to the Home Assistant installation. I’m doing them using separate Python versions and environments because there are some dependency issues between the two. Keeping the environments completely separate will make updating in the future much easier.

Create a system account

Same as for the Home Assistant user, Debian will do most of the work for us with this command:

useradd -rmd /var/lib/appdaemon -s /bin/nologin appdaemon 

Most of the following commands needs to be run as the appdaemon user. We can switch to it using sudo to explicitly run Bash

sudo -u appdaemon bash

Install Python

Again, we’ll use pyenv to install the latest version of Python for the service account

curl -s -S -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
~/.pyenv/bin/pyenv install 3.8.0

Install AppDaemon

Again this is fairly simple. AppDaemon is available through PyPi, so it can be installed using the Pip command:

~/.pyenv/versions/3.8.0/bin/pip install appdaemon

Starting automatically with systemd

Finally, we can use systemd to automatically start appdaemon with the server. The below unit file can be placed in /etc/systemd/system/appdaemon.service

[Unit]
Description=AppDaemon
[email protected]

[Service]
Type=simple
User=appdaemon
ExecStart=/var/lib/appdaemon/.pyenv/versions/3.8.0/bin/appdaemon -c /var/lib/appdaemon/config
ExecStartPre=+/bin/chown -R appdaemon:appdaemon /var/lib/appdaemon

[Install]
WantedBy=multi-user.target

There’s a couple of non-obvious options in here, so let’s go through them all:

  • After… – This makes sure appdaemon doesn’t start until Home Assistant is up and running
  • ExecStartPre… – Like many users I store my Home Assistant configuration in Git. AppDaemon requires permissions on it’s configuration file, and modifying them through git as another user may accidentally remove the permissions. This command explicitly grants those permissions each time AppDaemon starts.

Installing/configuring HASS Apps, or any other AppDaemon app

One of my main uses of AppDaemon is Schedy, part of HASS Apps. Though this is just an example, and should work for any AppDaemon-powered app. First we install HASS Apps:

~/.pyenv/versions/3.8.0/bin/pip install hass-apps

Now we can configure AppDaemon, using the config file /var/lib/appdaemon/config/appdaemon.yaml and it’s matching secrets file.

---
appdaemon:
  threads: 10
  plugins:
    HASS:
      type: hass
      ha_url: !secret hass_url
      token: !secret hass_key

Then we need to load the HASS Apps module into AppDaemon. This is done using a shim in /var/lib/appdaemon/config/apps/hass_apps_loader.py

from hass_apps.loader import *

Now the important bit, we tell AppDaemon to use Schedy and what schedules we want. This goes in /var/lib/appdaemon/config/apps/schedy.yaml

---
schedy_heating:
  module: hass_apps_loader
  class: SchedyApp
  actor_type: thermostat
  rooms:
    everywhere:
      rescheduling_delay: 120
      actors:
        climate.heating:
      schedule:
        - v: 20
          rules:
            - {start: "18:00", end: "20:30"}
            - weekdays: 1-5
              rules:
                - {start: "06:00", end: "08:00"}
            - weekdays: 6-7
              rules:
                - {start: "07:00", end: "09:00"}
        - v: 18

Turning Everything On

Now all of our software is in place, and has a basic starting configuration, let’s tell systemd to turn everything on!

systemctl enable --now mosquitto
systemctl enable --now homeassistant
systemctl enable --now appdaemon

Home assistant will take a while to start for the first time, so now is ideal to go and make a cup of tea. In my case, this took over 90 minutes due to the complexity of my particular setup.

Leave a Reply

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