A few of my IoT home hacks

To start with, I’ll explain my situation. I’ve got a bad back. A really bad back. I’ve had three operations on it now, back when I was a teenager, then a revision in 2006, and then a second revision about three weeks ago. What I’ve ended up with is a fusion of ten of my vertebrae and a lot of metalwork. Going into this latest surgery, I knew I was going to be recovering for a long time: up to a year. A lot of that would be spent in bed. Even without the surgery, the chronic back pain from which I’ve suffered has given me a lot to deal with, so having my environment under control is important to me.

So, this is a perfect opportunity for hardware hacking.

First up, I’ve built my own bedroom clock, the Pi-Clock-O-Matic 2000™. I have a thing for catchy names. This is a Raspberry Pi with a screen, covered in red transparent acrylic, so as not to dazzle me during the night. It displays the time (duh), date, indoor and outdoor temperature, humidity, barometric pressure and change in pressure.

The GidTech Pi-Clock-O-Matic 2000™

These sensor readings are to help me pre-empt migraines, as I’ve found (through extensive manual journalling and data logging of various suspected factors) that the change in barometric pressure is a trigger: if there’s a sudden change in pressure, my head starts going woolly and it’s time to reach for the drugs. The graph shows the last three hours of barometric pressure data.

Right now, the screen's also showing the number of days since my surgery (+24 days); my current estimated level of Oramorph — oral morphine syrup — in my system; and the time since I last took my meds. Once this passes six hours, it inverts video to remind me to take my pills.

This clock is actually one of two in my bedroom, so I can see it no matter which side I’m lying on. To achieve this, I’ve changed most of the system over to a client/server mechanism based on MQTT. The client software is written in Python using pygame, as it seemed an excellent way of controlling the Pi official screen in console mode.

The clocks also act as hosts for several USB (and wireless) keypads for controlling the entire system:

These keypads issue MQTT messages, which are picked up elsewhere for transformation and processing.

Originally, these converted the keystrokes directly into concrete commands, to control various things. Over time, I’ve moved it to a Node-RED based system; the keypads just publish raw keycodes to MQTT, and a flow in Node-RED interprets them. This allows for simpler, centralised, on-the-fly configuration of the intents without having to restart loads of scripts.

The actions break down into several categories:

  • Lights and fans, controlled via mains relay switches over 433MHz RF.

The Node-RED flow converts raw keycodes from MQTT messages into more concrete actions, sent back out as MQTT messages.

The ugly Node-RED logic for converting raw keycodes into actions

The lights and fans are controlled remotely by the Remote-Switch-Network-Izer 2000™: a NodeMCU programmed with Arduino that listens for rf action MQTT messages and sends out the appropriate control codes using a cheap 433MHz transmitter. These codes are picked up by consumer-grade remote sockets around the room to switch lights and fans on and off.

GidTech Remote-Switch-Network-Izer 2000™

These sockets are the kind you buy for £20 with a flimsy remote control, rather than the more substantial (and much more expensive) WiFi or Bluetooth-enabled WeMo or SmartThings.

Inside (an earlier version of) the Remote-Switch-Network-Izer 2000

It’s not ideal, as the switches have no real concept of state; and because it’s possible (and not uncommon) for a command to get lost in transit, keeping track of state is not reliable. If I’d bought WeMo sockets (for example) I could query them for state. The main ceiling light is even worse: as I replaced the mechanical wall switch with an RF-controlled remote wall switch that does not accept on/off but only toggle, there isn’t even a good way to reset back to a known value.

However, as my keypads are interactive and only offer toggle capability, it doesn’t matter that much: if pressing the button doesn’t work, press it again…

The medication tracking has an interesting implementation. The medication last dose tracker is fairly straightforward; when the button is pressed, an MQTT message is published with the current epoch timestamp, with retain set. That way, if/when the clocks are rebooted, they get the last known value.

Node-RED meds tracking

The Oramorph tracker’s a bit smarter: Node-RED keeps track of the current estimated quantity in my body, and then regularly decreases it using exponential decay based on the average metabolic half-life of morphine in the body (roughly 2.5 hours), publishing the new value and timestamp with retain set. If a dose is signalled (typically 10mg per press) it’ll add 10 to the value and update the timestamp. Then, on the next update, Node-RED can calculate the difference in timestamps between the last retained value and “now”, and perform an exponential decay calculation on it. It’s all very rough, but it does give me an idea of when I’m overdoing it on the morphine, or whether it’s reasonable to take another dose if I’m in pain.

halfLife = 2.5 * 60 * 60;
dt = t - ot;
q = oq * Math.exp(-dt * Math.LN2 / halfLife);

The venetian and roller blinds really deserve separate posts, which I’ll consider later. The venetian blind was originally going to have a full lift motor, but I never got around to it, partly because I never really needed to lift the blind. Instead, I hacked the cheap venetian blind’s tilt function to take a high-torque servo motor, by way of a 3D-printed herringbone gear mechanism.

3D-printed herringbone gear for the venetian blind slats
3D-printed DC-motor mount for the blackout roller blind

Next steps:

  • Link Amazon Echo Dot (Alexa) for voice command. I’ve managed to get a custom skill to pass an MQTT message from AWS Lambda to the MQTT broker on AWS IoT, which my home Node-RED subscribes to. This should be more secure than opening up an HTTP endpoint on my home network for Amazon to hit directly. Getting this rigged up has been a major chore, as Amazon AWS loves to overcomplicate everything. It should be straightforward to use the Smart Home API thing to give a voice interface to the whole Node-RED / MQTT flows I have set up.
    UPDATE: Finally got it working… “Alexa, Turn On Lights”. They really don’t make it easy, though.

I’d also love to tell you about some of my other hacks, including:

  • the venerable iPad-Hold-A-Tron 2000™, a hacked and almost completely rebuilt Ikea anglepoise lamp repurposed to hold my iPad Pro over my bed while I’m recovering from back pain;

Geek for all seasons. Mucking about with various home automation IoT stuff, and other technical musings. NOTE: I’m publishing to https://gid.ink/ from now on.