Mastering Home Assistant Scripts: Orchestrating Complex Device Sequences

NGC 224
DIY Smart Home Creator
Introduction: Why Scripts Matter in Home Assistant
Home Assistant's automation engine is powerful, allowing triggers to initiate actions. However, sometimes you need more than a simple 'when this happens, do that'. You might need a sequence of actions with delays in between, conditional logic, or even repeated steps. This is where Home Assistant's built-in Script engine shines.
While Automations are triggered by events or state changes, Scripts are executed when called, either manually, via an Automation, or from another Script. Think of an Automation as the 'trigger' for a sequence of events, and a Script as the 'sequence' itself. By separating the sequence logic into a Script, you gain reusability and create cleaner, more manageable configurations.
This guide will walk you through the fundamentals of creating and using Scripts, integrating them into your setup, and leveraging their features to build sophisticated routines.
Anatomy of a Home Assistant Script
Scripts in Home Assistant are defined in YAML (or created via the UI, which generates YAML). The core of any script is its sequence
.
Basic Structure
alias: My First Script
sequence:
- type: turn_on
device_id: your_light_device_id
entity_id: light.your_light
domain: light
- delay: '00:00:05' # Wait for 5 seconds
- type: turn_off
device_id: your_other_light_device_id
entity_id: light.your_other_light
domain: light
mode: single
Every script has an alias
for identification. The sequence
key contains a list of actions to be executed in order. Actions can range from calling a service (like light.turn_on
) to adding delays or applying conditional logic.
The mode
key defines how the script behaves if it's called multiple times while it's already running. Common modes include:
single
(default): The script will not run again until the current execution finishes. Subsequent calls are ignored.restart
: Any running instance of the script will be cancelled, and a new instance will start from the beginning.queued
: If the script is called while running, the new call is added to a queue and will run after the current instance finishes.parallel
: Multiple instances of the script can run concurrently.
Choosing the correct mode is crucial for reliable script execution, especially for routines that might be triggered rapidly.
Key Components of a Script Sequence
The power of scripts comes from the variety of actions you can include in the sequence
:
1. Service Calls
The most common action is calling a Home Assistant service to control devices or integrate with other services. This can be done in various ways:
sequence:
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 50
- device_id: your_fan_device_id # Using the device action format
domain: fan
entity_id: fan.ceiling_fan
type: turn_off
2. Delays
Pause the execution for a specified duration. Useful for waiting for devices to respond or creating timed sequences.
sequence:
- service: switch.turn_on
target:
entity_id: switch.coffee_maker
- delay: '00:05:00' # Wait for 5 minutes
- service: script.turn_on # You can call other scripts
target:
entity_id: script.announce_coffee_ready
3. Conditions
Introduce logic into your sequence. An action block with a condition
key will only execute the actions listed below it if the condition is met. Note that conditions within sequences only affect subsequent steps, not the entire script execution.
sequence:
- condition: state
entity_id: binary_sensor.motion_detector
state: 'on'
- service: light.turn_on # Only runs if motion is detected
target:
entity_id: light.hallway
4. Conditional Branches (choose
and if/then/else
)
For more complex branching logic, similar to 'if/else if/else' statements in programming.
sequence:
- choose:
- conditions:
- condition: sun
after: sunset
sequence:
- service: light.turn_on
target:
entity_id: light.patio
- conditions:
- condition: sun
before: sunrise
sequence:
- service: light.turn_off
target:
entity_id: light.patio
default:
# Actions if none of the above conditions are met
- service: notify.mobile_app
data:
message: "Sun is out, patio lights state not changed."
The newer if/then/else
is often simpler for single conditions:
sequence:
- if:
- condition: state
entity_id: cover.garage_door
state: 'open'
then:
- service: cover.close_cover
target:
entity_id: cover.garage_door
else:
- service: notify.mobile_app
data:
message: "Garage door is already closed."
5. Repeating Actions (repeat
)
Execute a block of actions multiple times.
sequence:
- repeat:
count: 3
sequence:
- service: notify.mobile_app
data:
message: "Intruder Alert!"
- delay: '00:00:02'
Repeat can also use conditions or loops over lists.
6. Waiting for State or Trigger (wait_template
, wait_for_trigger
)
Pause execution until a specific state is reached or a trigger occurs. Useful for synchronizing actions with device states.
sequence:
- service: cover.open_cover
target:
entity_id: cover.living_room_blinds
- wait_template: "{{ is_state('cover.living_room_blinds', 'open') }}"
timeout: '00:00:30'
continue_on_timeout: false
- service: light.turn_on # Only turn on light after blinds are open
target:
entity_id: light.living_room_lamp
Setup Steps: Creating Your First Script
Using the UI (Recommended for Beginners)
- Navigate to Settings -> Automations & Scenes.
- Select the 'Scripts' tab.
- Click the '+ ADD SCRIPT' button.
- Give your script a descriptive name (this becomes the alias).
- Add 'Actions' to the sequence using the UI editor. You can choose service calls, delays, conditions, and more complex logic blocks like 'Choose' or 'If/then/else'.
- Configure the actions as needed (e.g., select device/entity, service, data).
- Set the 'Mode' for the script.
- Click 'SAVE'.
Once saved, you can test the script by clicking the 'RUN' button on its card.
Using YAML
For more complex scripts or for managing configuration in files, you can define scripts directly in YAML. By default, scripts are loaded from scripts.yaml
in your Home Assistant configuration directory.
- Open your Home Assistant configuration directory.
- Edit the
scripts.yaml
file (create it if it doesn't exist). - Define your script(s) using the YAML structure described above. Each script is a top-level entry identified by its entity ID (e.g.,
script.my_first_script
). - Save the file.
- In Home Assistant, navigate to Settings -> System -> Developer Tools -> YAML.
- Click 'Check Configuration' to ensure your YAML is valid.
- Click 'Reload Scripts' under 'YAML configuration reloading'.
# scripts.yaml
my_yaml_script:
alias: My YAML Defined Script
sequence:
- service: notify.mobile_app
data:
message: "Hello from YAML script!"
mode: single
Using packages (splitting your configuration into multiple files) is a common practice for managing scripts alongside related automations, sensors, etc.
Device Integration Tips with Scripts
Scripts excel at orchestrating multiple devices in a specific order or under certain conditions. Here are some tips:
- Sequenced Scenes: Instead of relying solely on Home Assistant's built-in scenes (which set states simultaneously), use scripts to create scenes that unfold over time, like gradually dimming lights for movie night.
- Conditional Device Control: Use
choose
orif/then/else
to control devices differently based on current conditions (e.g., turn on lights to 50% if it's daytime, 20% if it's nighttime). - Retry Logic: While not a built-in script feature, you can simulate retries using
repeat
with conditions or by calling a script multiple times from an automation with delays and state checks. - Complex Shut-down Routines: Ensure devices are turned off in a specific, safe order when leaving home or going to bed. For instance, lock the front door, wait a few seconds, then turn off all lights, wait, then turn off specific plugs.
- Staged Announcements/Notifications: Use delays to space out voice announcements or push notifications so they aren't overwhelming.
Best Practices for Managing Scripts
- Use Descriptive Aliases: Give your scripts clear, human-readable names so you understand their purpose at a glance.
- Comment Your YAML: If writing scripts in YAML, use comments (#) to explain complex logic or the purpose of specific steps.
- Keep Scripts Focused: Design scripts to perform a single, well-defined task. For more complex workflows, chain smaller scripts together.
- Utilize Variables (Templates): Pass dynamic data into your scripts using template variables, especially when calling scripts from automations. This makes scripts more reusable. For example, a notification script could take the message content as a variable.
- Choose the Right Mode: Carefully consider the
mode
. Most scripts work well withsingle
orrestart
. Usequeued
orparallel
only when necessary and understand their implications. - Test Thoroughly: Use the 'RUN' button and the Trace feature (available via the UI for both UI and YAML scripts) to follow the execution path and debug issues. The trace provides invaluable insight into which steps ran, which conditions passed/failed, and variable states.
- Organize Your YAML: If using YAML, consider splitting your scripts into multiple files or using packages for better organization.
Advanced Example: Bedtime Sequence
Let's create a script that performs several actions when called at bedtime:
bedtime_sequence:
alias: Bedtime Routine
sequence:
# Action 1: Turn off downstairs lights gradually
- service: light.turn_off
target:
area_id: downstairs
data:
transition: 10 # 10-second fade out
- delay: '00:00:10' # Wait for lights to fade
# Action 2: Ensure specific devices are off (e.g., TV, computer monitor plug)
- service: switch.turn_off
target:
entity_id:
- switch.living_room_tv_plug
- switch.office_monitor
# Action 3: Announce doors/windows left open (conditional)
- condition: state
entity_id: group.doors_windows_open # Assuming you have a group tracking these
state: 'on'
- service: tts.cloud_say # Example using Cloud TTS
data:
entity_id: media_player.google_home_speaker
message: "Warning: Some doors or windows are still open."
- delay: '00:00:05' # Brief pause after announcement
# Action 4: Lock all exterior doors
- service: lock.lock
target:
device_id: # List device IDs for smart locks
- your_front_door_lock_id
- your_back_door_lock_id
# Action 5: Set thermostat to night mode
- service: climate.set_preset_mode
target:
entity_id: climate.main_thermostat
data:
preset_mode: "Night"
# Action 6: Play white noise on bedroom speaker (optional)
- service: media_player.play_media
target:
entity_id: media_player.bedroom_speaker
data:
media_content_type: 'audio/mp4'
media_content_id: 'http://your_local_media_server/white_noise.mp4'
mode: single # Only allow one bedtime sequence at a time
This script combines service calls, delays, and a condition to create a structured and reliable bedtime routine.
Conclusion
Home Assistant Scripts are a fundamental tool for building sophisticated and reliable smart home automations. By providing a robust engine for sequential execution, conditional logic, and repetition, they allow you to orchestrate complex interactions between your devices that go far beyond simple triggers and single actions. Mastering scripts is key to unlocking the full potential of your Home Assistant system and creating truly intelligent routines that enhance your daily life.
Start by converting some of your multi-step automations into scripts, practice using different action types and modes, and leverage the tracing feature to build confidence in your configurations. Your smart home will thank you for it!

NGC 224
Author bio: DIY Smart Home Creator