Direct answer: already true, or the next change?
In a Home Assistant script or automation sequence, both waits pause later actions—but they answer different questions.
wait_templatere-evaluates a template. If it is already true when the wait is reached, following actions continue immediately. The template is checked again when referenced entities change, and templates that usenow()are also rechecked at the start of each minute. (Home Assistant wait template)wait_for_triggerwaits for one listed trigger to fire after the wait step is reached. An already-matching current state is not enough; the trigger must react to a later change. You can list multiple triggers; the first one that fires ends the wait. (Home Assistant wait for trigger)
If a door is already open and you only need “open is true,” use a template wait. If you need “the door opens from now on,” use wait for trigger—even when the entity already looks correct.
Shared timeout behavior
Both waits share the same timeout controls:
Option | Behavior |
|---|---|
| Optional maximum wait (same duration formats as delay, including templates). Omit it to wait indefinitely. |
| Optional; default |
|
|
| Seconds left on the timeout, or |
Restart | A Home Assistant restart ends a waiting run. Neither wait persists or resumes afterward. |
wait_for_trigger also exposes wait.trigger (or none on timeout). Optional per-trigger id values let later conditions branch on wait.trigger.id; see how to branch one automation by trigger ID.
Do not confuse automation mode restart (a new run can stop a waiting run) with restarting Home Assistant as a service. Manual Run actions also does not reproduce live trigger data the way a real trigger would.
Starting on, starting off, and timeout
For a state trigger with to: "on", the starting state decides which wait fits:
Situation at the wait step |
|
|
|---|---|---|
Already | Continues immediately | Keeps waiting for a later transition into |
Currently | Waits until the template becomes true | Waits for a new change into |
Timeout, default | Later steps still run; check | Same |
Timeout, | Sequence stops | Sequence stops |
That table is the practical split between wait-for-a-state and wait-for-a-future-change.
Two minimal inert examples
These YAML fragments are illustrative only. They use placeholder entity IDs and a notification action—not door unlocks, heaters, hazardous loads, or sensor setup. Replace binary_sensor.example_door with your own binary sensor and keep the action inert while you learn the semantics.
Example A: wait for current state
sequence:
- wait_template: "{{ is_state('binary_sensor.example_door', 'on') }}"
timeout: "00:00:30"
continue_on_timeout: false
- condition: template
value_template: "{{ wait.completed }}"
- action: persistent_notification.create
data:
title: "Wait template finished"
message: "Door reported on before timeout. Replace binary_sensor.example_door."If the door is already on, this path can proceed without another event. If the timeout wins with continue_on_timeout: false, the sequence stops before the notification.
Example B: wait for the next change
sequence:
- wait_for_trigger:
- trigger: state
entity_id: binary_sensor.example_door
to: "on"
timeout: "00:00:30"
continue_on_timeout: false
- condition: template
value_template: "{{ wait.completed }}"
- action: persistent_notification.create
data:
title: "Wait for trigger finished"
message: "A new on transition arrived after this step. Replace binary_sensor.example_door."If the door is already on when this step starts, the wait still sits until a later qualifying transition or timeout. When you need alternate events, add more entries under wait_for_trigger; the wait ends when any one fires.
Safe trace checklist
When a wait ran too soon or never finished, walk the automation or script trace in this order:
- Confirm which wait you used: template waits can pass on current state; trigger waits need a post-step change.
- Read the starting state of every entity the wait references when the wait began.
- Check timeout and
continue_on_timeout. Default continue-on-timeout is true, so later actions may run even whenwait.completedis false unless you stop or guard. - Inspect
wait.completedand, for trigger waits,wait.trigger/wait.trigger.id. - Look for mode
restartor a Home Assistant restart that ended the waiting run—waiting does not survive a restart. - Do not treat manual Run actions as proof that live trigger data will match.
One decision question
Ask: Do I need the condition true right now, or a future event after this step?
- True right now, including “already true” →
wait_template, still with a timeout and await.completedguard when failure must not continue. - A future matching change, including when the entity already looks correct →
wait_for_trigger. - Fixed dead time with no condition → use a plain delay instead.
Use the official wait template and wait for trigger docs as the source of truth for field names and defaults.



