Home Assistant is a marvelous app that makes your home smarter. It’s also a raging pain in the ass if you’re an early adopter and actually have set things up already. This post is not only a helpful guide for how to update and use the latest flavor of Home Assistant, it’s a lovely well for me to scream into instead of yelling obscenities at the squirrels in the backyard.
A lot of this is going to be date dependent, so denizens of the future you’re probably going to have an easier time of things.
Recently, HomeAssistant has gotten a lot of work done (i’ll blame the pandemic and idle developers, which are sometimes the devil’s playground). To that end, it requires Python 3.8+.
Problem #1: Debian & Python 3.7
As of this date, if you’re running Raspbian/Raspberry Pi OS on your Raspberry Pi, the underlying system you’re running is Debian Buster1. That means the Python you’ve got installed is Python 3.7.3. As of December 2020, HomeAssistant considers Python 3.7 obsolete and stopped supporting it2. You could download the source for Python, and compile it locally. You could also walk from Utqiagvik, Alaska to Tierra del Fuego. You might want to consider not doing that though.
When a version of python becomes obsolete, it’s not the main program that breaks. No, that honor goes to a percentage of the many, many small libraries that the software now uses and drags in like a hoarder at an unguarded Costco. For me, it was about two months in when i discovered that one of my webcams no longer worked.
Fortunately, there is a solution, kind of. The HomeAssistant folks offer multiple ways to install, including an SD image (or if you’re like me and you have other programs running on your Pi, because, well, you can and HomeAssistant isn’t THAT big of a pig), you can run it inside of a Docker image.
Docker is free (regardless of the impression you get from the site). And while you can install it using
apt, i’d actually encourage you to install it using the (ugh3) docker install script at https://get.docker.com. If you prefer a few more steps, you can also follow the Debian instructions.
Problem #2: Docker
Docker is clever because it uses a combination of virtual images in order to run applications in a sandbox. It makes up for that cleverness by eating disk space and being horrifically obtuse about how it should be used. Suffice to say that you have
images which are the bits of stuff that get run to do things and
containers which are the actual, running programs. That will become important in a bit, but it’s also worth noting that you really need to keep an eye on how much space the images are eating up. There are lots of documents you can read, but suffice to say that
$ docker container prune
$ docker image prune
are your bestest friends4.
Problem #3: node
Ah, but wait! There may be something else you’ll need before you can get going. HomeAssistant has moved onto a more modern (pronounced: “sə-pôrt′-ed“) Z-Wave integration system called “ZWave-js”. This is a node.js app. Again, the Debian default is going to be old. So, instead, grab a copy from the download page (for Raspberry Pi, you want the ARMv7 one). Once you have it, you can
tar -xvf node-*.tar.xz which will extract node into it’s own directory. You might also need to
sudo apt install xz-utils to get the
xz decompression tool for
tar. You can move that wherever (i usually keep those in
$HOME/app). You may also want to add
$HOME/node-v-linux-armv71/bin to your
$PATH, since you’re going to need those in a bit.
Node helpfully includes
npm or the Node Package Manager. This nifty little tool allows you to install packages. What it doesn’t make frightfully clear is that the packages
npm installs go into
`pwd`/node_modules so you can wind up creating lots of
node_modules directories as you try to figure out where the hell things are installed. For now, go to your home directory and run these there.
$ npm install zwave-js
$ npm install @zwave-js/server
This should install some programs and in
node_modules/.bin/ there should be a
Well, sort of “yay”.
zwave-server needs the device address for your ZWave USB dongle. You can get this from your old
.homeassistant/configuration.yaml file. For me, it’s under
Yours is probably under something like
/dev/ttyAMA0 or something more sane.
Once you have the device path you can then fire up
$ node_modules/.bin/zwave-server /dev/serial/by-id/usb-0658_0200-1f005
and be awestruck by just how chatty this thing is. You’ll then kill it and add
2>&1 > /dev/null & to the command so that it runs in the background and all the chatter goes to
/dev/null, because there’s a lot of it,
--help do nothing, and i just want to get things running.
Problem #3: ZWave
Wait, didn’t we just solve that? We solved about half of that.
The old ZWave config system is deprecated. While zwave-js does an amazing job recovering and loading devices so you don’t have to re-sync them, there are a few things you still need.
- Your system security key. If you have a security key (because you have locks or garage door openers or something) you’re going to need the code for it. Hopefully you have it, still. You can sometimes also get it out of the zwave logs.
- Your friendly device names. HomeAssistant’s integration doesn’t use the friendlier device names when listing things out. You will probably have to reset them based on the device node-ids or device ids. Both of these are in the old configuration data. You can also fire up the old version of HomeAssistant, grab a notepad and take notes.
Once you’ve got your list of ZWave things, drop the old, deprecated ZWave integration. Comment out the old
zwave: section from the configuration.yaml file.
Now you should be able to get HomeAssistant started.
To start the HomeAssistant docker run
$ docker run \
-v $HOME/.homeassistant:/config \
-v /etc/localtime:/etc/localtime:ro \
Remove the container once it exits
Run in the background (daemon)
Name the container “home-assistant”
Link the config directory as
Link the time to the system time
Use host networking
What you want to run
Give that a few and you should be able to bring up the admin panel on port
:8123 like before. You’ll need to enable the ZWave-JS integration under
/config/integrations. If the
zwave-server above is running, you should be able to just connect to the default websocket port. Once that’s done and the device list is loaded, simply walk the displayed list setting each entity id back to whatever you had originally set it. They should show up on the Lovelace UI, work in scripts and all the other joy, just like before.
There may be a few other things you’ll do, but it’s getting late and my tequila bottle is empty and i need to go make some tacos for dinner, so you’re on your own.
Footnotes & snark
1Debian is stable. It wants to be very stable. i’m talking “fixed to the bedrock” stable, and much like the bedrock, it tends to move at a geological scale. This means that stuff on Debian tends to be a bit “legacy”, and they don’t release new versions very often. It’s rumored that they only do so once the magic smoke released from overclocking a VT-100 terminal is white.
2 One might ask “wait, why did HomeAssistant basically drop support for Raspberry Pi?” It’s a good question, but basically works out that 3.7.3 was releases mid 2018 and there’s a fair bit of cruft in it compared with later releases. i’ll note that 3.7.3 is still supported until 2023, and just dumping support for it is kinda rude to folks, but they do suggest docker and docker adds a fairly minimal amount of overhead. At this point, it’s looking more and more likely that running apps in some sort of sandbox, be it docker, flatpak, snap or something else will probably keep OS’s secure enough from devs that want to play with all the shiny, new toys.
3 Yes, i get it. Giving folks a clever shell script they can run in
sudo sure is a fun and easy way to get things done. It’s also like tossing a stranger the keys to your car so he can go get your take-away order. It’s usually safe, but there’s the off chance that he runs over a kindergarten class or uses it in a bank heist.
4 i am absolutely not kidding about this. Dockers default setting is to fill your disk with old crap. Calling
prune goes through and can delete gigabytes of old image data. You want to do that before your computer locks up because / is out of space. Hell, you want to keep a close eye on things using
docker image ls -a because docker doesn’t always show you everything, and docker can keep lots of old versions of packages lying around for reasons.
5 So, yeah, fun fact. If you try to later switch to a different ZWave controller USB, it won’t work because the devices and protocol specify the controller, not the local settings. Oh, but it may screw up your local
/dev list forcing you to do crap like this because the
/dev/ttyUSB0 device is now pointing to an invalid endpoint and something keeps resetting it. It’s super annoying.
So, one of the HomeAssistant folks reached out and asked “Why aren’t you running the Home Assistant Operating System, which handles a fair bit of this for me.
The short answer is mostly FUD on my part, since i’ve not dug super deep into the OS option and been burned by similar things in the past, but a bit more than that too.
i may convert everything over to HAOS (trying to backronym a C to the start of that for some reason), but there are a few personal caveats:
- This would basically be a from scratch rebuild. Much of my HASS is still YAML based, so to do this right, i’d have to rebuild it all in the native UI. Not impossible, but a lot of work.
- i run a few things on this machine. It’s my understanding that HAOS is basically Alpine running a slew of Docker images, and it’s fairly easy to convert things into Dockers to run on it. This may mean rebuilding stuff like PiHole, as well as my semi-hacky python scripts, and whatever other bits i might need. Again, not impossible, but a lot of work.
- Much of the logging does not get written to the SD Card. i’ve gone in and softlinked much of it to write to a USB3 drive attached to the Pi. This is because Linux is “write heavy” and that can burn through SD card write cycles pretty quickly. Again, not impossible (since i can probably mount the USB drive and alter Docker files configs to use that drive), but … well, you can see the pattern emerging.
i have no doubt that things would be a lot easier if i were to have started from scratch yesterday. i didn’t. There’s definitely sunk cost at play here, but sadly, i can’t ignore it because it’s actually functional.