[ Home Automation — Snippets ]
[ Low-battery aggregator |
Smart-charging cutoff |
Door-left-open alert |
Door auto-lock |
Evening lights ]
Smaller standalone automations and templates that don't warrant their own page — one-liners, helper sensors, and YAML patterns extracted from larger setups. Each snippet is shown inline below; copy what you need into your own configs. These pair naturally with the longer guides on the parent page (alarm system, ESP32 Bluetooth proxy, Volcano + HA) and the external references in Links & Resources.
[ Low-battery aggregator (any device under N%) ]
Low-battery aggregator (any device under N%) — 2026
A template binary_sensor that fires on when any sensor with device_class: battery drops below your threshold — without having to enumerate every device individually. Drop new battery-powered devices into HA and they get monitored automatically. Pattern: iterate states.sensor with a Jinja namespace to short-circuit on the first match. Cheaper than building a list and checking length when you have many sensors. The devices attribute gives you a friendly name list for the notification body.
# configuration.yaml — drop in alongside your existing template: blocks
template:
- binary_sensor:
- name: "Any low battery"
unique_id: any_low_battery
state: >-
{% set threshold = 20 %}
{% set ns = namespace(found=false) %}
{% for s in states.sensor
if s.attributes.device_class == 'battery'
and s.state not in ['unknown', 'unavailable'] %}
{% if s.state | int(100) < threshold %}
{% set ns.found = true %}
{% endif %}
{% endfor %}
{{ ns.found }}
attributes:
# Friendly list for the notification body
devices: >-
{% set threshold = 20 %}
{% set out = namespace(names=[]) %}
{% for s in states.sensor
if s.attributes.device_class == 'battery'
and s.state not in ['unknown', 'unavailable']
and s.state | int(100) < threshold %}
{% set out.names = out.names + [s.name + ' (' + s.state + '%)'] %}
{% endfor %}
{{ out.names | join(', ') }}
# automations.yaml — notify once per device when threshold tripped
- alias: "Low battery: notify"
trigger:
- platform: state
entity_id: binary_sensor.any_low_battery
to: "on"
action:
- action: notify.mobile_app_magikh0e_phone
data:
title: "🔋 Low battery"
message: "{{ state_attr('binary_sensor.any_low_battery', 'devices') }}"
[ Smart-charging cutoff (stop at 80%) ]
Smart-charging cutoff (stop at 80%) — 2026
Battery longevity hack — lithium cells age fastest when held between 80–100% charge, so cutting the charger at 80% extends the cell's useful life by 2–3×. Pairs the HA companion app's battery_level + battery_state sensors with a smart plug or zigbee outlet that the charger is plugged into. Pattern: numeric-state trigger + state condition gates the action. The condition is what makes this safe to leave armed — without it, the automation would fire every time the phone passed 80% even if it wasn't currently charging (e.g., during normal discharge).
# automations.yaml
- alias: "Phone: stop charging at 80%"
description: "Cut the charger plug when phone hits 80% to preserve the cell"
mode: single
trigger:
- platform: numeric_state
entity_id: sensor.magikh0e_phone_battery_level
above: 79
condition:
# Only act if actually charging — prevents firing on normal discharge
- condition: state
entity_id: sensor.magikh0e_phone_battery_state
state: "charging"
action:
- action: switch.turn_off
target:
entity_id: switch.bedroom_charger_outlet
- action: notify.mobile_app_magikh0e_phone
data:
title: "🔋 80% — charger off"
message: "Battery longevity preserved. Plug in again to override."
[ Door "left open" alert + closed announcement ]
Door "left open" alert + closed announcement — 2026
Two paired automations for "the front door has been open for a
while" situations.
- Open alert — after the door's been open 30 seconds,
fires a phone push + Nest TTS announcement, then repeats every
~10 minutes while the door stays open.
- Closed announcement — plays a 'door closed' TTS when
the door is finally shut, but only if it had been open more than
30 seconds. Suppresses the closed-TTS for quick in/out trips so
the house doesn't narrate every time you grab the mail.
Pattern: state + for: as the trigger (30-second debounce),
then a while: loop that re-checks the contact sensor every
~10 min and only continues while it's still open. The companion
closed-announcement uses a template condition on
trigger.from_state.last_changed to gate on how long the door
was open before closing.
Retarget at any contact-sensor + notify-target + speaker by swapping
three entity_ids (front_door_door, mobile_app_magikh0e_phone,
nest_display).
# automations.yaml
# 1. Alert when door is left open
- alias: "Front Door Left Open Alert"
description: "Notifies + announces when front door has been open for 30s, repeating every ~10 min"
trigger:
- platform: state
entity_id: binary_sensor.front_door_door
to: "on"
for: "00:00:30"
action:
# Loop while the door remains open
- repeat:
while:
- condition: state
entity_id: binary_sensor.front_door_door
state: "on"
sequence:
- action: notify.mobile_app_magikh0e_phone
data:
title: "Front Door"
message: "The front door has been left open"
- action: media_player.play_media
target:
entity_id: media_player.nest_display
data:
media_content_id: >-
media-source://tts/tts.piper?message=The+front+door+has+been+left+open&language=en_US
media_content_type: audio/mp3
# Wait before the next reminder (only fires if door is still open)
- delay: "00:10:45"
# 2. Announce when the door is closed (only if it had been open a while)
- alias: "Front Door Closed Announcement"
description: "Plays a 'door closed' TTS when the front door is closed after being open more than 30s"
trigger:
- platform: state
entity_id: binary_sensor.front_door_door
from: "on"
to: "off"
condition:
# Only fire if the door had been open at least 30 seconds — skips quick in/out
- condition: template
value_template: >-
{{ (now() - trigger.from_state.last_changed).total_seconds() > 30 }}
action:
- action: media_player.play_media
target:
entity_id: media_player.nest_display
data:
media_content_id: >-
media-source://tts/tts.piper?message=The+front+door+has+been+closed&language=en_US
media_content_type: audio/mp3
[ Door auto-lock with open-door safety ]
Door auto-lock with open-door safety — 2026
Re-lock the front door if it's been left unlocked for 5 minutes, unless the door itself is currently open (locking with the door open jams most smart-lock bolts against the strike plate). Pairs a smart lock entity with the contact sensor on the same door — both common Z-Wave / Zigbee setups. Pattern: state + for: duration as the trigger debounces brief unlocks. condition on the contact sensor adds the safety interlock — a deceptively important detail that prevents your auto-lock from grinding the bolt against the frame every time you walk groceries inside.
# automations.yaml
- alias: "Front Door: auto-lock after 5 min"
description: "Re-lock if left unlocked for 5 min, only if door is closed"
mode: single
trigger:
- platform: state
entity_id: lock.front_door
to: "unlocked"
for: "00:05:00"
condition:
# Don't lock against an open door — bolt vs strike plate is bad news
- condition: state
entity_id: binary_sensor.front_door_door
state: "off"
action:
- action: lock.lock
target:
entity_id: lock.front_door
- action: notify.mobile_app_magikh0e_phone
data:
title: "🔒 Auto-locked"
message: "Front door re-locked after 5 min unlocked."
[ Outdoor lights — sunset fade-in / overnight fade-out ]
Outdoor lights — sunset fade-in / overnight fade-out — 2026
Also available as a one-instantiate-per-light HA blueprint (writeup) — the same three-stage cycle wrapped as a single automation with configurable color, brightness, durations, sunset offset, and a sun-elevation gate. Use the blueprint if you want a UI install + per-light instances; use the snippet below if you'd rather hand-roll three plain automations. For a longer write-up with a step-fade alternative (three sunset- anchored stages instead of one long ramp), a color reference, and a troubleshooting table, see the full Outdoor lights guide. This snippet is the simple-fade variant only. Three coordinated automations driving an outdoor RGB light through a gentle daily cycle: lights grow in over 30 minutes starting at sunset, fade back down over 30 minutes starting at 23:30, and switch off at midnight. The colour stays at a warm 2200K-ish amber the whole time (RGB 255,147,41 — close to a candle / old-school sodium streetlight, easy on the eyes after dark). Pattern — the two-step fade-on. Home Assistant can't transition: from the off state directly;light.turn_on ... transition: 1800against a bulb that's currently off just snaps to the target brightness instantly. Workaround: issue two back-to-back calls. The first turns the bulb on at 1% with the desired colour and NO transition (establishes the starting state). After a 5-second settle, the second call requests the target brightness WITH the long transition, and the bulb actually animates from 1% → 50% over the full 30 minutes. The fade-out side doesn't need the trick because the light is already on -- a singlelight.turn_on ... transition: 1800works from any non-off state. The midnight automation then does the actuallight.turn_offafter the fade has run its course. To adapt: changelight.lanai_lightto your entity_id, swap thergb_colorif you want a different tint (cooler white = 255,180,107; pure-amber = 255,140,30), and shift the'23:30:00'/'00:00:00'times to taste.
# automations.yaml
- id: 'lanai_lights_sunset_on'
alias: 'Lanai: Evening Lights Fade In at Sunset'
description: 'Gradually fades lanai lights on at sunset over 30 minutes'
triggers:
- trigger: sun
event: sunset
conditions: []
actions:
# Step 1 -- establish starting state at 1% with the target colour.
# No `transition:` here on purpose; HA can't transition from off.
- action: light.turn_on
target:
entity_id: light.lanai_light
data:
brightness_pct: 1
rgb_color: [255, 147, 41]
- delay:
seconds: 5
# Step 2 -- now that the bulb is on, request the real fade.
- action: light.turn_on
target:
entity_id: light.lanai_light
data:
brightness_pct: 50
rgb_color: [255, 147, 41]
transition: 1800 # 30 minutes
mode: single
- id: 'lanai_lights_fade_out'
alias: 'Lanai: Evening Lights Fade Out at 11:30pm'
description: 'Gradually fades lanai lights out from 11:30pm over 30 minutes'
triggers:
- trigger: time
at: '23:30:00'
conditions:
# Don't try to fade out a light that's already off (e.g. someone
# turned it off manually earlier).
- condition: state
entity_id: light.lanai_light
state: 'on'
actions:
- action: light.turn_on
target:
entity_id: light.lanai_light
data:
brightness_pct: 1
transition: 1800 # 30 minutes
mode: single
- id: 'lanai_lights_midnight_off'
alias: 'Lanai: Evening Lights Off at Midnight'
description: 'Turns off lanai lights at midnight after fade out'
triggers:
- trigger: time
at: '00:00:00'
conditions: []
actions:
- action: light.turn_off
target:
entity_id: light.lanai_light
mode: single
