Mastering Home Assistant's Scripts and Sequences for Advanced Automation Routines

Represent Mastering Home Assistant's Scripts and Sequences for Advanced Automation Routines article
4m read

Home Assistant excels at making your smart home intelligent, but beyond simple "if X then Y" automations lies a powerful feature: Scripts. While automations react to triggers, scripts define reusable sequences of actions, enabling you to orchestrate complex routines, introduce delays, implement conditional logic, and build highly sophisticated smart home behaviors that would be cumbersome, if not impossible, with standalone automations.

Understanding the Role of Scripts

Think of automations as the "events" and scripts as the "functions" or "subroutines" in programming. An automation detects a trigger (e.g., motion detected, time of day) and then calls a script (or a series of actions). The script itself contains the detailed, ordered steps that need to be executed. This separation of concerns offers significant benefits:

  • Reusability: Define a complex routine once and call it from multiple automations, dashboards, or even other scripts.
  • Modularity: Break down large automation flows into smaller, manageable, and testable script components.
  • Complex Logic: Implement intricate sequences with delays, conditional branches, loops, and dynamic variables.
  • Manual Execution: Run a script manually from the Home Assistant UI, providing quick control over predefined routines.

Key Scripting Features and Syntax

Scripts are defined under the script: domain in your Home Assistant configuration, typically in configuration.yaml or an included YAML file (e.g., !include scripts.yaml or !include_dir_list scripts/). Each script is given a unique ID.

Basic Structure:

# scripts.yaml
my_first_script:
  alias: "My First Script"
  sequence:
    - service: light.turn_on
      target:
        entity_id: light.living_room_lights
    - delay: "00:00:05" # Wait 5 seconds
    - service: notify.mobile_app
      data:
        message: "Lights are on!"

The core of any script is its sequence block, which is a list of actions executed sequentially. Home Assistant offers a rich set of actions:

  • service: Call any Home Assistant service (e.g., light.turn_on, media_player.play_media).
  • delay: Pause script execution for a specified duration (e.g., "00:01:30" for 1 minute 30 seconds, or seconds: 10).
  • wait_template: Halt execution until a Jinja2 template evaluates to true. Essential for waiting for device states.
    - wait_template: "{{ is_state('light.living_room_lights', 'on') }}"
              timeout: "00:00:10" # Optional: Timeout after 10 seconds
              continue_on_timeout: true # Optional: Continue even if timeout occurs
            
  • wait_for_trigger: Pause until a specific event or trigger occurs.
    - wait_for_trigger:
                - platform: state
                  entity_id: binary_sensor.front_door
                  to: 'off'
              timeout: "00:05:00"
            
  • condition: Introduce conditional logic. If the condition isn't met, the remaining actions in the sequence are skipped.
    - condition: state
              entity_id: binary_sensor.motion_sensor_hallway
              state: 'on'
            - service: light.turn_on
              target:
                entity_id: light.hallway_light
            
  • choose: Implement if/elif/else branching logic, allowing different sequences based on various conditions.
    - choose:
                - conditions: "{{ is_state('sun.sun', 'below_horizon') }}"
                  sequence:
                    - service: light.turn_on
                      target:
                        entity_id: light.porch_light
                - conditions: "{{ is_state('sun.sun', 'above_horizon') }}"
                  sequence:
                    - service: light.turn_off
                      target:
                        entity_id: light.porch_light
              default: # Optional: Actions if no conditions match
                - service: notify.persistent_notification
                  data:
                    message: "Sun state unclear."
            
  • repeat: Loop through a sequence of actions a specific number of times, until a condition is met, or while a condition is true.
    - repeat:
                count: 3 # Repeat 3 times
                sequence:
                  - service: media_player.volume_up
                    target:
                      entity_id: media_player.living_room_tv
                  - delay: "00:00:01"
            
  • variables: Define temporary variables within a script's execution, useful for passing dynamic data.
    my_dynamic_script:
              sequence:
                - variables:
                    target_light: "{{ light_entity_id_from_automation }}" # Passed from caller
                - service: light.turn_on
                  target:
                    entity_id: "{{ target_light }}"
            

Managing Script Execution Modes

An often-overlooked but crucial aspect of scripts is their mode. This defines how Home Assistant handles multiple simultaneous calls to the same script:

  • single (default): Only one instance of the script can run at a time. New calls are ignored if one is already running.
  • restart: If the script is called while already running, the current instance is stopped, and a new one starts.
  • parallel: Multiple instances of the script can run concurrently. Useful for independent actions.
  • queued: New calls are added to a queue and executed one after another once the previous instance finishes.

Choosing the correct mode is vital for preventing unexpected behavior, especially with time-sensitive or state-dependent routines.

Best Practices for Reliable Scripting

  1. Modularity: Break down complex routines into smaller, single-purpose scripts. This enhances readability, testing, and reusability.
  2. Use wait_template with timeout: Never assume a device will instantly respond. Always add a timeout to wait_template or wait_for_trigger actions to prevent scripts from hanging indefinitely.
  3. Leverage Variables: Design scripts to accept variables (passed from the automation that calls them). This makes your scripts highly reusable and adaptable to different contexts or devices. For example, a "turn on light with color" script could take entity_id and color as variables.
  4. Error Handling with choose and default: Use the default block in a choose action to handle scenarios where none of your explicit conditions are met, preventing unintended omissions.
  5. Comment Your Code: Add comments (#) generously to explain the purpose of complex steps or logic, especially when collaborating or revisiting scripts later.
  6. Thorough Testing: Use the Home Assistant UI to manually trigger scripts and observe their behavior. Leverage the "Traces" feature (available for automations and scripts) to visually debug their execution flow step-by-step.
  7. Understand mode: Carefully consider the implications of single, restart, parallel, and queued for each script based on its purpose. For routines that should never run concurrently or need to finish before another starts, single or queued might be appropriate. For independent actions, parallel.

Example: An Advanced "Good Night" Routine

Let's build a robust "Good Night" script, triggered by a button press or time of day:

# In scripts.yaml
good_night_routine:
  alias: "Execute Good Night Routine"
  mode: single # Only one instance should run at a time
  sequence:
    - service: input_boolean.turn_on
      target:
        entity_id: input_boolean.good_night_active # Indicate routine is running

    # 1. Turn off all main lights (using a light group)
    - service: light.turn_off
      target:
        entity_id: light.all_interior_lights

    # 2. Check if doors are closed before arming alarm
    - choose:
        - conditions:
            - condition: state
              entity_id: binary_sensor.front_door_contact
              state: 'off'
            - condition: state
              entity_id: binary_sensor.back_door_contact
              state: 'off'
          sequence:
            - service: alarm_control_panel.alarm_arm_home
              target:
                entity_id: alarm_control_panel.home_alarm
            - service: notify.mobile_app
              data:
                message: "Alarm armed. All doors closed."
        default:
          - service: notify.mobile_app
            data:
              message: "Warning: Doors are open! Alarm not armed."
              title: "Home Assistant Alert"
          - stop: "Doors open, cannot arm alarm." # Stop script execution
          
    - delay: "00:00:02" # Short delay after alarm arming attempt

    # 3. Set thermostat to night mode
    - service: climate.set_preset_mode
      target:
        entity_id: climate.thermostat
      data:
        preset_mode: "sleep"

    # 4. Power off media devices, waiting for them to turn off
    - service: media_player.turn_off
      target:
        entity_id:
          - media_player.living_room_tv
          - media_player.soundbar
    - wait_template: >
        {{ is_state('media_player.living_room_tv', 'off') and
           is_state('media_player.soundbar', 'off') }}
      timeout: "00:00:20"
      continue_on_timeout: true # Continue even if devices don't report off

    # 5. Lock all smart locks
    - service: lock.lock
      target:
        entity_id:
          - lock.front_door_lock
          - lock.back_door_lock
          
    # 6. Final confirmation notification
    - service: notify.mobile_app
      data:
        message: "Good Night! Your home is secured."

    - service: input_boolean.turn_off
      target:
        entity_id: input_boolean.good_night_active # Routine finished

Conclusion

Home Assistant's scripting capabilities are a cornerstone for building truly sophisticated and reliable smart home ecosystems. By understanding and effectively utilizing sequences, delays, conditions, loops, and execution modes, you can move beyond basic automations to create dynamic, robust, and incredibly intelligent routines that precisely meet your home's needs. Dive in, experiment, and transform your smart home from reactive to proactive with the power of scripts!

Avatar picture of NGC 224
Written by:

NGC 224

Author bio: DIY Smart Home Creator

There are no comments yet
loading...