Trying to create an automation which is triggered by all entites which use the ping integration

Hello everybody,
I’m trying to create an automation, which sends an notification if a device which uses the ping ICMP integration is down. Until now I have put every device explicitly in the automation. Is it possible to use a template or something like that to apply the notification-automation to every entity which is checked via icmp?

Here is my current status:

alias: Benachrichtigung Netzwerk-Störung
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.fb
    for:
      hours: 0
      minutes: 0
      seconds: 30
    from: "on"
    id: fb
  - platform: state
    entity_id:
      - binary_sensor.ubnt1
    for:
      hours: 0
      minutes: 0
      seconds: 30
    from: "on"
    id: ubnt1
  - platform: state
    entity_id:
      - binary_sensor.ubnt2
    for:
      hours: 0
      minutes: 0
      seconds: 30
    from: "on"
    id: ubnt2
  - platform: state
    entity_id:
      - binary_sensor.nextcloud
    for:
      hours: 0
      minutes: 0
      seconds: 30
    from: "on"
    id: nextcloud
  - platform: state
    entity_id:
      - binary_sensor.eq3_mqtt_esp32
    for:
      hours: 0
      minutes: 0
      seconds: 30
    from: "on"
    id: EQ3-MQTT-ESP32
condition: []
action:
  - service: notify.me
    data:
      title: "*Störung im Netzwerk*"
      message: "{{ trigger.to_state.name }} ist offline"
  - wait_template: "{{ is_state(trigger.entity_id, 'on') }}"
    continue_on_timeout: true
  - service: notify.me
    data:
      title: "*Störung im Netzwerk behoben*"
      message: "{{ trigger.to_state.name }} ist online"
mode: parallel
max: 10

I’ve also tied something like that:

trigger:
  - platform: template
    value_template: |
      {%- set ns = namespace(entities = []) %}
      {%- set entities = integration_entities('ping') %}
      {%- for entity in entities %}
         {%- if states(entity) == 'off' %}
           {%- set ns.entities = ns.entities +  [entity  + ': true']  %}
         {%- endif %}
      {%- endfor %}

      {{ ns.entities }}
    for:
      hours: 0
      minutes: 0
      seconds: 10

Do you have any suggestions for me?

Best regards!
Hoasgit

The issue with your template trigger is that doesn’t render to a boolean value. Template triggers fire when their rendered value changes from false to true… yours will never do that. The most accurate way to do what you want is to use a State trigger like in your first example, but you can condense it into a single trigger:

alias: Benachrichtigung Netzwerk-Störung
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.fb
      - binary_sensor.ubnt1
      - binary_sensor.ubnt2
      - binary_sensor.nextcloud
      - binary_sensor.eq3_mqtt_esp32
    for: "00:00:30"
    from: "on"
condition: []
action:
  - service: notify.me
    data:
      title: "*Störung im Netzwerk*"
      message: "{{ trigger.to_state.name }} ist offline"
  - wait_template: "{{ is_state(trigger.entity_id, 'on') }}"
    continue_on_timeout: true
  - service: notify.me
    data:
      title: "*Störung im Netzwerk behoben*"
      message: "{{ trigger.to_state.name }} ist online"
mode: parallel
max: 10

Ok, got that. But isn’t there a way to modify the trigger template? My hope was that there is a smarter way than putting all the entities explicit in the trigger.

My idea was to use something like that, but I don’t get it tot work :frowning:

alias: New automation
description: ""
trigger:
  - platform: template
    value_template: |-
      {%- set ns = namespace() %}
      {%- set entities = integration_entities('ping') %}
      {%- set ns.return = '' %}
      {%- for entity in entities %}
        {%- if states(entity) == 'off' %}
          {%- set ENTITY_NAME = entity.split('.')[1] %}
          {%- set LAST_CHANGED = states['binary_sensor'][ENTITY_NAME].last_changed %}
          {%- if now() > LAST_CHANGED  and now() < LAST_CHANGED  + timedelta(seconds=5) %}
            {% set ns.return = 'true' %}
          {%- endif %}
        {%- else %}
          {%- if ns.return == '' %}
            {% set ns.return = 'false'%}
          {%- endif %}
        {%- endif %}
      {%- endfor %}

      {{ns.return}}
condition: []
action:
  - wait_for_trigger:
      - platform: template
        value_template: |-
          {%- if states(trigger.entity_id) == 'off' %}
            {{ true }}
          {%- else %}
            {{ false }}
          {%- endif %}
        for:
          hours: 0
          minutes: 0
          seconds: 10
  - service: notify.me
    data:
      title: "*Störung im Netzwerk*"
      message: "{{ trigger.to_state.name }} ist offline"
  - wait_template: "{{ is_state(trigger.entity_id, 'on') }}"
    continue_on_timeout: true
  - service: notify.me
    data:
      title: "*Störung im Netzwerk behoben*"
      message: "{{ trigger.to_state.name }} ist online"
mode: parallel
max: 10

The next problem after managing the trigger will be the value of the “trigger.*” variables in the actions.
The doc says they are positioned by a template trigger, but I have no clue how that would work.

1 Like

Not really. The second-best option is to create a template sensor that counts the number of non-“on” ping entities. Set a State trigger for that sensor with a trigger-attached variable to save the state object of all ping entities as the trigger fires. Then use a template that sorts and selects by last_changed of the saved ping entities’ state objects to get the name for your message.