The not so smart home

I knew something had to change when I found myself spending upwards of ten minutes each night before sleep manually turning off the few dozen or so lights around the house.

At this point, I knew I was ready to graduate from incandescent bulbs to “smart” lights. Their hefty price tag aside, programmable lights sound like a dream: each is dimmable, with a wide range of colors available, and all of them can be turned off and on as a single unit with a touch of a button.

I decided to go with Pilips Hue lights since at the time they sounded like they have the best hardware quality. A few hundred euro later and my home could now look like a cozy cottage at one moment or like a nightclub the next, which greatly pleased me, but there is one thing I wasn’t looking forward to doing for years to come:

I was dreading using yet another app to control things around my home.

Now, as far as mobile apps go, Philips Hue isn’t terrible, but I already have separate apps to monitor my energy usage, my solar panel production, my car battery level & charging status; apps to control the robot vacuum cleaner and the thermostat; an app to pinpoint the location of my mischievous ginger tabby cat; two apps to interface with sound systems of different brands, an app to check the local wind situation, one to track the trash pick-up schedule, and one for surveillance cameras we have outside that we exclusively use to spy on our backyard chickens.

We regularly have friends housesitting and I really don’t want to ask them to download apps or sign up for services or request access control permissions just so they could turn things off and on in the house. Once friends were texting us that the robot vacuum decided to go on a little unprompted rampage—perhaps leading a tiny uprising against humankind by bumping against their feet—and they didn’t know how to send it back, because to redirect it to its docking station you’d either need to know an arcane spoken incantation that the robot only recognizes 50% of the time, or to sign up for an app.

Companies that make good hardware don’t necessarily make decent software, and their apps often feel like an afterthought. Taking our unruly robot vacuum as an example, the app for controlling it often needs to be quit and restarted before it would reestablish the connection with the device. Another offense is the app for monitoring our surveillance videos having the audacity to pop up a large “BLACK FRIDAY DEALS” overlay when I was trying to review footage just the other week. No, hardware vendors cannot be trusted with making apps, and I would much rather that they sell me on protocols that their devices speak instead of how their apps look.

A smart home hub that unifies all the different services under a single interface would be a decent solution to fragmentation of both software and of user experience. HomeKit looks neat, but we are a mixed Apple/Android household, and additionally I didn’t want to hand over the reins to either Apple, Google, nor Amazon when it comes to overseeing the sanctity of my home. Being a big open-source nerd that I am, the only solution I would trust is something that is self-hosted and community-maintained. After all, when software breaks, I feel much better about it if I can look into why it happened.

Smart home goals and boundaries

And here are some boundaries where we draw the line:

My Home Assistant setup

I’ve been running Home Assistant for about a year now and have recently arrived at a configuration that I think has long-term potential. Most of it now seems simple in hindsight, but it was neither clear nor well-documented when I was starting out, and I remember often feeling overwhelmed by the number of options available for accomplishing nearly everything I set out to do.

A lot about Home Assistant—especially when it comes to “glue” between its different optional components—is supposed to be an exercise for the reader, which is great if you a DIY hobbyist who’s in it for the learning experience, but not so great if you’re just trying to get things set up.

Home Assistant host machine

My Home Assistant is hosted on a Raspberry Pi 4 model B. You could host yours on your Network-attached storage (NAS) if you have that, but in my experience, a Raspberry Pi is perfect for this use-case as it’s easy to set up and later make disappear in the utility closet.

⚠️ Be sure to go for Home Assistant Operating System so that you can benefit from access to their add-ons, which are *chef’s kiss*. I have previously used this Rpi as a makeshift media center and had Docker set up on it running a UniFi Network application, among other things, so I wanted to avoid wiping the whole disk for the Home Assistant OS to take over. Instead I’ve installed Home Assistant Core in its container form. That was a big mistake. Not only did I end up with more work managing Docker and spinning up various containers under it, but my whole stack was brittle and not enjoyable to maintain over the long term. After I let Home Assistant OS take over the whole machine, I realized that I can actually install components like UniFi Network or the ad blocker within Home Assistant as add-ons and have its Supervisor architecture take care of their orchestration.

⚠️ One disaster that I’ve had is when my Raspberry Pi turned into a brick, taking down the entire home network. Looking into that it seemed that its SD card died; something that a friend had warned me about but that I thought would not realistically happen. Apparently, even a quality SD card can only take so many write operations. I already set up system logs to be written to RAM instead of to the card, but perhaps it wasn’t enough? I didn’t want a repeat of this, so now I’m booting the Raspberry Pi from an M.2 SSD housed in a USB enclosure. This SSD will also come in handy for storing media for entertainment shortly.

Network ad blocking

I am running AdGuard Home as a Home Assistant add-on to block ads and trackers on the network level.

There are three main benefits to such a setup:

Here is how to set up AdGuard Home in Home Assistant:

  1. Install the AdGuard Home add-on and configure it to start on boot;
  2. Follow the add-on documentation to configure Home Assistant to have static IP on the local network, such as 192.168.1.33, as well as static upstream DNS server (e.g. Cloudflare 1.1.1.1 & 1.0.0.1);
  3. In AdGuard Home web UI, go to “DNS settings” and define a list of several upstream DNS servers you want to use—these are providers that will resolve DNS queries for domains that pass AdGuard’s own filters, and I have had good experience with AdGuard DNS, Cloudflare DNS, and Cloud9 DNS from this list;
  4. Lower on that page, for “Private reverse DNS servers” enter 192.168.1.1:53, where 192.168.1.1 is the IP address of your network router—this is optional but will enable AdGuard to resolve local IP addresses to host names of client devices on the network;
  5. Finally, in your network router admin interface go to DHCP/DNS settings and enter the IP address of Home Assistant as the DNS server to be assigned to all network clients.

Now, whenever a client connects to your local network (existing clients might need to reconnect or to renew their DHCP lease), they will get assigned Home Assistant as the DNS provider, which in turn forwards port 53 (the DNS port) to AdGuard Home running as an add-on, which then chooses to either resolve that domain name or block it according to filter lists that you choose to adopt in AdGuard’s “Filters” tab.

You can test this out on the command-line, substituting 192.168.1.33 for the IP address of your Home Assistant:

$ dig @192.168.1.33 googleads.g.doubleclick.net
...
googleads.g.doubleclick.net.		10	IN	A	0.0.0.0

Since googleads.g.doubleclick.net is a known tracker on the “AdGuard DNS Filter” list that I have enabled, this domain is blocked and correctly resolves to 0.0.0.0.

In my household, a whopping 45% of all domain requests get blocked and all devices still work normally, which gives you an idea of just how much data tracking was casually attempted. The biggest offender of them all? The smart TV.

⚠️ In the past I have used Pi-hole as the network ad blocker and it’s a lovely project which I was happy to sponsor for a while, but I found it to be slightly buggy and occasionally slow, including experiencing one complete instance of data loss that I was unable to track down. Granted, I was manually self-hosting Pi-hole at the time and might have configured something wrong, but after that experience I’ve found AdGuard Home to be a breeze of fresh air. Maybe it’s just that the Go programming language is better suited for this stack than the PHP/C combo.

Accessing Home Assistant when away from home

Up until now I have been accessing Home Assistant at http://homeassistant.local:8123, which is the default address of its web interface, but that only works on the local network. Being able to access Home Assistant while away can be useful not only for commands like preheating the home while on your way back, but also for location updates that the Home Assistant mobile app can track for every member of the household, which is then useful for various geofencing features and automations. (I have checked in with my partner about whether she is okay with me being able to see her location this way, and you should too for each member of your household.)

To access Home Assistant when away, I see mainly three options:

  1. Paid subscription to Home Assistant Cloud, which also helps sponsor Home Assistant development;

  2. Setting up your own VPN that includes your Home Assistant machine, made super easy using the free tier of Tailscale and the Home Assistant add-on of the same name—I have tried this and it works brilliantly, but requires each device to be connected to the VPN before it can access Home Assistant, plus the free tier of Tailscale is limited to a single user;

  3. Using a dynamic DNS approach to update a domain name record every time your internet service provider changes your public IP.

In the end I went with dynamic DNS because, once set up, it has the most long-term potential: no subscriptions (apart from my existing subscription to DNSimple), no VPN connection required; just visiting a URL and having it work for anyone, anywhere.

Here is how to set up remote access for Home Assistant using dynamic DNS:

  1. You will need to own a domain name, e.g. example.com;
  2. You will also need a dynamic DNS provider or, as is with DNSimple in my case, a regular DNS provider that offers a simple API for updating a DNS record;
  3. In your network router settings, find the “Dynamic DNS” option. My UniFi router supports providers like No-IP and Namecheap, but not DNSimple, which is solved by using the DDNS.Horse service to make DNSimple act as if it’s No-IP. Configure your router to update the record for a hostname such as myhome.example.com;
  4. In your network router settings, use port forwarding to forward port 443 (the standard HTTPS port) to 192.168.1.33, which you should substitute with the IP of your Home Assistant instance;
  5. In Home Assistant, install the Nginx Proxy Manager add-on and configure it to start on boot;
  6. Nginx Proxy Manager has its own admin web interface that it starts on port 81, so let’s access it at http://homeassistant.local:81/ and log in with default credentials admin@example.com and password changeme;
  7. In Nginx Proxy Manager, create a new proxy host for the domain myhome.example.com and have it forward to scheme http, hostname homeassistant.local, and port 8123. Make sure to enable websockets. In the “SSL” tab, request a new certificate with Let’s Encrypt, choose “Force SSL” and “Use a DNS challenge”. My DNS provider is DNSimple, so I generate a new API token and paste it into Nginx Proxy Manager.