So i have ESPHome running on SonOff switches. They use MQTT for communication.
ESPHome was much easier then Tasmota for me.
One issue is when we loose power (that happens more often in India then guys in the west), all my devices default to OFF. (Except devices running stock sonoff devices). This is a problem as say during the night if the fan is on before the power cut, it just stays off even after the power is back and a serious blocker in ‘wife acceptance’.
Just to clarify all my switches and my HassIO reboot. So is there a way out?
Yes. Set the restore_mode option for your switches.
restore_mode ( Optional ): Control how the GPIO Switch attempts to restore state on bootup. For restoring on ESP8266s, also see esp8266_restore_from_flash in the esphome section.
RESTORE_DEFAULT_OFF (Default) - Attempt to restore state and default to OFF if not possible to restore.
RESTORE_DEFAULT_ON - Attempt to restore state and default to ON.
ALWAYS_OFF - Always initialize the pin as OFF on bootup.
ALWAYS_ON - Always initialize the pin as ON on bootup.
Oops, i am very new to Hassio and Home assistant in general and assumed it was just an option i added to the gpio.
Sorry for that
Ok i am flashing it as i speak with the new option added.
I’ve been having the exact same issue, only with a WiFi power strip controlled by the Tuya integration.
One of the many reasons (other than tinkering) I setup HA in a Pi 3 was to be able to automate a “return to last state” sort of command/automation for my power strips because the Tuya and Smart Life apps don’t give you that option (Ewelink/Sonoff devices do).
I have 6 of these power strips, and every time there is a power outage, they remain in the “off” state.
Just to share my settings since I am hesitating to use restore_from_flash due to sonoff s31 logs current/power/voltage too.
This uses an input booleans to detect if I’m away from home (afh) and the switch’s state, it also uses the esphome on_boot function. There is a delay of 10s to compensate if there are multiple power trips and I wasn’t able to play with ‘wait_until’ condition.
I had the same problem and I was about to do the same, but I found why it didn’t retain the state and maybe it’s what happened to you, when doing the performance tests after having made the modifications and installed on the device proceeded to change the state of the device and immediately cut off the power, when turning on the power the device had not saved the previous state, what happens is that when making the change of state in the device it takes around 30 to 40 seconds in save the state in memory, so even though it takes a long time to save it during tests in everyday use it is not and it works correctly
esphome:
name: foco-papas
# on_boot:
# priority: 800
# ...
# then:
# - light.turn_off: foco_papas
esp8266:
board: esp01_1m
restore_from_flash: true #**For me just need to add this line.**
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
I’m trying to retain a value for a switch on esp32 without success while restore_from_flash on esp8266 is working fine. what should I do to write the value in the flash for esp32 devices?
I have been having the same problem for a long time.
I’ve tried both esp8266 and esp32 boards. Tried the esp8266_restore_from_flash with esp8266 and also restore_mode for switch entities on esp8266 and esp32. also I’ve tried restore_value setting with global variables.
Nothing worked properly.
also another parameter related with this is
preferences:
flash_write_interval: 0s
which makes it write values to flash on every state change.
I found a very effective way of retaining values on technically any entity, however it’s a bit slow.
The solution is to receive the last value from home assistant when the esp device api connects to home assistant. For this to work you need to use the helper entities to hold values and a syncing script on home assistant which sends the retained values to esp home device. on the esp home device you use an interval to detect api connection state changes and when the api is connected, use a homeassistant.service script run command which runs the syncing script on home assistant.
this is my code:
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
# request sync from home assistant
- lambda: "id(api_connection) = true;"
- homeassistant.service:
service: script.sync_aquarium_controller
else:
- if:
condition:
not:
api.connected:
then:
# just disconnected now
- lambda: "id(api_connection) = false;"
Also, one other thing to note is that home assistant will loose the latest helper values too if the power is cut without a proper shutdown depending on how recent was the last state change. Anyways the solution to that is a small UPS that triggers a graceful shutdown when the power is abruptly cut.
All - Thank you for this thread, as it helped me get a Sonoff S31 Wi-Fi Smart Plug up and running ESPHome. Since this thread was originally posted, there have been a few tweaks to the general ESPHome yaml config sections. I also had some initial confusion as to exactly how to get the “restore_mode” feature to work correctly on the ESP8266.
I will leave a copy of my ESPHome yaml config here for others who might benefit from it in the future.
EDIT: Updated on 2024-02-21 to work with ESPHome 2024.2.0 due to breaking change for the cse7766 sensor.
esphome:
name: sonoff-s31
friendly_name: Sonoff S31
esp8266:
board: esp01_1m
restore_from_flash: True # required on ESP8266 to enable restoring device settings upon restart
preferences:
flash_write_interval: 5min # set to 5min to prevent wearing out the onboard flash module too quickly
# Enable logging
logger:
baud_rate: 0 # (UART logging interferes with cse7766)
# Enable Home Assistant API
api:
encryption:
key: "redacted"
ota:
password: "redacted"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
#ap:
# ssid: "Sonoff-S31 Fallback Hotspot"
# password: "redacted"
captive_portal:
# Device Specific Config
uart:
rx_pin: RX
baud_rate: 4800
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: "Sonoff S31 Button"
on_press:
- switch.toggle: relay
- platform: status
name: "Sonoff S31 Status"
sensor:
- platform: wifi_signal
name: "Sonoff S31 WiFi Signal"
# update_interval: 60s
- platform: cse7766
current:
name: "Sonoff S31 Current"
accuracy_decimals: 1
filters:
- throttle_average: 60s
voltage:
name: "Sonoff S31 Voltage"
accuracy_decimals: 1
filters:
- throttle_average: 60s
power:
name: "Sonoff S31 Power"
accuracy_decimals: 1
id: my_power
filters:
- throttle_average: 60s
- platform: total_daily_energy
name: "Sonoff S31 Daily Energy"
power_id: my_power
switch:
- platform: gpio
name: "Sonoff S31 Relay"
pin: GPIO12
id: relay
# This next line is necessary to allow the relay to return to its last state after a restart.
# If no flash data is available, it will leave the relay off.
restore_mode: RESTORE_DEFAULT_OFF
time:
- platform: sntp
id: my_time
status_led:
pin:
number: GPIO13
inverted: True
When you set the flash_write_interval to 0min the state will be written to flash only when the state changes. When using the device only as a switch normally the number of flash writes will be very low.
What about the power reporting state data generated by the Sonoff S31 outlet? That was my main concern with wearing out the flash memory, and thus my reason for using the 5min interval. It seemed like a somewhat reasonable compromise in my use-case.