Teaching a wired burglar alarm to talk to Home Assistant
When we moved in last year, the house came with a proper old-fashioned wired burglar alarm: a control panel and five zones, each with a PIR motion sensor staring out of a corner. It does its job. It just has no idea the rest of the house exists, and Home Assistant has no idea it exists either.
I had two reasons to change that. The first is the keypad. I don’t want to fuss with a code every time we go out or come home. My idea is to scan an RFID tag from outside instead: the Home Assistant app on my Android phone picks it up, and Home Assistant takes care of arming and disarming securely, so neither of us has to deal with codes at all.
The second, a bonus, is the PIRs. They’re already wired and already powered, and the panel reports their motion whether the alarm is armed or not. That’s motion sensors for the hallway and landing lights that I didn’t have to buy, if only I could listen in.
The wiring
The plan was a Raspberry Pi sitting alongside the panel, reading its outputs on the GPIO pins and poking its inputs with a couple of relays:
- five inputs, one per zone, which go high while that zone’s PIR sees movement;
- a “triggered” input, high while the alarm is going off;
- an “armed” input, which the panel holds high when it’s disarmed (so the logic reads backwards, as alarm logic seemingly must);
- two relay outputs, one for “arm away” and one for “arm home” (usually a part-set, with only some zones active).
The relays are wired to the panel’s own inputs. The panel’s outputs run at alarm-panel voltages, far too much for the Pi’s 3.3 V pins, so they come in through a pair of LM339s. Each is four comparators in one chip: a comparator is a close cousin of an op-amp that simply says whether one voltage is higher than another. Its outputs are open-collector, which means they can only pull a line down. So I pull each output up to 3.3 V, and a 12 V signal from the panel becomes a clean high or low that the Pi can safely read. Two chips give eight channels, one more than the seven lines I need.
The relays don’t hold anything on. Each command closes one for two seconds and lets go again, like someone pressing a button. Disarming is the odd one out: it pulses the arm away relay again. So the panel seems to treat that input as a toggle, where pressing the same button twice gets you back where you started.
The software
The bridge is one small Python script using RPi.GPIO and paho-mqtt. It has no ambitions beyond shuttling edges one way and commands the other.
Every GPIO input gets an interrupt on both edges, with a 100 ms debounce. When a zone changes, the script publishes ON or OFF to home/motion_<zone>/state. When the armed or triggered lines change, it publishes the alarm’s state to home/alarm/state. The armed state is retained, so when Home Assistant restarts it finds out straight away whether the house is armed, instead of waiting for someone to walk past a sensor.
Going the other way, it listens on home/alarm/set for ARM_HOME, ARM_AWAY and DISARM. It replies with arming or disarming straight away, then pulses the right relay, and the real state follows when the panel’s armed line changes.
Those topic payloads aren’t a coincidence. They’re the defaults for Home Assistant’s MQTT alarm control panel, so on the Home Assistant side there was nothing to translate. Point the panel at the two topics, add one MQTT binary sensor per zone, and the stock alarm card just works.
The panel keeps some secrets
The panel’s “armed” output is a single wire, so it can tell you that the alarm is armed but not how. The script’s workaround is to remember which button it pressed last, and to report armed_away or armed_home accordingly. If someone sets the alarm at the panel itself, the Pi simply assumes it’s whichever mode it asked for last time. It’s a guess, but usually a good one.
A third relay is still sketched out in the code, commented out, with a matching TRIGGER command. I was toying with letting other Home Assistant sensors set the siren off. In the end, though, there was only really room for two relays in the space we had, and I didn’t fancy the risk of false alarms!
Where it stands
The zones now show up in Home Assistant as five motion sensors, and the alarm as a panel I can arm and disarm from anywhere. The panel is still in charge of actually being a burglar alarm, which is exactly as it should be. The Pi is just the nosy neighbour who tells everyone what it’s up to.