Each automation has triggers, optional conditions and actions. A sun trigger takes offset -00:30:00 to fire before sunset. Motion lights can wait for five continuous minutes without motion. A dishwasher alert first records sustained running power in a helper, then waits for power below 5 watts for two minutes. Two-person away mode checks that both people are away.
Contents
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
The visual editor supports complex action sequences too. Its YAML view edits the same UI-managed automation. For hand-maintained files, the YAML documentation distinguishes automations.yaml from labeled blocks in configuration.yaml. The full examples below go in configuration.yaml; merge their list entries into one automation block or give each block a distinct label. In the UI YAML editor, paste one automation without the enclosing automation: key and list marker.
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_kelvin: 2500 # warm
The offset field accepts positive or negative durations. -00:30:00 means 30 minutes before the event.
Use color_temp_kelvin for temperature-capable lights. Home Assistant removed the old mired argument in 2026.3. The examples convert mireds with kelvin = 1000000 / mireds, rounded to a whole kelvin; choose a value within your light’s supported range.
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_kelvin: 2000 # 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
Use a smart plug rated for the dishwasher’s load that reports watts. This example records a running cycle in an input boolean helper before allowing a completion alert:
input_boolean:
dishwasher_running:
name: Dishwasher running
# No initial value: restore the previous state after a restart.
automation dishwasher:
- id: dishwasher_record_running
alias: "Dishwasher - Record Running Cycle"
trigger:
- platform: numeric_state
entity_id: sensor.dishwasher_power
above: 10 # watts; tune from a complete cycle's power history
for: "00:01:00"
action:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.dishwasher_running
- id: dishwasher_notify_done
alias: "Dishwasher - Done Notification"
trigger:
- platform: template
value_template: >-
{{ is_state('input_boolean.dishwasher_running', 'on') and
is_number(states('sensor.dishwasher_power')) and
states('sensor.dishwasher_power') | float(0) < 5 }}
for: "00:02:00"
action:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.dishwasher_running
- service: notify.mobile_app_phone
data:
title: "Dishwasher Done"
message: "Cycle complete."
An idle reading cannot notify while the helper is off. Unknown or unavailable readings also cannot complete a cycle. The helper survives a normal restart; the two-minute trigger timer starts over after a restart or automation reload. The 10 W, one-minute start and 5 W, two-minute finish values are examples. Inspect a full wash and drying cycle and lengthen the finish interval beyond any mid-cycle pause. Clear the helper manually after a canceled cycle. Verify an idle period, a short dip and a completed cycle in Traces before relying on the alert.
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_kelvin: 4000 # 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_kelvin: 2000 # warm, evening
default:
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 10
color_temp_kelvin: 1667 # very warm; check your light's minimum
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_kelvin: 5000 # 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
After adapting entity IDs, run Developer Tools → YAML → Check configuration before reloading manual YAML. Test each light action with a supported kelvin value and check the automation trace. These examples were reviewed against current documentation on 2026-10-12; a YAML parse alone does not verify your installed integrations, devices or notification service.
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.
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. If you’d rather trigger these by voice than by dashboard, the local LLM voice guide covers HA 2026.8’s llama.cpp integration — including which models actually target the right entities.
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?
Sources and corrections
- Last updated
- Methodology
- See our methodology for research and review standards.
- Corrections
- Spotted an error or a stale number? Email contact@techfuelhq.com. Confirmed corrections are recorded here with the date and change.