ESPHome switches / relays states after reboots / power loss

Hello there,

I'm totally fond of the whole ESPHome idea & implementation.

Its integration into the Home Assistant ecosystem is brilliant and I love the way you can program a whole device's logic right into its ESPHome code without having to rely on Home Assistant for a lot of a device's smart functions implementations. All of this is really cool.

I've been using Tasmota before, it's really nice too. But I now have a tendancy to convert/start using new devices with ESPHome directly.

There's just one thing that just doesn't feel right to me and that ultimately prevents me from going "all ESPHome" : the state of switches on reboot / power loss.

This is actually something I've been bothered with for a long time and it's even become a decisive aspect of my choice between Tasmota and ESPHome : every time a device's switch absolutely needs to keep its previous state on reboot I always use Tasmota even though I know I'll miss a lot of the above capabilities I'm really happy with in ESPHome.

I read quite a lot about restore_mode, flash_write_interval and the abundant forum litterature they generated but I can't seem to find anything as satisfying as Tasmota's straightforward way of handling switches' states after reboots : they simply remain as they are. Simple as that.

My recent new experience was with 3 x Sonoff POWR320D. These devices, unlike the Sonoff Basic, have bistable relays so I initially thought that reboots wouldn't do much as these types of relays need to be explicitely set/reset to change state. But, guess what ? No.

On every reboot, my relay (exposed as a switch in Home Assistant/ESPHome) gets set to the OFF position on reboot, whatever the settings I tried in the code. With Tasmota, it doesn't. The reboot has absolutely no effect on the relay (neither has it on the built-in LED). They just remain the way they were bofore power-cycling...

The options I tried in ESPHome are :

  • The described code/setup on ESPHome devices' page
  • Adding different flavors of restore_mode : combined with a flash_write_interval: 0s

Nothing seems to do the trick. It's as if on every reboot, at quite an early stage, before anything even gets displayed on the screen, the relay gets set to its off position.

I (really) tried a lot of stuff but this time, the devices really can't start on a different state than the one they were in before power outage / intended interruption. So I reluctantly reverted to Tasmota which perfectly does the job of restoring an identical device in such a situation.

Let's be clear : I like Tasmota. I'm not being judgmental or anyhting. It's just that I miss the configurability and programming/scripting abilities offerd by ESPHome.

If anyone has an idea on how I could reliably get reboot-proof switch states in ESPHome, I'm all ears :slight_smile:

With one or two inputs?
Did you observe your logs? What you get there when switching state, do you get flash save therel? And on boot, what you get on logs about restore...

From what I understand, Sonoff PWR320D relays have 2 inputs :

  • One for putting the relay in a "direction" i.e. connect COM to NO
  • One for putting the relay in the other "direction" i.e. connect COM to NC

To be absolutely honest : I didn't check logs. Will do for sure :folded_hands:

While investigating tonight I realized ESPHome has a perfectly suited component AKA H-bridge switch to operate such relays. Will look less cluttery than the solution given in the ESPHome device page.

BTW : Tasmota effortlessly remembers status LEDs state too. Which is convenient in configurations such like the present one (lit LED <-> closed relay / unlit LED <-> open relay).

I'll continue investigating. I hope logs give me a better insight. I somehome just wish this behavior could be more easily configured. But that's another story.

Thanks @Karosm

Remember that 2-pin latching relay needs physical pulse on one of the inputs to change state. So if state changes on boot, it means relay got pulse for that change. Its not like normal case of static high/low state of some pin.

Hi Jemome. I drafted a reply ... then realised I (and maybe Karosm) had made the assumption that you were adding a relay to an ESP32 microcontroller ... but looking at the Sonoff POW Elite 20a (POWR320D) device page you linked to earlier, I realise it is the ESP32 microcontroller ... which includes a bistable relay, power meter and even a display.

If i understand correctly, the issue is that when powering on, the relay hardware is staying in its current state - but the control in ESPHome is being reset, and so gets out of sync with the hardware.

If you are using the yaml which you pointed to earlier, it appears that on-boot: is setting the relay_1 switch on if there is power flowing through the relay, and setting it off otherwise.

Are you perhaps bench testing the device and do not have the relay connected to power ? If so, the on_boot is correctly turning the switch off - because no power must mean that the relay is off.

Alternatively I suggest to determine the values for v_sensor and a_sensor used in the on_boot condition

 lambda: 'return id(v_sensor).state > 90 || (id(v_sensor).state > 10 && id(a_sensor).state > 0.1);'

Thanks @donburch888

Using the device page's code, the device's relay doesn't stay in its previous state on boot and/or power loss/power on. If the previous state is ON, then it always gets back in to the OFF position at a very early stage in the boot process (from what I can infer).

I understand what the piece of lambda code you quoted from the device page's configuration is supposed to do but it is not really what I'm trying to achieve. I don't actually want the control value in ESPHome to get its state from a measurement (although that'd actually be ok with voltage only) but from its previous state before being "shut down" (properly or not i.e. rebooted or unplugged).

I was not bench testing the device, it is actually already connected to its intended load. The thing is : if the Sonoff PWR320D gets rebooted if the load is turned off, no current can be measured flowing through it.

I hope I'm being clear enough.

Could you use early_pin_init: false ??

A long shot, but... did you "play" a lot with setting "flash_write_interval: 0s" ? If so, flash might be dead... don't use that setting too long, flash can wear out pretty quick doing that, especially if you have any sensors that have a lot of state changes.

But, posting your whole yaml (hiding secrety only) would perhaps help troubleshooting your problem...

Most of sensor values are not saved in flash, but yes, total_daily_energy is one that has restore parameter and combined with short update interval on power sensor it could write flash at high frequency.

Thanks @MuzzaM !

I never heard of the early_pin_init configuration variable before !

It sounds as if this would prevent exactly what's actually happening in my situation but it appears it only exists for the ESP8266 Platform :slightly_frowning_face:

I'll make a big cleanup of my yaml and send it here so any inconsistency can be investigated for :grin:

Don't forget your logs...

Thanks everyone,

I cleansed my code as much as I could, I removed sensors I don't really actually use (total_daily_energy, uptime, WiFi info, internal_temperature...).

It seems to work now.

I don't really understand why.

I simply tried (again) using restore_mode: ALWAYS_ON as a test. And it simply worked.

This puzzles me a little but I'll deal with it :slightly_smiling_face:

This makes me think of something a little strange : is it possible that in the process of uploading new ESPHome code, the ESP32 chip doesn't really reset on reboot and actually executes the previous code ? Sounds like a strange idea but what happened during my tests really looked like it.

For example : the first time I tried restore_mode: ALWAYS_ON I'm pretty sure the relay didn't start in the ON state... It did the second time though.

I'm somewhat sorry for having spammed the forum a little :confused:

In the meantime, I think my code is a more compact/clean version of what's actually present on the ESPHome device page. Does someone know the way to propose a revised version for it ?

Fork the repo
Make the changes to the docs
Test them
Create the PR

You forgot the last step...
Wait for it to be closed as stale without anyone looking at it