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
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…
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
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:
Unfortunately this gives error.
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.
@Didgeridrew - thank your for your suggestion. For me it is too advanced although it looks flexible and short so in a way clean.
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