Weebo: my family-friendly home automation app with mTLS


Challenges with Off-the-Shelf Solutions

While there are easier ways to build home automation than what I’ve been working on over the last 15 years, I’ve come to realize that despite the easier options. You could just buy all the controls, sensors, hubs, and trust that the SaaS that ties it all together and provides external access will be both safe (they aren’t) or that they’ll last more than a few years (they won’t.) The tradeoff in buying off-the-shelf stuff is that it “sort of just works” and in theory, you can add your family to whatever apps they use. This approach was tested in my household with one of the early Wink hubs connected to a bunch of smart switches/outlets/etc as well as with AppleTV home integrations.

The same problems always cropped up:

  • devices lose connectivity and go unresponsive, require re-pairing and config.
  • app or hub updates and requires re-auth without warning.
  • hub would lose networking or be slow without reason, making the app un-usable.
  • app switches to subscription model, deprecates hardware, etc.
  • smart company / product line / API integration evaporates unexpectedly.

Most of the connectivity/auth/update issues are not that difficult to resolve, but if the customer is your spouse, they quickly lose trust in the amazing contraption you’ve cobbled together.

While testing anything I could buy, I also experimented with building my own sensors, platform, etc., and after all these years, I finally have a system fully custom built that has been 99% reliable, is very easy to use and extend.

Here’s how I eventually made something more reliable than we could buy that’s easy enough that my whole family uses it regularly.

Remote access

VPN-Based Remote Access

Building on my internal network setup, a remote access solution was needed. In a previous post I described the internal topology of my network, sensor communication, and protocol used to deliver data and real-time commands to nodes. Using some basic TypeScript and CDK, I was able to deploy and tear down a VPN server fully configured for my network and clients. Once I had that under control, we used it for a few months.

Remote Access Version 1 VPN setup allowing remote access to Home Assistant.

It performed well as long as we remembered to connect to the VPN before checking Home Assistant to open or close the garage door. While it worked for me, my wife simply wasn’t using it after a while. The Home Assistant interface remained clunky and slow no matter how much effort I put into widgets, reporting, and presentation. So, closer technically but back to the drawing board if I want this to actually be used.

mTLS

Implementing mTLS for Secure Access

To address these limitations, a more secure alternative was explored. The last thing I wanted to do was stick a web server on my VPN server. The whole point of the Wireguard service is to be an easy-to-trash-and-rebuild silent service, and the moment you stack extra services into it, you lose some of that disposability. Additionally, I don’t want open services/ports, possible vulnerabilities from a web framework/server, and wasn’t excited about having another auth layer to manage long-term.

Remote Access Version 2 mTLS architecture for secure client-server communication.

After some research, I found a reasonable alternative: mutual TLS Authentication (mTLS) with a minimal web service in Go. Basically, mTLS is a way to secure communication between clients and servers where the client presents its own certificate to the server during a request. Instead of passing a simple API key or auth header, the client passes a full certificate. The server validates the certificate and either allows or ignores traffic completely based on the result. It isn’t used often in end-user applications because of the overhead, however, overhead isn’t a concern for my use case, so I wrote a very light server in Go, set up proper certificates for the server and client, and made a couple endpoints for my specific sensor data / controls.

Weebo Mobile App

With the comms and infrastructure all worked out, attention then shifted to the mobile app. I wanted it to have a name and face that my family would like, and since we all like the movie Flubber, I picked Weebo as our mascot.

Goals for this app are quite straightforward:

  • app opens quickly to most useful info / controls
  • long-press & haptic feedback on controls
  • one-touch to use the ‘blind close’ feature of our garage door
  • secondary automations / sensors in their own screens

There’s not a lot of app state, so MobX was used and an API client structure was built that implements all of the mTLS shuffling. I distribute the app using TestFlight to the family, then once it is installed, I manually add the appropriate client certificate in the Settings screen, so updating the client certificates is easy and intentional.

For sensor areas like the chicken coop or leopard gecko, I include temperature, humidity, etc., along with “optimal ranges” depending on season, time of day, etc. If the sensor values get out of whack, we can see what they should be, why, and what might happen if the issue isn’t corrected. When my son looks at his leopard gecko sensors on the iPad, he can quickly see and understand this and he’s motivated to figure out if the mister is out of water, for example, because the consequence of it being too dry is quite clear.

Achievement unlocked

This has been an epic odyssey of building across dozens of Arduino and ESP-based microcontrollers, various network protocols and packet formats, different integrations with hubs, mqtt deliveries, etc., and finally it all works seamlessly. It’s not just the ultimate nerd toy I’ve always wanted; it’s actually something useful my wife and I rely on every day.

With this solid foundation in place, I’m extending this to a physical device next. Using an M5stickC Plus2, I have 90% of an integration built out that will result in a smart keychain fob that can flip through everything the app can do with a couple simple buttons and a tiny screen.

This setup has proven reliable, and I’m excited to see how the upcoming keychain fob integration builds on it.