My somewhat optimistic plans for the weekend were dashed by the sudden demise of my ODROID-U2‘s EMMC flash storage, which is hardly unsurprising considering the thing has been running uninterrupted for years–a little over seven of them, in fact.
So I ended up spending some time rebuilding my home automation setup, which took me a good deal of time. I could have just redeployed the whole thing as is, but I needed a distraction.
Think of this as the latest post in my series on home automation, if you will.
I had pretty good backups thanks to
restic, so no important data was lost rather them a few hours of telemetry, and I had plenty of spare hardware.
But it’s kind of ironic that the Raspberry Pi 4 I’m replacing the ODROID with is pretty much equivalent performance-wise (except that it has twice the RAM at 4GB) and that (for the moment, at least) it uses theoretically much less reliable SD card storage, so that’s “progress” for you.
This was also a great opportunity to streamline my setup even further and getting my home automation setup back into the “mainstream” with modern hardware, baseline OS and software packages, since maintaining the ancient kernel and hacked
16.04 userland on the ODROID-U2 was getting tiresome.
In particular, having to build containers specifically for it was an extra annoyance for even simple updates to my stack (one that had some nasty surprises, in fact).
So this time around I decided to go “bare metal”, get rid of most (so far, in fact, all) of the custom containers and just run everything on Ubuntu LTS (currently
piku as a service orchestrator for
node-red, which now run directly as
So, what did I learn in the process?
For completeness (even though I’ve documented it here), after first boot, all you need to do is log in to your Pi, copy the
cloud-init.yml file to it and do:
sudo rm -rf /var/lib/cloud/instances/nocloud cd /boot/firmware sudo cp user-data user-data.original sudo cp ~/cloud-init.yml user-data sudo reboot
cloud-init will do its thing.
- I was able to replace the vast majority of my ZigBee device shims with
homebridge-z2m, which does not do everything my shims did but removes a lot of custom flows from Node-RED.
- In the intervening years my LG TV was upgraded with native HomeKit support, so I was also able to drop some of the custom logic I was using for it–but had to keep the
homebridgeplugin in order to be able to control volume and audio inputs, which are not exposed by LG’s native support.
- I also refreshed the plugin I was using to control our Vodafone MediaRoom set-top boxes.
This last change removed some finicky bits of packet sniffing I was using to figure out whether the boxes were actually on or not (spoiler: local recording and various hacks mean they may well still be streaming video but not idle).
During that, I also set up a new org in my Gitea instance with all the individual
git repos, which was a relatively simple matter of splitting the backup into its constituent configuration files, setting up
package.json manifests for each service, and setting them up to be deployed to
The Tiresome Bits
Testing everything is, well… still going on. I managed to simplify a lot of stuff, but I had to resort to a number of tricks to replicate some Node-RED functionality, such as using Tasmota timers on the devices themselves to get my doorbell extender to work.
In particular, some automations are still missing, since I have decided to err on the safe side and disable most of my Node-RED flows until I’m sure device characteristics and events are still being handed about between components the same way.
But I’m 80% there already, so that’s good.
So Why (Still) Not Home Assistant?
This is something that comes up on every episode of my home automation saga, and the gist of it is that:
- All the UX, automations, etc., are exposed via the Home app, so I don’t need a Web UI (other than for a very simple dashboard, which is something Node-RED excels at).
- It has too many moving parts (I would still need to run
homebridge, and they now integrate almost seamlessly).
- If necessary, handling MQTT logic in Node-RED is just way easier for me (and more flexible) than Home Assistant’s declarative configuration approach.
That said, considering that I only had to reconfigure anything twice a year (typically when I add or remove the Tasmota devices we use for managing the heaters), I’ve decided to try setting our Tasmota devices to use HomeAssistant auto-discovery, which is working fine with a
homebridge as well.
Over the next few evenings I intend to clean up portions of my setup and add them to
piku as samples (or collect the more arcane bits in another post). It’s going to be another long week at work, and it will keep my mind off things.
Update (Sep 26):
Since the list of tweaks I needed to do was fairly small I’m just going to append my notes to this post:
- The Ubuntu image I used was
- I ended up having to reflash my
CC2531dongle with the
source_routingfirmware to have a stable ZigBee network with the newer runtime.
- Even though that now seems quite stable, I ordered a set of new
CC2652-based dongles. I also ordered a ZigBee wall mount switch (no neutral), but am having to return it since it requires a square wall mount and won’t fit in our walls.
- Since the Node-RED dashboard UI buttons unaccountably don’t support something as simple as a plain button with an external URL, I grabbed a copy of SUI and hacked my own Heimdall clone.
- To configure my Tasmota devices, I set the MQTT topic to
tasmota_%06Xand then issued the command
SetOption19 onin the console. This means I don’t have very friendly topics, but the
homebridgeplugin I am using uses the device name when creating the HomeKit accessories, so that’s OK.
- I am still looking for a way to remap two contact sensors (the ones I taped to my doorbell coils) into occupancy sensors without using Node-RED (that works, but I would love to have the ability to remap device types and characteristics on
- To have my doorbell extender’s buzzer play for only 5 seconds when turned on, I defined this rule via the Tasmota console (indentation mine):
rule1 on Power1#state=1 do ruleTimer1 5 endon on rules#timer=1 do power 0 endon rule1 1
I’ve also been playing around with the
RGBW strips in the office, but that saga might well be worthy of a standalone post.