Each automation is one trigger, condition and action block. A sun trigger takes offset -00:30:00 to fire before sunset. Motion lights hold with wait_for_trigger instead of delay, so movement resets the timeout. A dishwasher alert waits for power below 5 watts sustained two minutes. Two-person away mode must condition on both, because the trigger fires on whoever leaves first.
By LK Wood IV · 2026-06-16 · ~15 min read · St. Louis County, MO
Home Assistant automations follow a consistent structure: something happens (trigger), check if conditions are met (conditions), then do things (actions). Once you understand that structure, you can write almost any automation. This guide is examples-first — real working YAML for the automations that actually matter.
If you haven’t set up Home Assistant yet, the Home Assistant on Proxmox guide covers the install. For Zigbee/Z-Wave devices, the integration guide covers pairing.
The automation structure
automation:
- alias: "My Automation Name"
trigger:
- platform: <trigger_type>
# trigger-specific fields
condition:
- condition: <condition_type>
# condition-specific fields
action:
- service: <domain.service>
target:
entity_id: <entity_id>
data:
# service-specific data
Trigger: what initiates the automation (state change, time, zone entry, webhook, etc.) Condition: optional guards — the automation only proceeds if all conditions pass Action: what happens when the trigger fires and conditions pass
Lighting automations
Turn on lights at sunset
automation:
- alias: "Living Room — Lights On at Sunset"
trigger:
- platform: sun
event: sunset
offset: "-00:30:00" # 30 minutes before actual sunset
action:
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 60
color_temp: 400 # warm color temperature (mireds)
The offset field accepts positive or negative durations. -00:30:00 means 30 minutes before the event.
Adaptive lighting: dim at night
automation:
- alias: "Bedroom — Dim Lights After 10 PM"
trigger:
- platform: time
at: "22:00:00"
condition:
- condition: state
entity_id: light.bedroom
state: "on"
action:
- service: light.turn_on
target:
entity_id: light.bedroom
data:
brightness_pct: 20
color_temp: 500 # very warm
transition: 10 # 10-second transition
The condition here prevents the automation from triggering the bedroom lights if they’re already off — you don’t want the lights turning on at 10 PM just to dim them.
Motion-triggered lights with timeout
automation:
- alias: "Hallway — Motion Light"
trigger:
- platform: state
entity_id: binary_sensor.hallway_motion
to: "on"
action:
- service: light.turn_on
target:
entity_id: light.hallway
- delay: "00:05:00" # wait 5 minutes
- condition: state # only turn off if still no motion
entity_id: binary_sensor.hallway_motion
state: "off"
- service: light.turn_off
target:
entity_id: light.hallway
For more reliable motion timeout behavior, use the wait_for_trigger action instead of delay:
action:
- service: light.turn_on
target:
entity_id: light.hallway
- wait_for_trigger:
- platform: state
entity_id: binary_sensor.hallway_motion
to: "off"
for: "00:05:00"
- service: light.turn_off
target:
entity_id: light.hallway
wait_for_trigger pauses the action sequence until the trigger fires, then continues. If the motion sensor never clears, the action sequence waits indefinitely (use timeout: to cap it).
Presence-based automations
Welcome home scene
automation:
- alias: "Welcome Home — Set Living Room Scene"
trigger:
- platform: zone
entity_id: person.lk
zone: zone.home
event: enter
condition:
- condition: sun
after: sunset
before: sunrise
action:
- service: scene.turn_on
target:
entity_id: scene.living_room_evening
- service: climate.set_temperature
target:
entity_id: climate.main_thermostat
data:
temperature: 70
The sun condition ensures the welcome home lighting only triggers after dark. Arriving home at noon doesn’t need the lights on.
Everyone left — eco mode
automation:
- alias: "All Away — Energy Saving Mode"
trigger:
- platform: state
entity_id:
- person.lk
- person.partner # list multiple people
to: "not_home"
condition:
- condition: state
entity_id: person.lk
state: "not_home"
- condition: state
entity_id: person.partner
state: "not_home"
action:
- service: climate.set_temperature
target:
entity_id: climate.main_thermostat
data:
temperature: 65 # setback temperature
- service: light.turn_off
target:
area_id: living_room
- service: notify.mobile_app_phone
data:
message: "Away mode activated."
The trigger fires when any person changes to not_home. The conditions verify that ALL tracked people are away before applying eco mode — so the trigger fires but conditions gate it until the last person leaves.
Notification automations
Dishwasher done
This works with a smart plug that measures wattage (Zigbee or Z-Wave smart outlet):
automation:
- alias: "Dishwasher — Done Notification"
trigger:
- platform: numeric_state
entity_id: sensor.dishwasher_power
below: 5 # watts — below this = cycle complete
for: "00:02:00"
condition:
- condition: numeric_state
entity_id: sensor.dishwasher_power
above: 0.1 # was actually running (not just idle/off)
action:
- service: notify.mobile_app_phone
data:
title: "Dishwasher Done"
message: "Cycle complete."
The for: "00:02:00" on the trigger prevents false positives from mid-cycle power dips — the wattage has to stay below 5W for two minutes before triggering.
Low battery alert
automation:
- alias: "Low Battery — All Devices"
trigger:
- platform: numeric_state
entity_id:
- sensor.front_door_lock_battery
- sensor.bedroom_motion_battery
- sensor.thermostat_battery
- sensor.smoke_detector_battery
below: 20
action:
- service: notify.mobile_app_phone
data:
title: "Low Battery"
message: "{{ trigger.to_state.name }} is at {{ trigger.to_state.state }}%"
The template {{ trigger.to_state.name }} and {{ trigger.to_state.state }} pull the entity’s display name and current value from the trigger context — so one automation handles multiple devices and tells you specifically which one is low.
Template-based automations
Door left open warning
automation:
- alias: "Front Door — Left Open Alert"
trigger:
- platform: state
entity_id: binary_sensor.front_door
to: "on"
for: "00:10:00" # open for 10 minutes
condition:
- condition: template
value_template: "{{ states('person.lk') == 'home' }}"
action:
- service: notify.mobile_app_phone
data:
message: "Front door has been open for 10 minutes."
- service: tts.speak
target:
entity_id: media_player.kitchen_speaker
data:
message: "The front door is still open."
The template condition checks that someone is home before sending the alert — no point in notifying if no one is there to close it.
Thermostat override protection
automation:
- alias: "Thermostat — Override Detection"
trigger:
- platform: state
entity_id: climate.main_thermostat
attribute: temperature
condition:
- condition: template
value_template: >
{{ trigger.to_state.attributes.temperature | float > 78 and
now().hour >= 1 and now().hour < 6 }}
action:
- service: climate.set_temperature
target:
entity_id: climate.main_thermostat
data:
temperature: 70
- service: notify.mobile_app_phone
data:
message: "Thermostat was set above 78°F at night — reset to 70°F."
Choose blocks: conditional action branching
When you need the automation to do different things based on a condition, use choose:
automation:
- alias: "Motion — Lighting by Time of Day"
trigger:
- platform: state
entity_id: binary_sensor.living_room_motion
to: "on"
action:
- choose:
- conditions:
- condition: time
after: "06:00:00"
before: "20:00:00"
sequence:
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 90
color_temp: 250 # cooler, daytime
- conditions:
- condition: time
after: "20:00:00"
before: "23:00:00"
sequence:
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 40
color_temp: 500 # warm, evening
default:
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 10
color_temp: 600 # very warm, late night
Scripts: reusable action sequences
Put repeated action sequences in scripts:
# configuration.yaml
script:
good_morning:
alias: "Good Morning Routine"
sequence:
- service: light.turn_on
target:
area_id: bedroom
data:
brightness_pct: 30
color_temp: 200 # cool/bright
transition: 120 # 2-minute sunrise
- service: climate.set_temperature
target:
entity_id: climate.main_thermostat
data:
temperature: 70
- delay: "00:02:00"
- service: light.turn_on
target:
entity_id: light.kitchen
data:
brightness_pct: 80
Call this script from any automation or button press:
action:
- service: script.good_morning
Debugging automations
Trace view: Settings → Automations → open automation → Traces. Shows every firing with the trigger value, each condition result (pass/fail with values), and each action outcome.
Template testing: Developer Tools → Template. Paste any Jinja2 expression and see it evaluate against current state in real time. Use this to test conditions before putting them in an automation.
Entity history: Developer Tools → States. See the current value and last-changed time for any entity. Useful when an automation isn’t triggering — check if the entity state is actually what you think it is.
Logbook: Settings → Logbook. Shows state changes and automation fires in chronological order. Filter by entity to see exactly when something changed.
Best practices
Use for: on state triggers to avoid automations firing on momentary state changes (a sensor flickering, a button double-press).
Avoid complex logic in a single automation — break it into an automation that calls a script, with multiple scripts for different conditions. Simpler automations are easier to debug.
Version control your config — store your configuration.yaml and automation files in a Gitea repository. The Docker Compose starter stack includes Gitea for exactly this.
Use areas and labels — Home Assistant’s area grouping lets you target all lights in a room without listing entity IDs. area_id: living_room in a target covers everything in that area, including devices added later.
This guide extends the setup work from the Home Assistant on Proxmox guide and the Zigbee/Z-Wave integration guide. The automations here assume your devices are already paired and showing correct state in HA.
Sources
- Home Assistant: Automating Home Assistant – official overview of the trigger/condition/action automation model.
- Home Assistant: Automation triggers – official reference for state, time, sun, zone, and numeric_state triggers.
- Home Assistant: Conditions – official reference for state, numeric_state, template, time, and sun conditions.
- Home Assistant: Script syntax – official reference for action sequences, choose blocks, delay, and wait_for_trigger.
- Home Assistant: Templating – official reference for the Jinja2 templates used in value_template and action data.
Frequently asked questions
Should I use the Home Assistant automation UI or YAML?
What is the difference between an automation and a script in Home Assistant?
How do I debug an automation that isn't firing?
What is a template in Home Assistant?
{{ states('sensor.temperature') | float > 75 }} evaluates to true or false based on the current temperature sensor reading. Templates are used in condition value_templates, in action data (to compute a brightness value from a sensor), and in trigger value_templates (to trigger on computed conditions).How do I trigger an automation when someone arrives home?
Evidence ledger
- Last updated
- Methodology
- This tutorial was written and edited by Lowell K. Wood IV in St. Louis County, MO. Specs, prices, commands, and version numbers are drawn from the official vendor, reseller, and project documentation current on the date above, and were verified before publishing. First-person hardware claims appear only where the article shows a verifiable artifact — a photo, receipt, or measurement — or links to the TechFuelHQ Open Bench Datasets. Every fact is human-verified against its cited source before publishing; AI assists with first-draft structure and source-gathering, not with the verdict. Full editorial standard: methodology.
- Update log
- 2026-07-25 — Last reviewed and updated.
- Corrections
- Spotted an error or stale price? Email hello@techfuelhq.com. Confirmed corrections are added to the update log above.