Crear notificaciones universales en Home Assistant

Aprende a crear notificaciones universales en Home Assistant, para controlar todos tus dispositivos con el mínimo esfuerzo.

¿Qué son las ‘notificaciones universales’?

Tanto si utilizamos las notificaciones de telegram como las notificaciones a través de la aplicación de Home Assistant, frecuentemente creamos automatizaciones para que HA nos avise cuando sucede algo con alguno de nuestros dispositivos. Por ejemplo:

  • Cuando alguno de nuestros dispositivos se queda sin batería.
  • Cuando alguna de nuestras luces se ha quedado encendida.
  • Cuando alguno de nuestros sensores de movimiento se ha activado.
  • Cuando alguno de los sensores de puertas y ventanas abiertas se activa.

Esto es, sin duda, de gran utilidad. Sin embargo, cuando tenemos un listado extenso de dispositivos puede ser un poco tedioso programar cada una de estas notificaciones.

En este contexto, crear notificaciones universales en Home Assistant sirve para que a través de una única automatización podamos controlar todos los dispositivos que tenemos, sin necesidad de añadirlos uno a uno. Además, los que vayamos incluyendo en el futuro se incorporarán de forma automática.

¿Cómo crear una notificación universal?

En este apartado te voy a explicar de forma detallada cómo crear notificaciones universales en Home Assistant para que puedas adaptarlas a tus necesidades y dispositivos, y sobre todo para que no se te escape nada.

Para ilustrar el ejemplo vamos a crear una notificación universal que nos avise cuando algún dispositivo se esté quedando sin batería. Si quieres saltarte la “clase teórica” y copiar directamente el resultado, empieza leyendo por el paso 7.

Notificaciones

Creación del sensor

El ‘truco’ para crear notificaciones universales en Home Assistant es crear un sensor definiendo un buen ‘template‘. Este template va a hacer un barrido de todas las entidades que tenemos de un tipo determinado (por ejemplo, “baterías”). De esta forma no será necesario buscar uno a uno, ni añadirlos en el futuro.

Para ello sigue estos pasos:

  1. Accede a Herramientas para desarrolladores > Plantillas. Desde aquí vamos a poder probar nuestro ‘template’ para ver si funciona como esperamos.
  2. Empieza pegando el siguiente código en el apartado de la izquierda.
    • La primera parte del código crea una variable (llamada ‘battery’) y le asigna un valor. En este caso busca entre el nombre de todas las entidades y selecciona aquellas que contienen la palabra ‘battery’. Luego escoge como atributo el nombre de la entidad (‘entity_id’) y la lista.
    • La segunda parte del código (‘{{ battery }}’) imprime el valor de la variable ‘battery’.
{% set battery = states
  |selectattr('entity_id', 'contains', 'battery')
  |map(attribute='entity_id')
  |list
%}

{{ battery }}
  1. Como resultado del código anterior, a la derecha de la pantalla te aparecerá un listado con todas las entidades que cumplen el requisito definido. Probablemente encuentres que te sobra información. Por ejemplo, entidades que proporcionan información relacionada, pero que no es exactamente lo que estás buscando (como el estado de la batería o el tiempo restante). Para quitar esta información que no nos interesa vamos a utilizar el filtro ‘rejectattr’ que en vez de añadir entidades, las excluye. Por ejemplo, en mi caso voy a enriquecer el código de la siguiente forma:
  2. Por un lado, la idea es la misma que en el apartado anterior, pero incluyendo las palabras que identifican las entidades que sobran.
  3. Por otro, voy a sacar del conjunto a las entidades que reportan un estado de “unknown” o “unavailable”, ya que algunos dispositivos sólo muestran el nivel de batería cuando están encendidos.
{% set battery = states
  |selectattr('entity_id', 'contains', 'battery')
  |rejectattr('entity_id', 'contains', 'state')
  |rejectattr('entity_id', 'contains', 'time')
  |rejectattr('entity_id', 'contains', 'remaining')
  |rejectattr('entity_id', 'contains', 'status')
  |rejectattr('entity_id', 'contains', 'browser')
  |rejectattr('state', 'contains', 'unknown')
  |rejectattr('state', 'contains', 'unavailable')
  |map(attribute='entity_id')
  |list
%}

{{ battery }}
  1. En mi caso de esta forma ya he conseguido quitar todas las entidades que sobraban. Pero espera, ¿no faltan algunos sensores? A veces no es suficiente con un sólo criterio de búsqueda. Por ejemplo, yo quiero incorporar además de las entidades que tienen ‘battery’ en el nombre, aquellas que tienen la palabra ‘bateria’ ya que algunos dispositivos lo muestran en español.
    • Para ello primero voy a repetir la operación anterior para crear un nuevo listado y limpiarlo de las entidades que no necesito.
    • Después uniré ambas variables en una sola que reuna todas las entidades que quiero considerar.
    • Puedes repetir este proceso tantas veces como necesites.
{% set battery = states
  |selectattr('entity_id', 'contains', 'battery')
  |rejectattr('entity_id', 'contains', 'state')
  |rejectattr('entity_id', 'contains', 'time')
  |rejectattr('entity_id', 'contains', 'remaining')
  |rejectattr('entity_id', 'contains', 'status')
  |rejectattr('entity_id', 'contains', 'browser')
  |rejectattr('state', 'contains', 'unknown')
  |rejectattr('state', 'contains', 'unavailable')
  |map(attribute='entity_id')
  |list
%}
{% set bateria = states
  |selectattr('entity_id', 'contains', 'bateria')
  |rejectattr('state', 'contains', 'unknown')
  |rejectattr('state', 'contains', 'unavailable')
  |map(attribute='entity_id')
  |list
%}

{% set battery_sensors = battery + bateria %}
{{ battery_sensors }}
  1. Ahora sí, ya tengo un listado automático de todos los sensores que quiero controlar. Ya sólo el falta aplicar un filtro más que seleccione sobre este conjunto, únicamente aquellas que quiero que disparen la notificación. En mi caso van a ser aquellos sensores que indiquen un 10% de batería o menos (es decir, que el atributo ‘state’ sea ‘less than’ 10).
{% set battery = states
  |selectattr('entity_id', 'contains', 'battery')
  |rejectattr('entity_id', 'contains', 'state')
  |rejectattr('entity_id', 'contains', 'time')
  |rejectattr('entity_id', 'contains', 'remaining')
  |rejectattr('entity_id', 'contains', 'status')
  |rejectattr('entity_id', 'contains', 'browser')
  |rejectattr('state', 'contains', 'unknown')
  |rejectattr('state', 'contains', 'unavailable')
  |selectattr('state', 'lt', '10')
  |map(attribute='entity_id')
  |list
%}
{% set bateria = states
  |selectattr('entity_id', 'contains', 'bateria')
  |rejectattr('state', 'contains', 'unknown')
  |rejectattr('state', 'contains', 'unavailable')
  |selectattr('state', 'lt', '10')
  |map(attribute='entity_id')
  |list
%}

{% set battery_sensors = battery + bateria %}
{{ battery_sensors }}
  1. Con este paso lo acabamos de transformar en un sensor que informa de todos los sensores de batería que indican un nivel del 10% o inferior. El último paso, para dejarlo más bonito, es cambiar la forma en la que nos imprime el valor del sensor. En lugar de mostrar la entidad del sensor, vamos a pedirle que nos muestre el “Friendly name” que es más intuitivo, y el porcentaje de batería entre paréntesis. Además vamos a quitar los prefijos de “Battery level” y “Batería” porque ya sabemos que este sensor se refiere a ello. Para ello vamos a sustituir la última línea (‘{{ battery_sensors }}’), por el siguiente código:
{% for device in battery_sensors %}
  {% set device_name = state_attr(device,'friendly_name')
  |replace ('Battery level','')
  |replace ('Batería','')
  %}
  {% set device_battery = states(device) %}
  {{ device_name }}({{ device_battery }}%)
{% endfor %}
  1. Una vez conseguido el resultado sólo queda abrir el fichero ‘sensors.yaml’ y pegar el siguiente código para crear el sensor.
- platform: template
  sensors:
    bateria_baja:
      friendly_name: "Batería baja"
      value_template: >
        {% set battery = states
          |selectattr('entity_id', 'contains', 'battery')
          |rejectattr('entity_id', 'contains', 'state')
          |rejectattr('entity_id', 'contains', 'time')
          |rejectattr('entity_id', 'contains', 'remaining')
          |rejectattr('entity_id', 'contains', 'status')
          |rejectattr('entity_id', 'contains', 'browser')
          |rejectattr('state', 'contains', 'unknown')
          |rejectattr('state', 'contains', 'unavailable')
          |selectattr('state', 'lt', '10')
          |map(attribute='entity_id')
          |list
        %}
        {% set bateria = states
          |selectattr('entity_id', 'contains', 'bateria')
          |rejectattr('state', 'contains', 'unknown')
          |rejectattr('state', 'contains', 'unavailable')
          |selectattr('state', 'lt', '10')
          |map(attribute='entity_id')
          |list
        %}

        {% set battery_sensors = battery + bateria %}

        {% for device in battery_sensors %}
          {% set device_name = state_attr(device,'friendly_name')
          |replace ('Battery level','')
          |replace ('Batería','')
          %}
          {% set device_battery = states(device) %}
          {{ device_name }}({{ device_battery }}%)
        {% endfor %}
      icon_template: mdi:battery-10

Después de reiniciar HA, ya puedes consultar tu nuevo sensor desde Herramientas para desarrolladores > Estados.

Creación de la automatización

Realmente ya hemos hecho prácticamente todo el trabajo. Sólo nos queda crear una nueva automatización con las siguientes premisas:

  • Desencadenante. Selecciona el tipo “Estado”, busca el sensor que acabamos de crear y deja el resto de campos vacíos. Esto hará que la automatización se active cada vez que cambie el valor del sensor (bien porque siga bajando la batería del dispositivo, o porque haya nuevos dispositivos con batería baja).
  • Condiciones. Selecciona de nuevo el tipo “Negar”. Dentro de esta añade una nueva condición, seleccionando el tipo “Estado”, buscando de nuevo el sensor creado y dejando el resto de campos vacíos. Esto lo hacemos para que no nos envíe ninguna notificación cuando el cambio producido en el sensor sea que ya no hay ningún dispositivo con batería baja.
  • Acciones. Selecciona “Llamar servicio” y busca el servicio ‘notify’ asociado al dispositivo donde quieres recibir las notificaciones. Luego personaliza los campos “Title” y “Message” para configurar la notificación que vas a recibir. Asegúrate de incluir en alguna parte del mensaje el valor del sensor creado, para que puedas identificar de que dispositivo se trata.

El código completo de la automatización del ejemplo sería el siguiente, tras ajustar el nombre de tu dispositivo y tu sensor.

alias: Notificación universal (batería baja) 🪫
description: >-
  Envía una notificación cuando algún dispositivo tiene un 10% de batería o
  menos
trigger:
  - platform: state
    entity_id:
      - sensor.bateria_baja
condition:
  - condition: not
    conditions:
      - condition: state
        entity_id: sensor.bateria_baja
        state: ""
action:
  - service: notify.mobile_app_DISPOSITIVO
    data:
      title: CUIDADO! Batería baja! 🪫
      message: |
        {{ states('sensor.bateria_baja') }}
mode: single

Como te comentaba en la introducción, puedes repetir y variar este procedimiento para crear notificaciones universales en Home Assistant de cualquier clase.


¿Dudas?¿necesitas ayuda? entra aquí
Y si te ha gustado, compártelo! 🙂
sorteo
Send this to a friend