Automatizaciones YAML con repeat, wait_for_trigger y choose en Home Assistant

Publicado el · Última revisión:

Flujo de repeat, wait_for_trigger y choose en una automatización YAML repeat repite N veces wait_for_trigger espera un evento choose ramifica según condición
Las tres estructuras de control más útiles para lógica que la UI de Home Assistant vuelve incómoda.

En Home Assistant, la interfaz gráfica es rápida para lo simple y se vuelve pesada cuando la lógica tiene bucles o esperas. Pasarlo a YAML te deja versionar, reutilizar como script y documentar el flujo entero. Aquí tienes la sintaxis concreta de tres estructuras que cubren la mayoría de los casos: repeat, wait_for_trigger y choose.

Cuándo usar cada una

repeat: bucles con límite o con condición

La sintaxis oficial solo permite un tipo de condición a la vez. No puedes combinar count con until; si lo necesitas, anida un repeat dentro de otro o usa un script intermedio.

Repetir un número fijo de veces:

action:
  - repeat:
      count: 3
      sequence:
        - action: notify.mobile_app_mi_movil
          data:
            message: "La puerta sigue abierta"
        - delay:
            minutes: 1

Repetir mientras una condición sea cierta:

action:
  - repeat:
      while:
        - condition: state
          entity_id: binary_sensor.movimiento_salon
          state: "on"
      sequence:
        - action: script.registrar_actividad

Repetir hasta que una condición se cumpla:

action:
  - repeat:
      until:
        - condition: template
          value_template: "{{ is_state('binary_sensor.puerta_entrada', 'off') }}"
      sequence:
        - action: script.comprobar_puerta

El caso de uso más habitual es el reenvío de un aviso: en lugar de enviar una sola notificación y esperar que se vea, repites el aviso tres veces con un minuto entre medias. Sacrificas algo de batería del móvil a cambio de no perderte el aviso.

wait_for_trigger: pausar hasta que pase algo

Detiene la ejecución de la automatización hasta que se dispare el trigger que le indiques. Acepta un timeout para continuar aunque el trigger no llegue, y continue_on_timeout (por defecto true) para decidir si después del timeout sigue la secuencia o se detiene.

action:
  - wait_for_trigger:
      - trigger: state
        entity_id: binary_sensor.puerta_entrada
        to: "off"
        for:
          seconds: 10
    timeout:
      minutes: 1
    continue_on_timeout: false

Puedes esperar varios triggers a la vez; el primero que ocurra libera la espera:

action:
  - wait_for_trigger:
      - trigger: state
        entity_id: binary_sensor.puerta_entrada
        to: "off"
      - trigger: event
        event_type: MY_EVENT
    timeout:
      minutes: 5

Advertencia confirmada con el issue #19360 del frontend: si defines un timeout con valor vacío, la espera se resuelve inmediatamente, como si no hubiera espera. No lo uses como “sin timeout”; si no quieres límite, omite la clave timeout por completo.

choose: ramas if / elif / else

La estructura choose evalúa las condiciones en orden y ejecuta solo la primera que se cumpla. Si ninguna se cumple y hay default, ejecuta esa rama.

action:
  - choose:
      - conditions:
          - condition: time
            after: "06:00:00"
            before: "23:00:00"
        sequence:
          - action: light.turn_on
            target:
              entity_id: light.salon
      default:
        - action: light.turn_off
          target:
            entity_id: light.salon

Para una comparación detallada entre choose y condition template, consulta la guía anterior.

Ejemplo combinado: aviso de puerta abierta con repeat y wait_for_trigger

Automatización que detecta la puerta abierta durante 5 minutos, repite un mensaje hablado tres veces y luego espera a que se cierre, con un timeout de 10 minutos antes de parar.

alias: "Puerta abierta: aviso repetido y espera de cierre"
mode: single
trigger:
  - trigger: state
    entity_id: binary_sensor.puerta_entrada
    to: "on"
    for:
      minutes: 5
action:
  - repeat:
      count: 3
      sequence:
        - action: tts.speak
          target:
            entity_id: media_player.salon
          data:
            message: "La puerta de entrada sigue abierta"
        - delay:
            minutes: 1
  - wait_for_trigger:
      - trigger: state
        entity_id: binary_sensor.puerta_entrada
        to: "off"
    timeout:
      minutes: 10
    continue_on_timeout: false

Este patrón cubre la mayoría de alertas domésticas: no bombardea con mensajes, no se queda en un bucle infinito y la espera final garantiza que el aviso se detiene cuando la puerta se cierra o cuando el timeout se agota.

Última revisión: · Publicación inicial con sintaxis verificada contra la documentación oficial de Script syntax y los hilos citados.