A Simple Alarm in Home Assistant: Zones, Delays, a Siren, and False Alarms
A Simple Alarm in Home Assistant: Zones, Delays, a Siren, and False Alarms
In Lesson 6, the alarm reacted to an opening in Away mode: instantly. In Lesson 8, home mode started switching itself based on presence. Now we're adding the missing layer: a simple supporting alarm with an entry delay, disarming, and handling false alarms.
This isn't installing a professional monitored alarm system. You're building extra logic inside Home Assistant that calls script.intrusion_alarm from Lesson 3: with escalation, repeats, and a local siren. A certified alarm system still protects the house independently of HA.
Plan on about 90 to 105 minutes. Start with one perimeter zone and a 60-second disarm window. Then add an interior zone with PIR.
The rule for this lesson
A supporting alarm gives you time to enter and consciously disarm.
It does not replace a monitoring contract, the police, or a certified alarm system.
input_boolean is a teaching model
For a production system, consider alarm_control_panel (e.g. the Manual Alarm Control Panel integration): arming/pending/triggered states, a code, and a distinction between night arming and away arming. Protect disarming: user permissions, a separate admin dashboard, a PIN, a dedicated tablet account: don't expose disarming on every panel.
An HA restart during the entry delay interrupts the countdown: the system may fail to trigger the alarm, or get stuck in an in-between state. A timer, or storing the end time, is more resilient. Reset timed helpers after HA starts up.
A real-life problem: you come home, open the door: and the alarm fires instantly
In Lesson 8, the entering_home_in_progress entry delay only protects you if the phone detects your return before you open the door. GPS can lag. Away mode might stick around a bit longer than it should. In that case, the Lesson 6 automation fires the alarm the instant the door opens: with no second to disarm.
Professional alarms solve this with an entry delay: once the door opens, you have, say, 60 seconds to punch in a code or disarm the alarm. In this lesson, you'll build similar logic in HA: simple, but honestly described for what it is.
A supporting alarm versus a monitored system
| Feature | Monitored alarm system | Supporting alarm in HA |
|---|---|---|
| Works without internet and HA | Yes: its own panel and siren | No: depends on HA, the network, and power |
| Connection to a monitoring center | Yes: a contract, patrol response | No: only your own notifications from Lessons 2-3 |
| Entry delay | Yes: industry standard | Yes: you're building it in this lesson |
| Integration with home mode and weather | Limited | Yes: tied into Lessons 6-8 |
A supporting alarm in HA makes sense as an extra layer: fast household notifications, a Zigbee siren, lights, SMS escalation. It doesn't replace a contract with a security company or a certified panel.
Zones: perimeter and interior
Professional alarm systems have zones. In HA, we'll simplify this to two groups:
Perimeter zone: the front door, windows, the gate, the garden gate. The first opening after arming starts the entry delay (time to disarm).
Interior zone: PIR in the hallway, garage, basement. Motion while the alarm is armed with no active disarming window = an instant alarm (an intruder is already inside).
The alarm_sensors group combines both zones for the dashboard and for "did anything trigger" conditions. Separate perimeter_zone and interior_zone groups let you tell the response apart.
What's actually the risk
Arming with no entry delay: every return ends in a false alarm and the household stops trusting the system.
PIR in the perimeter zone: wind, a curtain, a cat by the door: a false entry-delay trigger.
Two alarms running in parallel: the old Lesson 6 automation and the new one from Lesson 9 both fire: double escalation.
No way to handle a false alarm: after a test, the siren and SMS repeats keep running: the household stops responding.
Arming during Guests mode: a guest opens a window: an alarm. Zones need to respect the context from Lesson 8.
Which entities we're watching
You're using entities from earlier lessons. Example names below: swap in your own.
| Entity | Role in the alarm |
|---|---|
input_select.home_mode |
Context: Away → arming, Home/Guests → disarming |
input_boolean.entering_home_in_progress |
From Lesson 8: a signal that a return was detected before the door |
binary_sensor.front_door |
Perimeter zone: starts the entry delay |
binary_sensor.hallway_motion |
Interior zone: an instant alarm |
script.intrusion_alarm |
Escalation from Lesson 3: a single entry point for the alarm |
Alarm helpers
Add these to your configuration.yaml or helpers file:
input_boolean:
home_alarm_armed:
name: "Home alarm armed"
icon: mdi:shield-home
disarming_in_progress:
name: "Disarming in progress"
icon: mdi:shield-key
automatic_arming:
name: "Automatic arming with Away mode"
icon: mdi:shield-sync
home_alarm_test:
name: "Home alarm test"
icon: mdi:shield-alert
input_number:
alarm_entry_delay_seconds:
name: "Alarm entry delay"
min: 30
max: 120
step: 15
initial: 60
unit_of_measurement: "s"
icon: mdi:timer-sand
home_alarm_armed is the main switch: when it's on, the system watches the zones. disarming_in_progress means an active entry delay: you have time to turn off the alarm after opening the door. automatic_arming lets the alarm arm together with Away mode from Lesson 8, but you can turn it off by hand when you have guests.
The alarm_entry_delay_seconds number lives on the dashboard for tuning. In the automations below we use a hard-coded 60 seconds in delay:: the same approach as the Away delay in Lesson 8. You can swap it for a template referencing the helper later.
Zone groups
group:
perimeter_zone:
name: "Perimeter zone"
entities:
- binary_sensor.front_door
- binary_sensor.living_room_window
- binary_sensor.garage_gate
- binary_sensor.garden_gate
interior_zone:
name: "Interior zone"
entities:
- binary_sensor.hallway_motion
- binary_sensor.garage_motion
alarm_sensors:
name: "Alarm sensors"
entities:
- group.perimeter_zone
- group.interior_zone
The entities in these groups come from Lesson 6. If you don't have PIR yet: leave interior_zone empty and start with just the perimeter. You'll add the interior alarm once you install motion sensors.
What about the Lesson 6 automation?
Once you deploy Lesson 9, turn off the "Security: opening in Away mode" automation. The new entry-delay logic replaces it. Leaving both running at once will double the alarm.
Automation 1: arming with Away mode
When home mode switches to Away and you have automatic arming enabled: the alarm arms. In Guests mode, the alarm doesn't arm.
automation:
- alias: "Alarm: arming with Away mode"
description: "Turns on home_alarm_armed when the house is empty"
mode: single
triggers:
- trigger: state
entity_id: input_select.home_mode
to: "Away"
conditions:
- condition: state
entity_id: input_boolean.automatic_arming
state: "on"
- condition: not
conditions:
- condition: state
entity_id: input_select.home_mode
state: "Guests"
actions:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.home_alarm_armed
- action: script.notify_household
data:
title: "Alarm armed"
message: "Away mode: supporting alarm turned on."
Don't arm blindly with open zones
If a window or door is already open at the moment of arming, the automation may not catch a new violation, since the state won't change to on. To start, check the zones on the dashboard before leaving. In a more advanced version, you can add a condition: don't arm if the perimeter_zone group is already tripped.
Automation 2: disarming with Home or Guests mode
When the house is in normal use: someone's back, or you have guests: the alarm should disarm. Guests mode from Lesson 8 is manual, but once you set it, the alarm shouldn't stay armed.
automation:
- alias: "Alarm: disarming with Home or Guests mode"
description: "Turns off the alarm when the house is in normal use"
mode: single
triggers:
- trigger: state
entity_id: input_select.home_mode
to: "Home"
- trigger: state
entity_id: input_select.home_mode
to: "Guests"
actions:
- action: input_boolean.turn_off
target:
entity_id:
- input_boolean.home_alarm_armed
- input_boolean.disarming_in_progress
This works when Lesson 8 manages to switch the mode to Home before the door opens. When GPS lags: you need Automation 3 with its entry delay.
Automation 3: entry delay after a perimeter opening
This is the heart of the lesson. The alarm is armed. Someone opens the door: the system doesn't immediately call the escalation. It turns on disarming_in_progress, sends a countdown message, and waits 60 seconds. If you disarm the alarm in that window: silence. If not: it triggers script.intrusion_alarm.
Not every opening should get an entry delay
To start, we're simplifying: the whole perimeter zone triggers the countdown. In practice, you'd usually give the entry delay only to the door you normally use to come home. A window, garden gate, or garage gate could trigger the alarm instantly in the future. You can refine this once the basic logic is stable.
automation:
- alias: "Alarm: entry delay after a perimeter opening"
description: "60 seconds to disarm after entering through the perimeter zone"
mode: restart
triggers:
- trigger: state
entity_id:
- binary_sensor.front_door
- binary_sensor.living_room_window
- binary_sensor.garage_gate
- binary_sensor.garden_gate
to: "on"
conditions:
- condition: state
entity_id: input_boolean.home_alarm_armed
state: "on"
- condition: state
entity_id: input_boolean.disarming_in_progress
state: "off"
- condition: state
entity_id: input_boolean.leaving_home_in_progress
state: "off"
actions:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.disarming_in_progress
- action: script.notify_household
data:
title: "Disarm: 60 seconds"
message: >
{{ state_attr(trigger.entity_id, 'friendly_name') or trigger.entity_id }}.
You have 60 seconds to disarm the alarm on the dashboard.
- delay:
seconds: 60
- choose:
- conditions:
- condition: state
entity_id: input_boolean.home_alarm_armed
state: "off"
sequence:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.disarming_in_progress
default:
- action: script.turn_on
target:
entity_id: script.intrusion_alarm
data:
variables:
title: "ALARM: intrusion: perimeter zone"
message: >
{{ state_attr(trigger.entity_id, 'friendly_name') or trigger.entity_id }}.
The alarm was not disarmed within the entry window.
- action: input_boolean.turn_off
target:
entity_id: input_boolean.disarming_in_progress
mode: restart means: another opening during the countdown resets the timer. That protects against a series of false triggers from a contact sensor. The leaving_home_in_progress = off condition prevents an alarm when you're just leaving and closing the door behind you with the alarm already armed.
Automation 4: motion in the interior zone
Interior motion while the alarm is armed with no active disarming window is treated as an intruder already inside the house. There's no 60 seconds here: the alarm fires right away.
automation:
- alias: "Alarm: motion in the interior zone"
description: "An instant alarm for interior PIR while the house is armed"
mode: single
triggers:
- trigger: state
entity_id:
- binary_sensor.hallway_motion
- binary_sensor.garage_motion
to: "on"
conditions:
- condition: state
entity_id: input_boolean.home_alarm_armed
state: "on"
- condition: state
entity_id: input_boolean.disarming_in_progress
state: "off"
- condition: state
entity_id: input_select.home_mode
state: "Away"
actions:
- action: script.turn_on
target:
entity_id: script.intrusion_alarm
data:
variables:
title: "ALARM: motion in the interior zone"
message: >
{{ state_attr(trigger.entity_id, 'friendly_name') or trigger.entity_id }}.
Motion detected while the alarm is armed.
While disarming_in_progress is on: PIR doesn't trigger the alarm. That lets you come in, walk through the hallway, and get to the dashboard in time to disarm.
Automation 5: clearing the disarm window after turning off the alarm
When the alarm gets turned off: manually, through Home mode, or after a false alarm: the disarming_in_progress helper has to go back to off. Otherwise the system could think an entry countdown is still running.
automation:
- alias: "Alarm: clear disarm window after alarm off"
description: "Clears disarming_in_progress when the alarm is disarmed"
mode: single
triggers:
- trigger: state
entity_id: input_boolean.home_alarm_armed
to: "off"
actions:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.disarming_in_progress
Put a toggle for home_alarm_armed on the dashboard. That's your starter "PIN code": simple, but visible. Later you can add a numeric code via input_text and a condition in the automation.
Automation 6: a false alarm: stop the escalation
A false alarm isn't embarrassing: it's a normal part of living with automation. What matters is stopping the siren, the repeats, and the texts quickly. You'll use the script from Lesson 3.
A dedicated acknowledgment for intrusion
Use input_boolean.intrusion_alarm_acknowledged from Lesson 3: not a shared global helper. Acknowledging a flood alarm shouldn't be able to stop an intrusion escalation, and vice versa.
automation:
- alias: "Alarm: false alarm: stop"
description: "Calls security_alarm_stop and disarms the house"
mode: single
triggers:
- trigger: state
entity_id: input_boolean.intrusion_alarm_acknowledged
to: "on"
conditions:
- condition: state
entity_id: input_boolean.intrusion_alarm_active
state: "on"
actions:
- action: script.turn_on
target:
entity_id: script.security_alarm_stop
- action: input_boolean.turn_off
target:
entity_id:
- input_boolean.home_alarm_armed
- input_boolean.disarming_in_progress
- action: script.notify_household
data:
title: "False alarm: stopped"
message: "Escalation turned off. Check the cause and the home mode."
The intrusion_alarm_acknowledged helper from Lesson 3 works here as "I've seen it, it's a false alarm: shutting it down." After stopping it, check the log: what opened the zone, what home mode was active, whether GPS had time to catch up.
Automation 7: a home alarm test
The alarm test only runs when home_alarm_armed is on. If you click the test with the alarm disarmed, a separate automation clears the helper and shows a message, instead of leaving the test stuck on on.
The test can trigger the full escalation
If you turned on SMS, a siren, or repeats in Lesson 3, the home alarm test can fire the exact same channels. Test during the day, warn the household, and keep the script.security_alarm_stop stop button within reach.
automation:
- alias: "Alarm: home alarm test"
description: "Simulates an alarm with no door opening"
mode: single
triggers:
- trigger: state
entity_id: input_boolean.home_alarm_test
to: "on"
conditions:
- condition: state
entity_id: input_boolean.home_alarm_armed
state: "on"
actions:
- action: script.turn_on
target:
entity_id: script.intrusion_alarm
data:
variables:
title: "TEST: home alarm"
message: "This is a supporting alarm test. Check the siren, the push, and acknowledgment."
- delay:
seconds: 3
- action: input_boolean.turn_off
target:
entity_id: input_boolean.home_alarm_test
Automation 8: reset the test when the alarm isn't armed
automation:
- alias: "Alarm: reset test when the alarm isn't armed"
description: "Turns off the test helper if it was triggered with the alarm disarmed"
mode: single
triggers:
- trigger: state
entity_id: input_boolean.home_alarm_test
to: "on"
conditions:
- condition: state
entity_id: input_boolean.home_alarm_armed
state: "off"
actions:
- delay:
seconds: 2
- action: input_boolean.turn_off
target:
entity_id: input_boolean.home_alarm_test
- action: script.notify_household
data:
title: "Alarm test canceled"
message: "The home alarm isn't armed. Arm it if you want to run a test."
Automation 9: resetting helpers after an HA restart
automation:
- alias: "Alarm: reset helpers after HA startup"
description: "Clears timed helpers and acknowledgment after a restart"
mode: single
triggers:
- trigger: homeassistant
event: start
actions:
- action: input_boolean.turn_off
target:
entity_id:
- input_boolean.disarming_in_progress
- input_boolean.home_alarm_test
- input_boolean.intrusion_alarm_acknowledged
We deliberately don't reset home_alarm_armed: after an HA restart, the alarm can stay armed if that's how it was saved. We clear intrusion_alarm_acknowledged, since after a restart it's unclear whether it still applies to an active alarm. If you'd rather always disarm after a restart, add home_alarm_armed to the reset list.
Presence + alarm = two layers
Home mode from Lesson 8 answers "should someone be home." The alarm from this lesson answers "are we watching the zones." Both can run in parallel: as long as you understand which one is responsible for what.
Dashboard: what to show
On the security card, include:
The home_alarm_armed toggle: armed / disarmed
The input_select.home_mode entity: context from Lessons 6 and 8
The disarming_in_progress indicator: you can see the countdown is running
The alarm_sensors group: zone status
The test and acknowledgment buttons from Lesson 3
How to test: carefully, and in order
Test during the day, when the household knows the siren might sound. Start with the test helper: not by actually opening a window in the cold.
1. Turn off the old opening automation from Lesson 6. Turn on the new ones from this lesson.
2. Set Away mode. Check whether home_alarm_armed turns on by itself (if you have automatic_arming enabled).
3. Arm home_alarm_armed, then turn on home_alarm_test. You should get a TEST push and a siren: with no door opening.
3b. Disarm the alarm and click the test again. The helper should return to off, and you should get an "Alarm test canceled" message.
4. Arm the alarm. Open the front door. Check the "60 seconds" message and the disarming_in_progress helper.
5. Within 60 seconds, turn off home_alarm_armed. The escalation shouldn't start.
6. Repeat the opening, but don't disarm. After 60 seconds, script.intrusion_alarm should trigger.
7. Turn on intrusion_alarm_acknowledged. The false alarm should stop.
8. Finally, run script.security_alarm_stop if anything was left on.
Common mistakes
Two alarms at once: the old Lesson 6 automation and the new one from Lesson 9: turn off the old one.
PIR by the door: every entry triggers the delay and the interior alarm at the same time: move the PIR deeper into the house.
No disarm switch on the dashboard: 60 seconds pass before you find the toggle in the menu.
Testing without arming: without Automation 8, the home_alarm_test helper stays on on: add the reset from this lesson.
Arming with a window open: the alarm arms, but it detects nothing, since the state is already on: check the zones before you leave.
Arming with guests over: turn off automatic_arming and set Guests mode from Lesson 8.
What not to do
Don't pretend the HA alarm replaces a monitored system or a monitoring center.
Don't arm the house with no entry delay: false alarms destroy trust faster than no alarm at all.
Don't copy the SMS-repeat logic into every zone automation: call script.intrusion_alarm instead.
Don't test the full escalation at night without warning the household.
Practical assignment
☐ Add the home_alarm_armed, disarming_in_progress, automatic_arming, home_alarm_test, and alarm_entry_delay_seconds helpers.
☐ Create the perimeter_zone, interior_zone, and alarm_sensors groups with your own entities.
☐ Turn off the opening automation from Lesson 6. Paste in Automations 1-9 from this lesson.
☐ Test the entry delay: disarming within 60 seconds, and an alarm once the time runs out.
☐ Test a false alarm via intrusion_alarm_acknowledged and security_alarm_stop.
☐ Add the alarm toggle, the disarm-window indicator, and the sensor group to the dashboard.
Key takeaways
A supporting alarm is not a monitored system: HA adds logic and notifications, not a monitoring contract.
60 seconds to enter solves lagging GPS and stale Away mode: as long as you disarm the alarm on the dashboard.
The perimeter and interior zones respond differently: a door gives you time, interior PIR alarms instantly.
One escalation script: every zone calls script.intrusion_alarm.
Tests have to reset themselves: a test helper can't stay stuck on on after a canceled test.
The shared acknowledgment helper from Lesson 3 works globally: know exactly when it also disarms the home alarm.
You need to be able to stop a false alarm: otherwise the system loses the household's trust.
What's next
In Lesson 10, we'll look at what happens when the security system itself fails: no internet, no power, an offline sensor, a low battery. An alarm and its notifications are only as good as the weakest link in the chain.
After this lesson you have a coherent foundation: you detect hazards, set the home-mode context, arm zones with an entry delay, and escalate through one proven script. This is no longer a pile of separate automations: it's a response system.