Loading...
Author Cloudapp
E.G.

An Alarm Dashboard + Tecnoalarm Keypad in Home Assistant

June 10, 2026
Table of Contents

The most interesting decision in this whole project wasn't a Lovelace card. It was figuring out 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. Build that carelessly and you've published a break-in guide. 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 — useful operator console vs. literal threat map — shaped every choice below.

The honest part: I built it against fake sensors

Here's the confession that makes this post actually useful. 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.

This turned out to be the single 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 the quiet trick that makes the physical world and Home Assistant agree. 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.

The gotcha: a naive trigger cries wolf

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's the tunable knob doing its job — long enough to swallow glitches, short enough that a genuine entry still pages me well before anyone's settled in. Treat the 5-second value as a starting point, not gospel; the right number is whatever your hardware's noise floor demands.

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; describe the response, don't hand over the wiring.

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. Dual logging means an event can't quietly scroll away.

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.

Here's the trade-off in plain terms, because I think people get it backwards. A Home Assistant dashboard is a fantastic operator console — at-a-glance house state, a searchable history, one-tap arm/disarm, lights-and-siren choreography you'd never get from a standalone box. What it is not is a single source of truth for security. It depends on a server, a network, and software I'm actively tinkering with; a dedicated alarm panel is purpose-built to keep working when all of that falls over.

So the HA layer complements the dedicated system, it doesn't replace it. The Tecnoalarm panel is the thing I'd stake the house on; the dashboard is the thing that makes the house legible to me day to day. Building it in public just meant being honest about that line — and being disciplined about which side of it the details belong on. If you want the groundwork this sits on, the earlier parts of this series cover running Home Assistant in Docker and getting the wider stack talking.

Related articles