I have a Sonoff basic running ESPHome that is used to open and close a water valve for a set amount of time. It is automated in HA and all that works perfectly.
I wanted to build in a failsafe mechanism so that if HA crashes while the valve is open, ‘ESPHome’ on the Sonoff would makes sure the valve closes after a reasonable amount of time. The code below is what I was trying.
For some reason which I can’t work out, it doesn’t always work as expected. I’m not expecting anyone to actually write me a working solution (but go ahead if you like!) but is there something in this that I have missed or do you agree that it should work and I must have missed something elsewhere?
(Full disclosure, I did get some, ahem, artificially intelligent help with this)
Briefly (as I understand it)
- The
failsafe_time
sensor retrieves its value from the HA entityinput_number.failsafe_time_in_seconds
). - The
interval
runs every 10 seconds - The Failsafe Logic is:
When the relay is ON:
A static variablestart_time
is used to track when it was turned on.
Ifstart_time
is0
, it is initialized to the current time usingmillis()
.
The elapsed time (millis() - start_time
) is compared to thefailsafe time.state * 1000
.
If the elapsed time exceeds the failsafe time, the relay is turned off, and the timer is reset.
When the relay is OFF:
The timer is reset to 0 to ensure it starts fresh the next time it is turned on.
#============
#=== Sensors
#============
sensor:
#=== Failsafe time
- platform: homeassistant
id: failsafe_time
entity_id: input_number.failsafe_time_in_seconds
#=============
#=== Switches
#=============
switch:
#=== Switch
- platform: gpio
name: ${friendly_name}
pin: GPIO12
id: relay
#=============
#=== Interval
#=============
interval:
- interval: 10s
then:
- if:
condition:
switch.is_on: relay
then:
- lambda: |
static unsigned long start_time = 0;
if (start_time == 0) {
start_time = millis();
}
if (millis() - start_time > id(failsafe_time).state * 1000) {
id(relay).turn_off();
start_time = 0;
}
else:
- lambda: |
static unsigned long start_time = 0;
start_time = 0;