Home Assistant Automations: A Practical Guide with Real Examples
Hubs & Bridges

Home Assistant Automations: A Practical Guide with Real Examples

Learn Home Assistant automations the right way in 2026: triggers, conditions, actions, blueprints, templates, and real Zigbee, Z-Wave examples explained.

16 min read

Disclosure: Some links in this article are affiliate links. We may earn a commission on qualifying purchases at no extra cost to you.

Most Home Assistant tutorials teach automations as an abstract flowchart — trigger, condition, action, done — and leave you to figure out why your motion light turns off mid-conversation or why a blueprint won't do the one extra thing you need. The mental model is simple; what trips people up is applying it to real hardware with real quirks, and picking the setting (automation mode, template syntax, blueprint vs. custom YAML) that actually matches the job.

This guide builds the model first, then applies it directly to devices commonly running on Home Assistant setups: an Aqara motion sensor, a SONOFF door sensor, a Zigbee smart plug, a Philips Hue bulb, and a Z-Wave smart lock. Every example is written against the current automation engine, including the purpose-specific triggers ("when a light turns on" instead of raw state matching) that became the default behavior in the 2026.7 release.

By the end, you'll be able to build automations in either the UI editor or YAML, know when to reach for a blueprint instead of writing one from scratch, use Jinja2 templates without fighting string-vs-number errors, and — critically — pick the automation mode that prevents your automation from silently dropping triggers.

This is written for anyone running Home Assistant locally, from a first Zigbee sensor to a multi-protocol setup mixing Zigbee, Z-Wave, and Matter. No cloud dependency required — everything below runs entirely on your own network.

What You'll Need

  • A running Home Assistant instance (Home Assistant OS, Container, or Supervised)
  • A Zigbee coordinator or dongle if you're pairing Zigbee devices directly (ZHA or Zigbee2MQTT)
  • At least one trigger-capable device — a motion sensor, door sensor, or smart plug all work
  • Optional: a Z-Wave controller if you're using Z-Wave locks or sensors
  • 15–20 minutes for your first automation; longer if you're importing and customizing a blueprint

Before You Start — How Automations Actually Work

Every Home Assistant automation reduces to one sentence: when something happens, optionally check a condition, then do something. In the tool itself, that's trigger → condition → action, and the condition step is optional — plenty of useful automations skip it entirely.

Two things matter before you write your first one:

Everything lives in the same file. Whether you build in the visual UI editor or write raw YAML, both write to automations.yaml. The "Edit in YAML" button in the UI editor opens the exact YAML representation of what you built visually — there's no hidden translation layer, no lock-in. You can start in the UI and drop into YAML the moment you need a choose block or a loop the UI doesn't expose cleanly.

Conditions are ANDed by default. Stack three condition blocks and all three must pass — no wrapper needed. You only add an explicit condition: or or condition: and block when you're mixing logic (e.g., "condition A AND (condition B OR condition C)"). Adding redundant AND wrappers around a single list of conditions doesn't break anything, it just adds noise when you're debugging later.

One more piece of context worth knowing before you start: as of the 2026.7 release, Home Assistant defaults to purpose-specific triggers — instead of matching a raw state string, you pick "when a light turns on" or "if the climate is heating" directly from the trigger picker. These graduated from Home Assistant Labs (introduced 2025.12) to the default experience for everyone in 2026.7, and legacy template platform syntax was removed as part of the same cleanup in 2026.6. If you're following an older tutorial or an AI-generated YAML snippet, this is often exactly why it won't paste in cleanly anymore.

Step 1 — Trigger, Condition, Action: The Core Model, Applied to Real Devices

Abstract examples don't stick. Here's the model against a specific, widely used sensor: the Aqara Motion Sensor P1, a Zigbee 3.0 PIR sensor with a 170° field of view up to 4 meters (150° up to 7 meters), a built-in lux sensor, and an adjustable detection timeout from 1 to 200 seconds — configurable through the Aqara Home app before pairing to Home Assistant, or via cluster attributes in Zigbee2MQTT. It runs on two CR2430 cells, and Aqara's own spec sheet notes up to five years of battery life when the LED indicator is disabled and the timeout is kept at 30 seconds or higher.

A basic hallway-light automation using this sensor looks like:

  • Trigger: occupancy on the Aqara P1 changes to detected
  • Condition: the P1's built-in lux sensor reads below a threshold (so lights don't fire at noon)
  • Action: turn on the hallway light

The lux condition is the piece most beginner guides skip — because the P1 has an onboard illuminance sensor, you don't need a separate light sensor or a sun-elevation condition to get "only turn on when it's actually dark." That's also why the P1 shows up repeatedly in community write-ups as the reference motion sensor for Home Assistant: the lux data replaces an entire second device.

One quirk worth flagging before you buy: Aqara sensors can develop meshing quirks in mixed Zigbee networks — they sometimes stick to the first router they paired with even after signal degrades, leading to weak LQI or dropped events. Keeping router-capable devices (plugs, mains-powered bulbs) nearby mitigates this; it's not a dealbreaker, just a wiring consideration for larger homes.

Check the Aqara Motion Sensor P1 on Amazon

Step 2 — UI Editor or YAML? Pick the Right Tool for the Job

There's no "correct" choice here — both editors produce identical automations, because both write the same file. The decision is about what you're building:

Use the UI editor when… Use YAML when…
You're discovering what triggers/conditions exist You need a choose block with multiple branches
The automation is a straight trigger → condition → action You're combining nested AND/OR logic
You want a visual trace of what fired You want to version-control your automations in Git
You're new to Home Assistant You're copying a community-shared example

Every automation entry — UI or YAML — needs a unique id. The UI editor generates one automatically; if you hand-write YAML and skip it, the UI editor won't be able to edit that automation later, though it will still run.

Practical workflow: build in the UI, click "Edit in YAML" the moment you hit a wall, and don't be afraid to move back and forth. The two aren't separate tools, they're two views of the same file.

Step 3 — Build a Motion + Lux Automation with the Right Mode from the Start

Take the P1 automation from Step 1 and add the setting most tutorials leave at its default: automation mode. This single dropdown, buried at the bottom of the automation editor, decides what happens when the trigger fires again while the automation is still running — and it is, per Home Assistant lead developer Franck Nijhof, the most overlooked setting in the entire automation system. In his own words: "If you see 'already running' warnings, that is usually Home Assistant telling you that single is dropping triggers. Either that is intentional throttling, or it is a sign the mode is wrong."

For a motion-activated light, the default single mode is close to always wrong: if someone re-enters the room while the light's off-timer is counting down, single ignores the new trigger and the light turns off underneath them. Switching to restart mode fixes it — each new motion event restarts the automation's countdown from zero.

automation:
  - alias: "Hallway light on motion after dark"
    id: hallway_light_motion_lux
    mode: restart
    triggers:
      - trigger: state
        entity_id: binary_sensor.hallway_p1_occupancy
        to: "on"
    conditions:
      - condition: numeric_state
        entity_id: sensor.hallway_p1_illuminance
        below: 50
    actions:
      - action: light.turn_on
        target:
          entity_id: light.hallway
      - delay: "00:02:00"
      - action: light.turn_off
        target:
          entity_id: light.hallway

The four available modes each solve a distinct problem:

Mode Behavior when re-triggered Best for
single (default) Ignores new triggers, logs a warning Automations that should only ever run once at a time
restart Cancels the running instance, starts over Motion lights (resets the off-timer)
queued Runs new triggers one after another, in order TTS/announcements that shouldn't talk over each other
parallel Runs multiple instances simultaneously Per-event notifications, e.g. several doors/windows opening at once

Mode applies to the whole automation, not to individual triggers inside it — if you have five different triggers under one automation and need different concurrency behavior for each, that's a sign to split them into separate automations.

Step 4 — Add a Door Sensor and a Smart Plug to the Mix

Once one device works, chaining in more sensors follows the same pattern. Two common additions:

Door/window sensor → conditional lighting or arming. The SONOFF SNZB-04P is a Zigbee 3.0 contact sensor with a built-in tamper alert, a CR2477 battery rated for 5+ years, and local smart-scene control that keeps working even if your internet connection drops — it pairs directly with ZHA or Zigbee2MQTT through a coordinator like the ones covered in our Zigbee coordinator guide. A common pattern: front door closes after 11pm → arm the alarm helper and turn off downstairs lights. The predecessor SNZB-04 used a shorter-lived CR2032 cell and lacked the tamper button; if you're shopping today, the -04P is the current model.

Check the SONOFF SNZB-04P on Amazon

Smart plug → power-based triggers. A Zigbee plug like the Third Reality Smart Plug does double duty: it's a controllable outlet and, because Zigbee mains-powered devices act as network routers, it also strengthens your mesh. The metering ("Gen3") variant exposes switch, watts, and kWh entities automatically on both ZHA and Zigbee2MQTT without extra configuration — which enables one of the most requested automations in the community: a notification when a washing machine or dryer's power draw drops below roughly 2W, meaning the cycle finished. Note that the non-metering 4-pack and the energy-monitoring version are separate listings — confirm which one you're buying if the power-draw automation is the reason you want it.

automation:
  - alias: "Notify when laundry cycle finishes"
    id: laundry_done_notify
    mode: single
    triggers:
      - trigger: numeric_state
        entity_id: sensor.laundry_plug_power
        below: 2
        for: "00:03:00"
    actions:
      - action: notify.mobile_app
        data:
          message: "Laundry cycle finished."

Check the Third Reality Smart Plug on Amazon

For lighting specifically, a Philips Hue White Ambiance A19 bulb is worth calling out here because it behaves differently depending on how it's paired. Run through the Hue Bridge and you keep Hue's dynamic scenes; pair it directly to ZHA or Zigbee2MQTT and you get full local control but lose bridge-only scene data. Either way, its tunable 2200K–6500K range (not just fixed warm white) is what makes circadian-style automations possible — dimming and warming the light automatically as the evening progresses. One wiring note the community repeats often: Hue bulbs act as Zigbee routers, and mixing them on the same coordinator as Aqara or Third Reality devices can introduce 2–3 second command lag; keeping Hue on its own Zigbee network (via the bridge) avoids it. If a bulb sits behind a physical wall switch that gets toggled off, use a non-routing bulb there instead — cutting power to a router-capable bulb breaks the mesh for every device relying on it as a hop.

Check the Philips Hue White Ambiance A19 on Amazon

Step 5 — Import Blueprints Instead of Reinventing Automations

A blueprint is a reusable automation template with configurable inputs — someone else wrote the logic, you supply the entities. Import one from Settings > Automations & scenes > Blueprints > Import Blueprint, pasting in a URL from the community's Blueprints Exchange forum. Imported blueprints live in /config/blueprints/automation/ on disk.

The community's reference example is Blacky's "Sensor Light" blueprint (currently around v8.5–8.6), which combines motion sensor, door sensor, sun elevation, lux value, scenes, and time-of-day logic into a single configurable automation — frequently cited as the most complete lighting blueprint available, with the advantage that a one-click update propagates to every automation instance created from it.

The limitation worth knowing before you commit to one: blueprints can't be extended per-instance. If you need to change the trigger structure or add a condition the blueprint author didn't expose as an input, your only options are editing the blueprint source directly or converting your instance to a standalone automation via "take control" — which is one-way. Once converted, you lose the one-click update path. For straightforward, common patterns (motion + lux + time-based light control being the textbook case), a mature blueprint like Blacky's saves real setup time. For anything with unusual logic specific to your home, writing the automation directly is often less friction than fighting a blueprint's input schema.

Step 6 — Use Jinja2 Templates for Smarter Logic

Home Assistant uses Jinja2 for anything dynamic: {{ }} for expressions, {% %} for statements, {# #} for comments. Templates show up in trigger values, conditions, action data, and dedicated template sensors.

The most common beginner error is a type mismatch: entity states are always strings, so states('sensor.laundry_plug_power') < 2 will error until you convert it explicitly:

{{ states('sensor.laundry_plug_power') | float(0) < 2 }}

The | float(0) piece does two jobs at once — converts the string to a number, and supplies a default (0) if the sensor is briefly unavailable, which prevents the whole template from throwing an error during a Zigbee network blip. The same applies to | int for whole numbers. Always supply a default; templates without one are the single most common source of "why did my automation silently fail" reports.

A second gotcha: on and off are YAML boolean keywords, not strings, unless quoted. Writing a trigger condition against 'on' (quoted) rather than on (bare) avoids YAML parsing your intended string as a boolean.

Test any template live in Developer Tools > Template before wiring it into an automation — it renders in real time against your actual entity states, which is dramatically faster than trial-and-error through the automation editor.

Step 7 — Choose the Right Automation Mode (Revisited) and Avoid Losing Progress on Restart

Beyond the motion-light case in Step 3, mode choice matters anywhere an automation can be triggered faster than it finishes running. queued mode is the right call for text-to-speech announcements — without it, two overlapping notifications can talk over each other on the same speaker. parallel mode fits per-event notifications, where you genuinely want simultaneous instances (three windows opening at once should send three separate alerts, not one at a time).

A separate and easy-to-miss failure mode: automations containing long wait_for_trigger or delay actions lose all progress if Home Assistant restarts — whether from an update, a reboot, or a crash. There's no error, no log entry pointing at it; a reminder that was mid-delay simply never fires, or a light that was mid-timer stays on indefinitely. If an automation's core job depends on a delay surviving a restart, use a Home Assistant helper (timer or input_datetime) instead of an in-automation delay/wait — helpers persist their state independently of the automation that created them.

Common Mistakes to Avoid

Leaving mode on single for anything re-triggerable. This is behind most "my light turned off while I was still in the room" complaints — the fix is almost always restart, not more conditions.

Cramming everything into one automation with trigger IDs. Trigger IDs (letting one automation respond differently depending on which of several triggers fired) are genuinely useful, but stacking ten triggers and a large choose block into a single automation makes wrong-firing silent and hard to trace. Split logic when different triggers do fundamentally different things.

Pasting AI-generated YAML without checking it. ChatGPT- or Gemini-generated automations frequently carry outdated syntax (pre-2025.12 template platform syntax was removed in the 2026.6 release), reference entities that don't exist in your setup, or contain subtle logic errors that look plausible. Validate any generated YAML in Developer Tools > Template and check the automation's trace after its first real run — the trace shows exactly which trigger fired and which conditions passed or failed, which is the fastest way to catch a wrong assumption.

Skipping the condition on a lux-aware sensor. If your motion sensor has a built-in illuminance reading (like the Aqara P1), not using it is leaving free logic on the table — you'd otherwise need a second sensor or a sun-elevation condition to get the same "only at night" behavior.

Choosing a cloud-dependent lock or bulb for anything security-related. A Z-Wave or Matter-over-Thread device exposes every state change as a local trigger with no dependency on a manufacturer's servers. A Wi-Fi-only smart lock that leans on the manufacturer's cloud will silently stop triggering Home Assistant automations if that cloud service has an outage — a distinction covered in more depth in our smart lock troubleshooting guide.

Frequently Asked Questions

Q: Should I use the UI editor or write YAML for my automations?

Both produce the identical automation, since both write to the same automations.yaml file. Use the UI for straightforward trigger → condition → action automations and for discovering available options; switch to YAML once you need nested logic, loops, or want to track changes in version control.

Q: What automation mode should I use for a motion-activated light?

Use restart. The default single mode ignores new motion events while the automation is still running its off-timer, which causes the light to turn off while someone is still in the room. restart cancels and re-starts the countdown on every new trigger.

Q: Can I customize a blueprint's trigger logic without breaking it?

Not per-instance. Blueprints only expose the inputs their author defined. To add logic outside those inputs, you either edit the blueprint file directly or use "take control" to convert your instance into a standalone automation — a one-way conversion that gives up future one-click blueprint updates.

Q: Why does my template throw an error even though the sensor has a value?

Almost always a missing type conversion or default. Entity states are strings; comparing one to a number requires | float(0) or | int(0). The (0) default also prevents errors during brief sensor unavailability, such as a Zigbee mesh hiccup.

Q: Do my automations still work if my internet goes down?

Yes, as long as every device and integration involved is local — Zigbee, Z-Wave, and Matter-over-Thread devices communicate with Home Assistant on your own network. Automations built entirely around Wi-Fi/cloud-dependent devices lose that guarantee, since the automation depends on the manufacturer's servers staying reachable.

Q: Why did my reminder automation never fire after a Home Assistant update?

Long delay or wait_for_trigger actions lose all progress on a restart, and updates restart Home Assistant. If the timing needs to survive a restart, use a timer or input_datetime helper instead of an in-automation delay — helpers keep their state independently.

Conclusion

The trigger → condition → action model doesn't get more complicated as your setup grows — what changes is which settings you now know to check. Automation mode decides whether re-triggers get dropped, queued, or run in parallel; templates need explicit type conversion and defaults; blueprints trade flexibility for one-click maintenance; and long delays don't survive a restart unless you move that state into a helper.

Applied to real hardware — an Aqara P1's built-in lux sensor removing the need for a second device, a metering Zigbee plug turning power draw into a notification trigger, a Z-Wave lock exposing every event as a distinct trigger — the model stops being an abstract diagram and becomes the shortest path from "I want this to happen automatically" to a working automation.

Where to go next: if you're still choosing a coordinator, start with our Zigbee coordinator and dongle guide. For the devices used as examples above, see our dedicated guides on Zigbee and Z-Wave motion sensors, door and window sensors, and Zigbee smart plugs. And if a device isn't triggering reliably, our motion sensor troubleshooting guide covers the mesh and pairing issues behind most "why isn't this firing" reports.

Share:

Article Topics

#home assistant automations#home assistant blueprints#home assistant templates

You might also like