A home security system built on Home Assistant: RFID entry at two doors, a keypad-and-display door portal, presence tracking per key, a camera-driven door lamp, person detection, and an alarm that reaches phones.
Start here: INSTALL.md — from a fresh Home Assistant to a working system.
Ready with documented caveats. Not a product, not an add-on, not supported. A burglar alarm that fails does so at the worst possible moment. Read the caveats below before you run it. MIT, as is, without warranty.
Step-by-step assembly with more photographs is in
docs/documentation/.
- No proven alarm without Wi-Fi. The portal's offline siren compiles and has never been heard. Until you flash it and hear it, jamming 2.4 GHz or stopping Home Assistant silences the house. Cutting power to the portal still does: authority is RAM-only.
- Printable as 3MF profiles; Gerbers for a proto fab; not
pick-and-place. Print files live on MakerWorld and Printables.
PCBs/has KiCad source plus Gerber+drill zips. There is no CPL. The door lamp has no PCB — commercial bulb + camera in a printed housing.
- The outdoor unit holds the card master key in cleartext flash until you opt into flash encryption. That burn is irreversible; a first flash over OTA would brick the board. See INSTALL.md § Flash encryption. Use NTAG21x; MIFARE Classic is clonable.
- One Home Assistant account still works with zero extra setup. A second account can be linked to a key. Tamper detection needs a portal reflash.
Not application source code. It is the config tree for a Home Assistant instance, plus firmware for two ESP32 devices:
There is no application build and no way to execute this locally. The only way to run it is a real Home Assistant instance and real hardware.
- Two readers, one decision path. Every scan dispatches through one script. Cloned cards are caught by a rolling counter; keys reported stolen sound the siren on the tap.
- Passage windows. A valid scan opens a timed grace period. Direction is classified from the lever IMU, reader intent, and the door swing.
- Elevated mode ("Super Surveillance"), on a switch or up to four schedules. An unauthenticated opening while elevated opens a timed challenge — card and master PIN — before the alarm.
- Alerting per person. Each key can link a phone. The alarm, a stolen card, and portal tamper are non-maskable.
- Watchdogs on the portal, the doorbell, and the Frigate detection channel.
- A door lamp switched from measured camera luminance, with a sun-elevation fallback.
Meshes are not in this tree. Download the Bambu Studio profile for each device from the MakerWorld collection or the Printables collection:
There is exactly one automated check, and it is static:
python tools/guardian-preflight.pyIt validates that every YAML file parses, that version literals agree,
that script references resolve, that automation ids are unique, that no
secret placeholder survives, that nothing under www/guardian-ui/
reaches an external host, and that nothing can quietly cancel an alert.
It makes no network call and reads no credential value.
And one test for that check:
python tools/guardian-selftest-preflight.pyIt does not test behaviour. Nothing here fires an alarm. For that,
use Home Assistant's Check configuration and the numbered steps in
DEPLOY.md.
Stated plainly, because the parts that are careful could be mistaken for parts that are enforced.
- A Home Assistant login is the outer authorization boundary. The
panel is require_admin: falseso a non-administrator can use Keys and Notifications. Home Assistant still does not restrict which services a non-admin may call from Developer Tools. Seedocs/maintainers/GUARDIAN_UI.md§ Security boundaries.
- The siren does not work without Wi-Fi and Home Assistant on any device that has not been flashed with current firmware and then heard. The networked siren is an MP3 on the portal's DFPlayer. Jam 2.4 GHz, cut power to the access point, or take Home Assistant down and there is no proven alarm.
- The card master key is in cleartext flash on a unit mounted outside the door until you opt into flash encryption.
- MIFARE Classic cards are clonable. NTAG21x with a password is the medium that is actually strong here.
- Rotating the master key destroys every enrolled card, both types, with no way back.
- The master PIN hash is weak by construction: unsalted SHA-256 of 4–6 digits. It is a second factor at a door, not a secret.
- Dismissing a live alarm needs no factor. Any phone holding the alarm push can silence it. That is deliberate.
- Every alarm notification leaves your network via Apple or Google.
Do not port-forward Home Assistant. See INSTALL.md§10.
- Credentials live in esphome/secrets.yaml(gitignored, generated bytools/guardian-gen-secrets.py), Frigate add-on environment variables, and the master PIN.
Works, in daily use in one household: RFID entry at both readers, presence per key, passage windows and direction classification, the MFA/challenge flow, enrollment, per-person alert routing, the lamp, the panel, the offline watchdogs.
Known gaps, deliberately not hidden:
- Print files are 3MF profiles on MakerWorld / Printables; Gerbers are
in PCBs/. Not pick-and-place.
- Card-crypto and torn-rotate fixes are in the tree and unverified against a real card since those passes.
- The offline local siren compiles and has never been heard.
- Tamper detection needs a portal reflash.
- The alarm path is unverified on hardware since the last several
passes. INSTALL.md§9 andDEPLOY.mdnumbered steps remain the proof.
- Frigate integrates over raw MQTT, not the native integration.
- Single-household provenance. This has only ever run on one installation.
Early private git history contained a household LAN address and a camera RTSP URL. This public repository was seeded from a cleaned tree; that log is not here. If those credentials were ever live, rotate them.
MIT. This is a burglar alarm provided as is, without warranty of any kind. If you run it, you own the consequences of it failing.