An Alarm Dashboard + Tecnoalarm Keypad in Home Assistant
An Alarm Dashboard + Tecnoalarm Keypad in Home Assistant
Crossposted from my blog, where the rest of the Home Assistant series lives. The most interesting decision in this project was what not to put on screen. An alarm dashboard is, by definition, a map of where my house is soft - every open window, every door someone could walk through. A careless version of it would also document how to get in. So before I lined up a single card, I made a rule for myself: the panel can be as detailed as I like on my own network, but anything I write about it gets renamed, abstracted, and stripped of the real layout. That tension between a useful operator console and a literal threat map shaped every choice below.
Building Against Fake Sensors
When I started, most of the physical door and window contacts weren't wired yet. Rather than wait, or climb a ladder for every iteration, I created simulated binary_sensors, entity ids ending in _sensor_sim, and built the entire dashboard against those. I could sit on the couch, flip a fake window "open", and watch the whole pipeline light up: status grid, logbook entry, notification, the lot. In hindsight it was the best decision of the build. UI work on a security panel is fiddly: you want to see the red state, the alarm-armed state, the everything-closed state - and you cannot summon those reliably from real hardware on demand. Simulated sensors gave me a controllable test bench. By the time the real contacts went in, the dashboard already knew how to render every state, and swapping a sim entity for a real one was a one-line change. If you're building any kind of state-driven HA UI, fake the inputs first.
Two Helpers, Mirrored to the Bus
The whole thing runs on just two input_boolean helpers. One is the main arm/disarm toggle; the other is an "alarm ready" flag that's only true when every monitored opening is closed. Both are mirrored onto the KNX bus, which is what keeps the physical world and Home Assistant in agreement. The wall keypad - a Tecnoalarm unit - talks KNX. When someone arms at the keypad, the group address flips, and the HA helper follows; when I toggle the helper in the dashboard, the keypad's state follows back. I'm deliberately keeping that bridge conceptual: Tecnoalarm keypad → KNX → HA helper, nothing more. The point worth taking away is the pattern, not my group-address map. A plain boolean as the shared source of truth between a dedicated panel and your smart-home stack is clean, debuggable, and vendor-agnostic. Whatever flips the boolean - keypad, dashboard button, automation - the rest of the system just watches the boolean.
The Status Grid: a Jinja-Templated Map of the House
The centrepiece is a stock markdown card with a Jinja template per sensor. Green dot means closed and safe; red means open and would-trigger. No custom integration, no HACS card - just markdown and the templating engine HA already ships. The pattern is trivially repeatable, one line per opening:
{% if is_state('binary_sensor.garage_door_status', 'on') %}🔴{% else %}🟢{% endif %} Garage
{% if is_state('binary_sensor.window_office_status', 'on') %}🔴{% else %}🟢{% endif %} Office
There are 12 monitored window and door sensors in total - 7 on the ground floor, 5 upstairs - and I group them by floor in both the grid and the logbook so the panel reads like the building rather than a flat entity dump. (I'm showing two generic example sensors here; the real grid uses anonymised English ids, never the room-by-room inventory.) The garage door is just another contact in that list, which matters more than it sounds: a garage-entry attempt rides exactly the same arm/notify/log pipeline as any window.
A Naive Trigger Fires on Every Glitch
Each monitored opening gets its own automation - a state trigger from off to on - rather than one big template. Per-sensor automations mean per-sensor log messages and notifications, which is worth the extra YAML. My first version fired the alarm the instant a contact reported open. That was a mistake. Contacts glitch. A momentary flap, a sensor settling, a draft, and suddenly the house is lit up and phones are buzzing at 3 a.m. for nothing. The fix is a for: duration on the trigger: only fire if the contact stays open. Start with a short, tunable value while you watch behaviour - five seconds reads fine on paper:
triggers:
- trigger: state
entity_id: binary_sensor.garage_door_status
from: "off"
to: "on"
for: seconds: 5
After living with real false alarms, my actual setting climbed to 30 seconds of verify-and-recheck before the alarm commits. That is the tunable value doing its job: long enough to swallow glitches, short enough that a genuine entry still pages me well before anyone's settled in. The 5-second value is a starting point; the right number depends on how noisy your contacts are.
Dual Logging so Events Survive a Glance
When the alarm does commit, it fans out on multiple channels: critical push notifications to the household phones, an audible siren, and lights snapping on in the circulation areas - kitchen, staircase, hallways - so a break-in is visibly seen rather than silent. I'm keeping the exact siren entity and light circuits out of this on purpose and only describe the response. The part I'd recommend to anyone is the logging. Every trigger writes both a logbook.log entry (named "Alarm Event", with the sensor and a verification note) and a persistent_notification that sits in the bell menu until I dismiss it. One is the timeline; the other is the sticky "hey, look at this" that survives a casual glance at the phone. The dashboard surfaces this directly: a 24-hour logbook card filtered to exactly the alarm sensors, plus an 8-hour history-graph of the busiest contacts for spotting patterns. With both in place, an event stays visible until I have looked at it.
Quick Actions, a Mobile Frame, and Where this Sits
Three buttons handle the day-to-day: Arm, Disarm, and a jump-to-Logbook. Arm and Disarm call input_boolean.turn_on / turn_off on the same helper the KNX keypad flips, and the logbook button is a plain navigate action. Because everything routes through that one boolean, the dashboard disarm and the physical keypad disarm are literally the same operation. The whole panel is built mobile-first - touch-sized buttons (icon height around 40px), a scrollable logbook, a collapsible status list - so it works as a phone wall-panel by the door. The full config lives in the conventional HA files: automations, an input_booleans file, and a knx file mapping the helpers onto group addresses, all under git so I can see exactly what changed and when.
Comments
No comments yet. Start the discussion.