Saltar al contenido

Aprende a leer YAML sin memorizarlo

06/04/2023
Aprende a leer YAML sin memorizarlo

Este artículo puede contener enlaces de afiliado. Si compras desde estos enlaces, el precio para ti es el mismo y la tienda me paga una pequeña comisión que ayuda a mantener Tecnoyfoto.

← Capítulo 1 · Índice del curso

Cuando una configuración YAML falla, la tentación consiste en mover espacios hasta que Home Assistant deja de mostrar el error. A veces funciona, pero no has aprendido qué estaba mal ni sabes si el bloque conserva el significado original. La siguiente modificación vuelve a convertirse en una prueba a ciegas.

La alternativa no es memorizar docenas de reglas. Consiste en aprender a reconstruir la estructura que representan los espacios, los guiones y los dos puntos. Cuando puedas mirar un bloque y responder «esto es una lista de acciones», «estas dos líneas pertenecen a target» o «este valor es texto, no un booleano», una gran parte de YAML dejará de parecer misteriosa.

En este capítulo todavía no estudiaremos cómo funciona cada tipo de desencadenante o condición de Home Assistant. Nuestro objetivo es anterior y más importante: aprender a leer la forma del documento. Utilizaremos fragmentos de automatizaciones reales porque son el tipo de YAML que encontrarás durante el curso, pero nos concentraremos en cómo están construidos.

OFERTAS · TIENDA OFICIAL

Descuentos en domótica SONOFF

Interruptores WiFi, relés, sensores, tiras LED y más. Las promociones cambian con frecuencia en la tienda oficial.

Cupón: TECNOYFOTO (10% de descuento al pagar)

Ver ofertas oficiales Enlace de afiliado · Tienda Sonoff

Una línea sencilla: clave y valor

La unidad más fácil de reconocer es una pareja formada por una clave y un valor:

alias: "Luz al abrir la puerta"

La clave es alias. El valor es Luz al abrir la puerta. Los dos puntos separan ambas partes y el espacio posterior inicia el valor.

La clave funciona como una etiqueta que indica qué información se está proporcionando. El valor contiene esa información. YAML sabe que existe una relación entre ambas partes, pero no sabe para qué sirve alias. Es Home Assistant quien interpreta esa clave como el nombre descriptivo de una automatización.

Podemos añadir más parejas al mismo nivel:

alias: "Luz al abrir la puerta"
description: "Enciende la luz del salón cuando se abre la puerta"
mode: restart

Las tres claves empiezan exactamente en la misma columna. Eso nos permite reconocerlas como hermanas: ninguna está contenida dentro de otra.

Una clave puede no tener el valor en la misma línea

Observa ahora este fragmento:

target:
  entity_id: light.course_living_room

Después de target: no aparece un valor sencillo. La línea siguiente está desplazada dos espacios y contiene la información que pertenece a target. En lugar de guardar una sola palabra, target contiene una estructura interior.

Esta es una idea fundamental: una clave terminada en dos puntos puede abrir un bloque. Para saber dónde termina, debes observar la indentación de las líneas siguientes.

La indentación representa pertenencia

En un texto normal utilizamos márgenes y párrafos para facilitar la lectura. En YAML, los espacios iniciales no son decoración. Expresan qué datos están dentro de otros.

actions:
  - action: light.turn_on
    target:
      entity_id: light.course_living_room

Podemos leer la jerarquía de fuera hacia dentro:

  1. actions está en el nivel principal.
  2. action y target forman parte de un elemento situado dentro de actions.
  3. entity_id está dentro de target.

Si movemos entity_id hacia la izquierda, deja de pertenecer a target, aunque las palabras sean idénticas:

actions:
  - action: light.turn_on
    target:
    entity_id: light.course_living_room

Este segundo fragmento puede llegar a ser YAML sintácticamente válido: target queda sin contenido y entity_id pasa a estar al mismo nivel que target. Sin embargo, ya no describe la estructura que la acción de Home Assistant espera. Es un buen ejemplo de por qué un validador de YAML no puede detectar por sí solo todos los errores de Home Assistant.

Utilizaremos dos espacios por nivel

Home Assistant sigue la convención de indentar dos espacios cada vez que entramos en un nivel:

nivel 0: sin espacios
nivel 1: dos espacios
nivel 2: cuatro espacios
nivel 3: seis espacios

YAML puede admitir otras cantidades si se utilizan de manera coherente, pero mezclar estilos dificulta la lectura y aumenta los errores. Durante todo el curso utilizaremos dos espacios.

Los tabuladores no sustituyen a los espacios

Una tabulación puede parecer visualmente equivalente a varios espacios, pero YAML no la admite para indentar bloques. Este detalle es especialmente engañoso porque algunos editores muestran ambas cosas de forma casi idéntica.

Si Home Assistant informa de un mensaje parecido a found character '\t' that cannot start any token, no necesitas reorganizar toda la automatización. Debes localizar la tabulación indicada y sustituirla por espacios. Un editor que muestre caracteres invisibles ayuda a distinguirlos.

Mapas: varias propiedades agrupadas

Un mapa —también llamado diccionario— reúne parejas de claves y valores. El siguiente target es un mapa con dos propiedades:

target:
  area_id: living_room
  entity_id: light.course_living_room

area_id y entity_id están alineados. Ambos pertenecen a target y ninguno contiene al otro.

Podemos imaginar su estructura sin escribir YAML:

target
├── area_id → living_room
└── entity_id → light.course_living_room

No es necesario dibujar este árbol cada vez. Lo importante es aprender a verlo mentalmente. Cuando una línea vuelve hacia la izquierda, se ha cerrado el bloque interior y hemos regresado a un nivel anterior.

Las claves no se deben repetir dentro del mismo mapa

Este ejemplo intenta definir dos veces entity_id en el mismo mapa:

target:
  entity_id: light.course_living_room
  entity_id: light.kitchen

No representa dos objetivos independientes. Son dos valores para una misma clave y el resultado puede ser que uno sustituya al otro. Si quieres proporcionar varias entidades, necesitas una lista como la que veremos a continuación.

Listas: cuando hay más de un elemento

Una lista contiene varios elementos ordenados. Cada elemento comienza con un guion:

entity_id:
  - light.course_living_room
  - light.kitchen

Aquí entity_id no contiene un único texto, sino una lista de dos identificadores. Ambos guiones están alineados porque ambos valores pertenecen al mismo nivel.

Las listas también pueden contener mapas completos. Esto ocurre constantemente en automatizaciones:

actions:
  - action: light.turn_on
    target:
      entity_id: light.course_living_room

  - action: switch.turn_on
    target:
      entity_id: switch.course_fan

actions contiene dos elementos. Cada guion inicia una acción diferente. Dentro de cada elemento aparecen las claves action y target.

El primer guion no significa «acción» ni pertenece a Home Assistant. Significa «nuevo elemento de una lista» y forma parte de YAML. Home Assistant, por su parte, define qué propiedades debe contener cada elemento de la lista de acciones.

Esta separación vuelve a ser útil:

  • El guion y la indentación construyen la lista YAML.
  • Las claves action, target y entity_id forman parte del esquema que Home Assistant espera.
  • Valores como light.turn_on o switch.course_fan identifican operaciones y entidades de Home Assistant.

Listas y mapas se combinan continuamente

Una automatización no es «una lista» o «un mapa» de forma exclusiva. Contiene ambas estructuras anidadas.

alias: "Entrada iluminada"
description: "Enciende la luz cuando se abre la puerta y hay alguien en casa"
triggers:
  - trigger: state
    entity_id: binary_sensor.course_front_door
    from: "off"
    to: "on"
conditions:
  - condition: state
    entity_id: binary_sensor.course_someone_home
    state: "on"
actions:
  - action: light.turn_on
    target:
      entity_id: light.course_living_room
  - action: switch.turn_on
    target:
      entity_id: switch.course_fan
mode: restart

Todavía no necesitamos estudiar el comportamiento de cada sección. Podemos describir su forma:

  • El documento principal es un mapa con las claves alias, description, triggers, conditions, actions y mode.
  • triggers contiene una lista. Esta lista tiene un elemento, formado por un mapa con cuatro propiedades.
  • conditions también contiene una lista con un mapa.
  • actions contiene una lista de dos mapas.
  • Cada acción contiene un target, y cada target contiene un entity_id.

Si puedes realizar esta lectura, ya sabes mucho más que alguien que solo reconoce palabras sueltas. Incluso sin conocer una condición concreta, podrás localizar dónde empieza, qué propiedades posee y dónde termina.

Valores sencillos: texto, números, booleanos y nulos

Hasta ahora hemos prestado más atención a la estructura que al tipo de los valores. YAML distingue varios tipos básicos, y Home Assistant puede esperar uno diferente según la opción.

Texto

Estos valores son cadenas de texto:

alias: "Entrada iluminada"
entity_id: light.course_living_room
to: "on"

Un identificador de entidad contiene un punto, pero sigue siendo texto. El estado "on" también es texto, no una orden para encender nada.

Números

above: 25
brightness_pct: 60

25 y 60 se interpretan como números. No llevan comillas porque queremos conservar ese tipo numérico.

Booleanos

Un booleano solo puede representar verdadero o falso:

enabled: true
continue_on_error: false

Aquí true y false no son estados de entidades. Son valores lógicos que activan o desactivan una opción.

Por qué escribimos "on" y "off" entre comillas

El analizador YAML utilizado por Home Assistant puede interpretar palabras como on, off, yes o no como booleanos. Pero el estado interno de una luz o un sensor binario se compara normalmente como texto.

to: "on"

Las comillas obligan a conservar on como cadena. Sin ellas, el valor podría convertirse en true, que no es el estado textual que la configuración espera. Este es uno de esos errores pequeños que parecen caprichosos hasta que distingues el tipo del valor.

Valor nulo y cadena vacía

Estas dos líneas no significan exactamente lo mismo:

description:
description: ""

La primera deja la clave sin valor, lo que YAML interpreta como un valor nulo. La segunda contiene una cadena de texto vacía. Home Assistant puede aceptar ambas formas en algunos lugares y exigir una concreta en otros. No debemos intercambiarlas sin saber qué espera la opción.

Cuándo utilizar comillas

Muchas cadenas sencillas funcionan sin comillas:

alias: Entrada iluminada

Es YAML válido, pero la guía de estilo de Home Assistant prefiere comillas dobles para el texto normal. Durante el curso seguiremos esa norma en alias, títulos, mensajes, descripciones y otros textos. Dejaremos sin comillas identificadores de entidad, nombres de acciones, tipos de trigger o condición, clases de dispositivo y valores cerrados como mode, porque la propia guía los exceptúa.

Además de dar consistencia, las comillas eliminan ambigüedades cuando el texto puede confundirse con otro tipo o contiene caracteres especiales.

at: "08:00:00"
to: "on"
message: "Puerta #1 abierta: revisar entrada"

En el mensaje, el carácter # podría iniciar un comentario si no protegemos el texto. Los dos puntos seguidos de un espacio también tienen significado estructural. Citar el mensaje deja claro que todo pertenece a la cadena.

YAML admite comillas simples y dobles:

message: 'La puerta está abierta'
message: "La puerta está abierta"

Para los ejemplos básicos, cualquiera de las dos puede servir. Las dobles permiten determinadas secuencias de escape, mientras que las simples tratan el contenido de una manera más literal. No mezclaremos estilos sin motivo; elegiremos la forma que haga el valor más claro.

Comentarios: explicar sin cambiar el comportamiento

El carácter # inicia un comentario fuera de una cadena entre comillas:

# Esta automatización utiliza las entidades del laboratorio
alias: "Entrada iluminada"
actions:
  - action: light.turn_on  # Enciende la luz virtual

Home Assistant ignora el comentario. Su finalidad es explicar una decisión que no resulta evidente al leer las claves.

Un comentario útil explica el motivo:

# Reiniciamos la secuencia si vuelve a detectarse movimiento
mode: restart

Un comentario que solo repite la línea aporta poco:

# El modo es restart
mode: restart

Tampoco debemos utilizar comentarios para compensar nombres incomprensibles o dejar grandes bloques abandonados durante meses. Comentar bien no consiste en escribir más, sino en conservar el contexto que ayudará a entender una decisión futura.

Texto en varias líneas: > y |

Los mensajes y, más adelante, algunas plantillas pueden resultar demasiado largos para una sola línea. YAML ofrece dos formas habituales de escribirlos.

El símbolo > pliega las líneas y produce normalmente un párrafo continuo:

message: >
  La puerta de entrada está abierta.
  Comprueba si debe permanecer así.

El valor resultante se lee como una frase continua, con un espacio entre las líneas.

El símbolo | conserva los saltos de línea:

message: |
  Estado de la casa:
  Puerta abierta
  Luz encendida

En ambos casos, el texto debe quedar indentado dentro de message. No profundizaremos todavía en todas las variantes de los bloques multilínea. Por ahora debes reconocer que las líneas desplazadas forman un único valor de texto.

El mismo bloque puede necesitar un guion exterior según dónde se pegue

Una fuente frecuente de confusión no es el contenido de la automatización, sino el lugar donde se inserta.

La vista YAML del editor de una automatización suele mostrar directamente su mapa:

alias: "Entrada iluminada"
triggers: []
conditions: []
actions: []
mode: single

automations.yaml, en cambio, contiene una lista de automatizaciones. Cada automatización necesita un guion exterior:

- id: "course_entrada_iluminada"
  alias: "Entrada iluminada"
  triggers: []
  conditions: []
  actions: []
  mode: single

Y si se escribe directamente dentro de configuration.yaml, aparece además la clave superior automation::

automation:
  - alias: "Entrada iluminada"
    triggers: []
    conditions: []
    actions: []
    mode: single

No son tres sintaxis incompatibles. Es la misma estructura situada dentro de contextos diferentes. Antes de copiar un ejemplo, debes saber si representa una automatización aislada, un elemento de una lista o una sección completa de configuración.

Un método para leer cualquier bloque YAML

Cuando un ejemplo te resulte abrumador, no intentes comprenderlo todo simultáneamente. Recorre estas cinco preguntas:

  1. ¿Cuáles son las claves del nivel principal? Busca las líneas completamente alineadas a la izquierda del fragmento.
  2. ¿Qué claves abren un bloque? Son las que terminan en dos puntos y continúan con líneas más indentadas.
  3. ¿Dónde hay listas? Localiza los guiones y comprueba cuáles están alineados.
  4. ¿Qué propiedades pertenecen a cada elemento? Sigue la indentación hasta que una línea vuelva hacia la izquierda.
  5. ¿Qué tipo parece tener cada valor? Distingue texto, número, booleano, nulo y bloques multilínea.

Solo después debes preguntarte qué significado da Home Assistant a las claves. Separar la forma YAML del comportamiento reduce mucho la carga mental.

Dos errores que se parecen, pero no son iguales

Este fragmento tiene una indentación que rompe la estructura YAML:

triggers:
  - trigger: state
  entity_id: binary_sensor.course_front_door
    to: "on"

entity_id no está alineado con las propiedades del elemento iniciado por el guion y to entra en un nivel que no tiene un padre válido. El analizador no puede construir una estructura coherente.

Este otro fragmento sí puede analizarse como YAML, pero entity_id ha quedado fuera de target:

actions:
  - action: light.turn_on
    target:
    entity_id: light.course_living_room

En el primer caso esperamos un error de sintaxis o construcción YAML. En el segundo, el problema aparece cuando Home Assistant valida la forma de la acción. Aprender a distinguirlos nos prepara para el método de diagnóstico que desarrollaremos durante el curso.

Ejercicio: reconstruye y repara la estructura

El siguiente bloque pretende encender dos luces cuando se abre la puerta. Contiene varios problemas de indentación y un valor ambiguo:

alias: "Encender luces de entrada"
triggers:
  - trigger: state
  entity_id: binary_sensor.course_front_door
  from: off
  to: on
actions:
  - action: light.turn_on
    target:
      entity_id:
      - light.course_living_room
      - light.kitchen
mode: restart

Antes de corregirlo, responde:

  1. ¿Qué claves deberían pertenecer al elemento de triggers?
  2. ¿Qué valor de entity_id es una lista?
  3. ¿Qué guiones representan elementos de esa lista?
  4. ¿Qué valores deben conservarse como texto?
  5. ¿Cuáles son las claves del nivel principal?

Intenta corregirlo sin mirar la solución. Después compara estructuras, no solo el resultado visual.

Ver la solución explicada
alias: "Encender luces de entrada"
triggers:
  - trigger: state
    entity_id: binary_sensor.course_front_door
    from: "off"
    to: "on"
actions:
  - action: light.turn_on
    target:
      entity_id:
        - light.course_living_room
        - light.kitchen
mode: restart

alias, triggers, actions y mode son las claves principales.

triggers contiene una lista. El guion de trigger inicia su primer elemento. entity_id, from y to son propiedades del mismo mapa y, por eso, se alinean cuatro espacios desde el margen.

Los estados "off" y "on" llevan comillas para conservarse como texto.

actions contiene otra lista. Su primer elemento es un mapa con action y target. Dentro de target, entity_id contiene una lista de dos valores. Los guiones de las luces deben quedar un nivel por debajo de entity_id.

Si solo hubiéramos movido líneas hasta que el error desapareciera, podríamos haber creado un YAML válido con un significado diferente. La corrección parte primero de decidir qué elemento contiene a cuál.

Qué debes llevarte de este capítulo

Los espacios de YAML describen relaciones. Una línea más indentada pertenece al bloque anterior; una línea que vuelve hacia la izquierda cierra niveles. Los guiones crean elementos de una lista y las claves alineadas forman parte del mismo mapa.

También has visto que YAML puede contener texto, números, booleanos, valores nulos y bloques multilínea. Las comillas no son un adorno: a veces evitan que un estado como "on" se convierta en un booleano.

Todavía no hemos aprendido a diseñar una automatización. Ya podemos, sin embargo, mirar su estructura y explicar dónde se encuentra cada pieza. En el próximo capítulo añadiremos el significado que Home Assistant da a esas piezas: entidades, dominios, estados, atributos, acciones, objetivos y datos.

Continúa leyendo

Siguiente guía relacionada · 13 min de lectura

Tu primera automatización en YAML, línea por línea

← Capítulo 3 · Índice del curso Ya sabemos leer la estructura de un documento YAML y comprobar qué estados y acciones utiliza Home…

Continuar con este artículo