← Back to Blog

Practical Home Assistant Automation Patterns

By Charles

After running Home Assistant for a while, I’ve settled on a set of automation patterns that actually get used daily. Here are the ones that stuck, with full YAML examples.

Automation Architecture

All automations live in separate YAML files by category, loaded via !include_dir_merge_list:

# configuration.yaml
automation: !include_dir_merge_list automations/
automations/
  security.yaml     # Failed logins, door alerts, away mode
  presence.yaml     # Welcome home, auto away/home
  modes.yaml        # Sleep, vacation, wake-up
  lawn.yaml         # Lawn service gate control
  laundry.yaml      # Washer/dryer notifications
  reminders.yaml    # Trash day, garage door alerts

This keeps things maintainable. Each file is small enough to reason about.

Pattern 1: Mode-Based Behavior

We use an input_select for home modes (Home, Away, Sleep, Vacation). Other automations check the mode to decide what to do.

# configuration.yaml
input_select:
  home_mode:
    name: Home Mode
    options: [Home, Away, Sleep, Vacation]
    initial: Home

Sleep mode locks doors and kills lights:

- id: 'sleep_mode_activated'
  alias: Sleep Mode Activated
  triggers:
    - trigger: state
      entity_id: input_select.home_mode
      to: 'Sleep'
  actions:
    - action: light.turn_off
      target:
        entity_id: light.outside_front
    - action: lock.lock
      target:
        entity_id: all

Auto Away detects when everyone leaves:

- id: 'auto_away_mode'
  alias: Auto Away Mode
  triggers:
    - trigger: state
      entity_id: group.family
      to: 'not_home'
      for:
        minutes: 10
  conditions:
    - condition: state
      entity_id: input_select.home_mode
      state: 'Home'
  actions:
    - action: input_select.select_option
      target:
        entity_id: input_select.home_mode
      data:
        option: 'Away'

The 10-minute delay prevents false triggers from brief trips to the mailbox.

Pattern 2: Vacation Light Simulation

When we’re away for extended periods, randomly toggling lights makes the house look occupied:

- id: 'vacation_light_simulation'
  alias: Vacation Light Simulation
  triggers:
    - trigger: time_pattern
      minutes: '/30'
  conditions:
    - condition: state
      entity_id: input_select.home_mode
      state: 'Vacation'
    - condition: sun
      after: sunset
      after_offset: '-00:30:00'
    - condition: time
      before: '23:30:00'
  actions:
    - action: light.toggle
      target:
        entity_id: >
          {{ ['light.living_room', 'light.master_bedroom',
              'light.workout_room'] | random }}

A companion automation turns everything off at 11:30 PM so it looks like someone went to bed.

Pattern 3: Calendar-Driven Reminders

Home Assistant can trigger off Google Calendar events. We use this for trash day:

- id: 'trash_day_reminder'
  alias: Trash Day Reminder
  triggers:
    - trigger: calendar
      event: start
      entity_id: calendar.garbage
      offset: '-12:00:00'
  conditions:
    - condition: time
      after: '18:00:00'
  actions:
    - action: notify.family
      data:
        title: "Trash Day Tomorrow"
        message: "Don't forget to take the trash out tonight."

The offset: '-12:00:00' fires 12 hours before the event, and the time condition ensures it only triggers in the evening. Same pattern works for recycling.

Pattern 4: Safety Alerts with Timeouts

The garage door alert fires if it’s been open too long:

- id: 'garage_door_left_open'
  alias: Garage Door Left Open Alert
  triggers:
    - trigger: state
      entity_id: cover.ratgdov25_c8b3b1_door
      to: 'open'
      for:
        minutes: 15
  actions:
    - action: notify.family
      data:
        title: "Garage Door Open"
        message: "The garage door has been open for 15 minutes."
        data:
          priority: high

A second automation checks at 10 PM if it’s still open — catches the cases where it was left open all evening.

Pattern 5: Accessibility-Aware Notifications

Not everyone in the household should get the same notifications, and some people need different delivery modes. We handle this with separate notify groups:

# configuration.yaml
notify:
  - name: family
    platform: group
    services:
      - service: mobile_app_charles_phone
      - service: mobile_app_brandy_phone
  - name: landon
    platform: group
    services:
      - service: mobile_app_landons_phone

For a household member who is sensitive to sounds, we deliver notifications silently:

- action: notify.landon
  data:
    title: "Lawn Guys Are Here"
    message: "The side gate just opened."
    data:
      push:
        sound:
          name: none
          volume: 0
      importance: low
      channel: silent

The importance: low (Android) and sound: none (iOS) ensure the notification arrives without any audio or vibration. The person can check it on their own time.

Pattern 6: Cooldown Conditions

Gate alerts can spam if someone walks in and out repeatedly. A cooldown condition prevents this:

conditions:
  - condition: template
    value_template: >
      {{ (as_timestamp(now()) -
          as_timestamp(state_attr('automation.gate_is_open_notify',
          'last_triggered') or 0)) > 300 }}

This checks that at least 5 minutes (300 seconds) have passed since the last trigger.

What Didn’t Work

  • Complex templates in automation actions — Keep actions simple. Move complex logic to scripts.
  • Too many notifications — We started with alerts for everything. Now we only notify for things that require action.
  • Cloud-dependent automations — Anything that relies on internet access fails during outages. Local-first is better.

The Result

27 automations across 7 files, covering security, presence, modes, lawn service, laundry, reminders, and accessibility. Everything runs locally with no cloud dependencies. The dashboard shows all automations as toggles so anyone can disable something that’s annoying.

The key lesson: start with what annoys you. If you’re constantly forgetting trash day or leaving the garage open, automate that first. The fancy stuff can wait.