Multiple time condition in automation trigger - clean solution?

With several ESPs around the house I came to the need to make an automation which will notify me if any of the ESP boards are not available. I have done it with simple code:

automation:
  - alias: Esp not connected to WiFi
    id: warning_esp_01
    mode: single
    trigger:
    - platform: state 
      entity_id: 
      - sensor.esp01_wifi
      - sensor.esp02_wifi
      - sensor.esp03_wifi
      - sensor.esp04_wifi
      - sensor.esp05_wifi
      - sensor.esp06_wifi
      to: 'unavailable'
      for: 00:30:00
    condition: []
    action:
      - service: notify.mobile_app_XXXX
        data:
          message: "one of ESPs is not connected to WiFi!"

This works fine.
Then I wan to remind myself more often that this situation continues as I can overlook one message or forget to take an action/check/fix.

So, I was wondering if this condition will work (just the trigger section):

      for:
      - 00:30:00
      - 01:00:00
      - 02:00:00

As I want to get notification after 30 minutes, 1 hour and 2 hours of the unavailability.
However it seems this does not work. My test ESP disconnected for more then one hour did not trigger any message :frowning:
I know I can make a time_pattern to check the WiFi connectivity at certain times, but ideally I would like to make the above working. Also that it looks very nice and clean… :slight_smile:
Any help to make it will be appreciated.

I think you would need to make binary template sensors that work the same way as the triggers for this automation, and then use the alert integration which allows you to configure how often to alert.

Example:

template:
  - trigger:
      - platform: state
        to: 'unavailable'
        for: 00:30:00
        entity_id:
          - sensor.esp01_wifi
          - sensor.esp02_wifi
          - sensor.esp03_wifi
          - sensor.esp04_wifi
          - sensor.esp05_wifi
          - sensor.esp06_wifi
    binary_sensor:
      - name: ESP Fault
        state: "{{ on if 'unavailable' in [states('sensor.esp01_wifi'),states('sensor.esp02_wifi'),states('sensor.esp03_wifi'),states('sensor.esp04_wifi'),states('sensor.esp05_wifi'),states('sensor.esp06_wifi')] else 'off' }}"

And then the Alert integration - I’ll just show you what I have for my boiler:

boiler_fault:
  name: Boiler Fault
  done_message: "The Boiler is working normally"
  message: "*Boiler Fault* The boiler is not working!"
  entity_id: binary_sensor.boiler_fault
  state: 'on'
  repeat: 30
  can_acknowledge: true
  notifiers:
    - tg_house_group
1 Like

Your trigger can be templated, I don’t know if it meets the “nice and clean” criteria…

alias: Esp not connected to WiFi
id: warning_esp_01
mode: single
trigger:
  - platform: template
    value_template: >-
      {% set ns = namespace(times = []) %} 
      {% set x = expand('sensor.esp01_wifi', 'sensor.esp02_wifi', 'sensor.esp03_wifi', 'sensor.esp04_wifi', 'sensor.esp05_wifi', 'sensor.esp06_wifi') |
      selectattr('state', 'eq', 'unavailable') | map(attribute = 'last_changed') | list %} 
      {% for y in x %}
        {% set b = (now() - as_local(y)).seconds // 60 in [30, 60, 120] %}
        {% set ns.times = ns.times + ['{}'.format(b)]%}
      {% endfor %}
      {{ 'True' in ns.times }}
condition: []
action:
  - service: notify.mobile_app_XXXX
    data:
      message: "One of ESPs is not connected to WiFi!"

You could clean that up a little by putting all the sensors in a group and then just expand the group instead of the list of sensors.

Thank you. This was a good suggestion to go to ALERT functions.
I am exploring this path and it seems it can be triggered not only by boolean entities. Here is what works:

alert:
  esp_offline:
    name: Esp99 offline
    entity_id: sensor.esp99_wifi
    state: 'unavailable'
    repeat: 30
    skip_first: true
    notifiers:
      - mobile_app_xxxxx

I was hoping that similar to other triggers I can put several entities here, like that:

alert:
  esp_offline:
    name: Esp99 offline
    entity_id:
    - sensor.esp01_wifi
    - sensor.esp02_wifi
    - sensor.esp99_wifi
    state: 'unavailable'

Unfortunately this gives error. :frowning:
As ALERT functionality seems to me the best for my case and it also looks very clean (I can manage different delays times easily) at this point I think I will go for creating alert for each esp separate. This I do not like much but maybe one day it will be possible to add several entities into triggering criteria.
Unless there will be other good comments and suggestions here. :slight_smile:

@Didgeridrew - thank your for your suggestion. For me it is too advanced although it looks flexible and short so in a way clean. :slight_smile:
I will keep the idea for future also as a good education material (on templating) and for now will try other path. Thanks.

Personally, for something like this I would just use multiple triggers, because it makes it easier to extract trigger data to put in the notification message… For example the message could contain the name of the device and how long it has been unavailable:

alias: Esp not connected to WiFi
description: ''
trigger:
  - platform: state
    entity_id: >-
      sensor.esp01_wifi, sensor.esp02_wifi, sensor.esp03_wifi, sensor.esp04_wifi, sensor.esp05_wifi, sensor.esp06_wifi
    to: unavailable
    for: '00:30:00'
  - platform: state
    entity_id: >-
      sensor.esp01_wifi, sensor.esp02_wifi, sensor.esp03_wifi, sensor.esp04_wifi, sensor.esp05_wifi, sensor.esp06_wifi
    to: unavailable
    for: '01:00:00'
  - platform: state
    entity_id: >-
      sensor.esp01_wifi, sensor.esp02_wifi, sensor.esp03_wifi, sensor.esp04_wifi, sensor.esp05_wifi, sensor.esp06_wifi
    to: unavailable
    for: '02:00:00'
condition: []
action:
  - service: notify.mobile_app_XXXX
    data:
      message: >-
        ESP device {{trigger.to_state.name}} has been offline for {{ (
        trigger.for.total_seconds() / 60 )|round(0)}} minutes.
mode: parallel
max: 6

I agree that this is the simplest approach with the benefit of reporting the name of the unavailable entity.

FWIW, to simplify maintenance, you can employ YAML anchors and aliases. It will allow you to define the list of entities in the first State Trigger and use it in the other two State Triggers.

trigger:
  - platform: state
    for: '00:30:00'
    <<: &entities
      to: unavailable
      entity_id:
        - sensor.esp01_wifi
        - sensor.esp02_wifi
        - sensor.esp03_wifi
        - sensor.esp04_wifi
        - sensor.esp05_wifi
        - sensor.esp06_wifi
  - platform: state
    for: '01:00:00'
    <<: *entities
  - platform: state
    for: '02:00:00'
    <<: *entities
1 Like