escenas-y-scripts-home-assistant-acciones-complejas

Escenas y scripts en Home Assistant para reutilizar acciones

  • 6 min

Las escenas y los scripts son herramientas para reutilizar estados y secuencias de acciones en Home Assistant.

A medida que nuestra instalación crece y añadimos decenas de automatizaciones, nos encontraremos con un problema clásico: la duplicación de configuración.

Supongamos que tenemos una secuencia de acciones para “Apagar la casa” (apagar todas las luces, bajar las persianas al 0%, poner el termostato a 17°C y armar la alarma).

Si queremos ejecutar esta secuencia al pulsar un botón físico junto a la puerta, al decírselo a un asistente de voz, y automáticamente a las 00:00h, acabaríamos copiando y pegando el mismo bloque de acciones en tres automatizaciones distintas.

Home Assistant nos proporciona dos herramientas fundamentales para agrupar y reutilizar lógica: las Escenas y los Scripts.

Aunque a los ojos de un usuario principiante puedan parecer lo mismo, a nivel arquitectónico tienen propósitos radicalmente distintos. Vamos a analizarlos en profundidad.

Escenas: la fotografía del estado

Una Escena en Home Assistant es, estrictamente hablando, una captura estática del estado de un grupo de entidades.

No hay lógica, no hay retardos (delays), ni hay condiciones. Es simplemente una declaración de cómo queremos que estén ciertos dispositivos en un momento dado. Cuando “activamos” (scene.turn_on) una escena, Home Assistant envía simultáneamente las órdenes necesarias a todas las entidades involucradas para que adopten ese estado exacto.

Las escenas encajan muy bien para definir ambientes lumínicos o configuraciones fijas.

Ejemplo de una escena en YAML

Si miramos el archivo scenes.yaml, veremos que su estructura es un simple diccionario (mapeo) de entity_id y sus estados deseados:

- id: "escena_noche_cine"
  name: "Noche de Cine"
  entities:
    light.luz_techo_salon:
      state: "off"
    light.tira_led_tv:
      state: "on"
      brightness: 75
      color_name: "blue"
    cover.persiana_salon:
      state: "closed"
    media_player.amplificador:
      state: "on"
      volume_level: 0.45
Copied!

En lugar de escribir este YAML a mano, la forma más eficiente de crear una escena es ajustar físicamente las luces y dispositivos de la habitación a tu gusto, ir a la interfaz de Home Assistant (Ajustes > Escenas), darle a añadir y seleccionar los dispositivos. El sistema leerá sus estados actuales y los guardará automáticamente.

Escenas dinámicas (scene.create)

Aquí viene uno de los trucos técnicos más potentes de Home Assistant. Además de las escenas predefinidas, podemos crear escenas al vuelo en la memoria RAM durante la ejecución de una automatización.

Supongamos que estamos viendo una película con las luces tenues y alguien llama al timbre de la puerta. Queremos que la luz del salón parpadee en blanco para avisarnos, y luego vuelva exactamente al estado en el que estaba.

Para lograr esto, usamos el servicio scene.create antes de alterar nada:

action:
  # 1. Hacemos una "fotografía" del estado actual y la guardamos en memoria
  - action: scene.create
    data:
      scene_id: estado_previo_salon
      snapshot_entities:
        - light.luz_techo_salon
        - light.tira_led_tv

  # 2. Ejecutamos nuestra alerta visual (parpadeo en blanco al 100%)
  - action: light.turn_on
    target:
      entity_id: light.luz_techo_salon
    data:
      color_name: "white"
      brightness_pct: 100
      flash: short
      
  # 3. Esperamos 3 segundos
  - delay: "00:00:03"
  
  # 4. Restauramos la fotografía original
  - action: scene.turn_on
    target:
      entity_id: scene.estado_previo_salon
Copied!

Scripts: secuencias lógicas y funciones

Si una Escena es una fotografía estática, un Script es una película en movimiento.

A nivel interno, un Script es exactamente igual que el bloque action de una automatización, pero extraído a una entidad independiente (script.nombre_del_script).

Los scripts soportan secuencias, retardos, bucles y condiciones, además de esperas de eventos con wait_for_trigger. Son el equivalente a las funciones en un lenguaje de programación.

Uso de variables con Jinja

Lo que hace que los scripts sean especialmente útiles es su capacidad para aceptar parámetros de entrada (variables) al ser llamados, utilizando el motor de plantillas Jinja2.

Imaginemos que queremos un script estándar para enviar notificaciones de voz a nuestros altavoces inteligentes (TTS), pero queremos que el volumen se ajuste dinámicamente, envíe el mensaje, y luego devuelva el altavoz a su volumen original.

En lugar de crear una automatización para cada mensaje, creamos un único script reutilizable (script.anuncio_voz_dinamico):

alias: "Sistema: Anuncio de Voz Dinámico"
mode: queued # Evita que dos anuncios se pisen en el mismo altavoz
fields:
  mensaje:
    description: "El texto a reproducir"
    example: "Lavadora terminada"
  entidad_altavoz:
    description: "El media_player de destino"
    example: "media_player.altavoz_cocina"
    
sequence:
  # 1. Guardamos el volumen actual en una variable de Jinja2
  - variables:
      volumen_previo: "{{ state_attr(entidad_altavoz, 'volume_level') }}"
      
  # 2. Subimos el volumen al 70% para el anuncio
  - action: media_player.volume_set
    target:
      entity_id: "{{ entidad_altavoz }}"
    data:
      volume_level: 0.7
      
  # 3. Lanzamos el motor Text-to-Speech (TTS)
  - action: tts.speak
    target:
      entity_id: tts.google_translate_es_es
    data:
      media_player_entity_id: "{{ entidad_altavoz }}"
      message: "{{ mensaje }}"
      
  # 4. Esperamos a que el altavoz termine de hablar
  - wait_template: "{{ is_state(entidad_altavoz, 'idle') }}"
    timeout: "00:00:10"
    
  # 5. Restauramos el volumen original
  - action: media_player.volume_set
    target:
      entity_id: "{{ entidad_altavoz }}"
    data:
      volume_level: "{{ volumen_previo }}"
Copied!

Ahora, desde cualquier automatización de nuestra casa, solo tenemos que invocar este script pasándole los argumentos mensaje y entidad_altavoz. Hemos encapsulado la complejidad en un solo lugar. Si mañana cambiamos el motor de voz de Google por el de Nabu Casa, solo tendremos que modificar este script, y todas las automatizaciones de la casa heredarán el cambio automáticamente.

Cuándo usar cada herramienta

Para mantener una base de código limpia en Home Assistant, la regla de diseño que debemos aplicar es la siguiente:

  1. Automatizaciones: Se encargan exclusivamente de decidir CUÁNDO ocurren las cosas (Triggers y Condiciones). Su bloque de acciones debe ser lo más corto posible.
  2. Scripts: Se encargan de decidir CÓMO ocurren los procesos dinámicos (secuencias lógicas, comprobaciones, bucles, esperas). Las automatizaciones llaman a los scripts.
  3. Escenas: Se encargan de definir QUÉ estado exacto deben tener los dispositivos estáticos. Los scripts (o automatizaciones directas) aplican las escenas.

Esta separación de responsabilidades (Separation of Concerns) es la diferencia entre un archivo de configuración caótico de miles de líneas que se rompe con cada actualización, y un sistema domótico profesional, mantenible y escalable.

Helpers: pequeños estados auxiliares

Además de escenas y scripts, Home Assistant tiene otra herramienta muy útil para mantener la lógica ordenada: los Helpers o ayudantes. Son entidades virtuales que no representan un dispositivo físico, pero nos permiten guardar información.

Por ejemplo, un input_boolean.modo_invitados puede indicar que hay visitas en casa y evitar que se apaguen todas las luces a medianoche. Un input_select.modo_casa puede alternar entre normal, cine, noche o vacaciones. Y un input_number.temperatura_confort puede guardar la consigna de calefacción preferida.

Los Helpers son estupendos para separar estado de configuración de la lógica. En lugar de codificar valores fijos en diez automatizaciones, los guardamos en una entidad editable desde la interfaz.