I am looking to have a kind of failsafe feature on an important plug that is running ESPHOME. This plug is use to manage an heating device for my chicken coop.
Right now it is an outside automation (in nodered) that switch the plug from OFF to ON base on a temp sensor.
My goal is to do something like this :
If the esphome API is not reachable (since 5 minutes)
Turn ON the plug for 10 minutes
Then turn OFF the plug for 10 minutes
Loop the process until the API got connected again
oh that’s maybe a good way to use for me.
I can, on the “on_boot” event, turn on the switch for an amount of time if the api is not connected.
Do you know if the “reboot process” is recurrent ?
Example :
at 8h00 the api or wifi goes disconnected
at 8h15 esphome reboot
if after the reboot, the api is still disconnected…at 8h30 I will have another reboot ? then 8h45, 9h00, etc. etc. ?
I didn’t put it online yet but I think it will do the job I need. So each 5 minutes esphome will check if the API is connected and if not, it will call my script that turn on the switch for 5 min.
So with this in place, if my main server that run (HA / NodeRed) crash and it is not accessible, I will be sure that some heating will be done in the coop.
I’m doing something similar to what you’re doing.
I think the problem with your code is that it would execute your script every 5 minutes if it stays disconnected.
The solution to this is to detect only the api.connected state changes.
This is how I’m doing it:
globals:
- id: api_connection
type: bool
restore_value: no
initial_value: 'false'
interval:
- interval: 10s
then:
- if:
condition:
# check last connection state
- lambda: 'return { (id(api_connection) != true) };'
then:
- if:
condition:
api.connected:
then:
# just connected now
- lambda: "id(api_connection) = true;"
else:
- if:
condition:
not:
api.connected:
then:
# just disconnected now
- lambda: "id(api_connection) = false;"
This code creates a trigger for both the connected and disconnected state changes.
I’ve just written a ‘Router Watcher’ that does exactly this.
It will check every minute for a connection, if not it will add to the global int. Once that global int gets to 5 it performs a reboot and adds to a reboot counter. It has an override switch (for when you’re updating HA) and is easily configured.
Hope this is uselful to someone.
time:
- platform: homeassistant
id: hass_time
on_time: # This will reset the rebootcounter at Midnight Sunday
- seconds: 0
minutes: 0
hours: 0
days_of_week: 2
then:
- number.to_min: rebootcounter
number:
- platform: template # This will count the number of times your the router has been rebooted
id: rebootcounter
name: Reboot Counter
optimistic: True
restore_value: True
mode: box
min_value: 0
max_value: 120 # This is the maximum number of reboots it counts to (however, it will still reboot more)
step: 1
icon: mdi:restart-alert
unit_of_measurement: Count
globals:
- id: counter # This is a counter that increases each time the API is not connected.
type: int
restore_value: False
initial_value: "0"
switch:
- platform: gpio
pin: GPIO0
name: ${upper_devicename} Relay
id: router
inverted: True
restore_mode: ALWAYS_ON
on_turn_off:
- delay: 30s
- switch.turn_on: router
- platform: template
name: ${upper_devicename} Disable
optimistic: True
restore_mode: ALWAYS_OFF
id: disable
icon: mdi:stop-circle
interval:
- interval: 1min # Every minute
then:
- if:
condition:
or:
- api.connected:
- lambda: return (id(disable).state != 0); # If the API is not connected
then:
- globals.set: # Reset the global 'counter'
id: counter
value: "0"
else:
- lambda: id(counter) += 1; # Else add 1 to the global 'counter'
- if:
condition:
lambda: return (id(counter) >=5); # If the value of global 'counter' is 5 or above
then:
- number.increment: rebootcounter # Add 1 to the number 'rebootcounter'
- globals.set:
id: counter
value: "0" # Reset the global 'counter'
- switch.turn_off: router # Turn off the router
- logger.log:
format: "Disconnect Counter is: %i, Disable State is: %i"
args: [ '(int)id(counter)','(int)id(disable).state' ]
And this is what I made, I used an extension cable, cut it in half, through a buck converter and an ESP-01 with a relay module.
As for the counter, do I just increase to 3 or 5 counts since it’s 1 by default?
time:
- platform: homeassistant
id: hass_time
on_time:
- seconds: 0
minutes: 0
hours: 0
days_of_week: 2 <-- what is this for?
then:
- number.to_min: rebootcounter
number:
- platform: template
id: rebootcounter
name: Reboot Counter
optimistic: True
restore_value: True
mode: box
min_value: 0
max_value: 120 <-- is the equals to 120 seconds for each counter? do i just reduce the time here (eg 60 seconds)
step: 1
icon: mdi:restart-alert
unit_of_measurement: Count
Every minute it checks if there is a connection to the HA API, if not it will add 1 to the counter, after that counter has reached 5, the switch will turn off the router for 30 seconds and then switch it back on.
The visible counter ‘reboot counter’ shows how many times it has actually gone through all 5 and rebooted the router.
The counter resets at midnight Sunday (That’s what days of the week does) max_value: is just a maximum number for the counter.
In short, yes, the stuff in the interval will only run if the API is disconnected.
id: rebootcounter is just a counter that add 1 everytime the router is rebooted, it’s not needed, but gives you an indication that there has been a reboot.
The configurable parts are :-
How long the interval is (it’s set for 1 minute at the moment)
HI!
i have same problem - i can fix when my devise connecting HA, but in any case i can’t fix when it disconnecting,
My task is monitor “HA accessible”
when “YES” turn switch on, when “NO” - turn switch off
i tryed to use condition api.connected and triggers on_client_connected: and on_client_disconnected: with same result