Esphome: Keep cover positions or other global variables after reboot/repower

Programmed a rollershutter via cover. That works fine, but I have a problem with status of device after reflash firmware, reboot or repower.
I thought with setup like this:

  - id: pref_pos
    type: int
    restore_value: yes
    initial_value: '55'
  - id: timer_active
    type: bool
    restore_value: yes
    initial_value: 'true'

… I could have an initial values 55/true after flashing and after any modification and reboot/repower I get the latest value.
Same I thought about the actual “cover” position. Once properly set it should survive reboot or power cycles, but it doesn’t. Is there any trick that I missed?
BTW: How often I can write to flash - is it NOR-flash?
I am using a BK7231n.

If you want it to be 55 after reboot, set restore_value: no

If I understand the manual, the “initial_value” is AFTER flash and if no recovery from restore is possible. I want to come up with 55 originally, but if changed to some other value, I want to keep the changed value. That’s why the “restore”.

You are not very clear.
What you mean “after flash”? Can you make an example of wanted behavior ?

This exact topic gets brought up on here fairly frequently and you can find a lot of good information and shared configurations from lots of people who solved this issue. if you do a forum search for something similar to your posts current title, it shouldn’t be hard to find.

I think that isn’t as easy. If you think about esp8266_restore_from_flash - This isn’t an esp, it is a bk731n.

bk72xx: [source moes.yaml:18]
  board: generic-bk7231n-qfn32-tuya
  [esp8266_restore_from_flash] is an invalid option for [bk72xx]. Please check the indentation.
  esp8266_restore_from_flash: true

With after flash: I mean after flashing a new firmware to device.
I am in the middle of testing, and so I have to do that very often.

To bad: I think I have a the required functionality, but the reboot/repower sync is not really working - at least offline (I means with no help of server, restoring last position).

Who knows how/if restore is implemented for your chip.
But initial_value should work. I would set all restore_values to false.

I found this:

but that doesn’t work for me. So I gave it up to use that restore_value - also because of the side effect of wear the flash.

Let’s distinguish 2 uses cases:
a) reboot (maybe caused by lost Wifi/MQTT connection)
b) repower (power loss)

It seem that something is saved to flash during reboot. So I added an action that cause App.safe_reboot(); and I see:

[10:24:58][I][app:132]: Rebooting safely…
[10:24:58][D][lt.preferences:104]: Saving 2 preferences to flash…
[10:24:58][D][lt.preferences:132]: Saving 2 preferences to flash: 0 cached, 2 written, 0 failed

How do I find out which 2 preferences are saved? I mean that it saves it is likely what I want, but I didn’t ordered that ?!?
I don’t know whether same is happening when it reboots by itself (because of lost wifi).

Nevertheless the following can happen - at least in power-cycle:
Assume we are at position 40% and it reboots with 0%. Than cover operations can’t run to fully 0 (closed), as we are already there.

I added to cover the lower 6 lines - see below. That would make sure that if system thinks (!) it is fully opened or closed it will go to end (as switch-operations are not under control). Otherwise it would stuck at the point it thinks it is not going further to the end positions. But anyhow that is a dirty hack imho.

  - platform: time_based
    name: moes1
    id: my_cover
      - switch.turn_on: switch_up
      - output.turn_on: output_led_up
    open_duration: 26000ms
      - switch.turn_on: switch_down
      - output.turn_on: output_led_down
    close_duration: 25000ms
      - switch.turn_off: switch_up
      - switch.turn_off: switch_down
      - output.turn_off: output_led_up
      - output.turn_off: output_led_down
    assumed_state: no
      - logger.log: "Cover is/should fully open!"
      - switch.turn_on: switch_up
      - logger.log: "Cover is/should fully closed!"
      - switch.turn_on: switch_down

It’s confusing.
With esp32 I expect states are saved to RTC memory and they survive “soft reboot” even if not written to flash.
With your chip no idea.

Make a test yaml just with global variable set to restore_value: yes
Increment that global every startup on_boot: with lowest priority (or manually)
And then try different reboot-/power-cycles to see if it was restored.

I used now a small piece of code only for test as you recommend.
Indeed I can see that in on_boot the variable changes when reboot.
It is not happened after repower - unless you wait some time!

In log I could see the following:

[16:56:58][D][sensor:093]: 'Uptime': Sending state 297.11401 s with 0 decimals of accuracy
[16:57:01][I][ota:117]: Boot seems successful, resetting boot loop counter.
[16:57:01][D][lt.preferences:104]: Saving 3 preferences to flash...
[16:57:01][D][lt.preferences:132]: Saving 3 preferences to flash: 0 cached, 3 written, 0 failed

After that happens it is save to repower.

The reboot does this when “reboot” is recognised like that:

[17:05:44][I][restart.button:012]: Restarting device...
[17:05:44][I][app:132]: Rebooting safely...
[17:05:44][D][lt.preferences:104]: Saving 3 preferences to flash...
[17:05:44][D][lt.preferences:132]: Saving 3 preferences to flash: 0 cached, 3 written, 0 failed

What I am not sure about is:
Now I am changing the value during boot. If that happens later, 1h after boot - will than also 5min later the “save to flash” happen?
If not, can this be triggered to slow down or speed up that time?

Mh, now I go back to my code, and I see this

D][lt.preferences:104]: Saving 3 preferences to flash...

again 5min after boot, but not after some changes in variables.
What is the difference: once I changed the status right after boot, otherwise based on an action. Pfff … and now?

I guess I get changes before the 5min was up and not after that time.

Uh… ya, thats kind of an important detail that I somehow missed in your OP. 99% of the time its usually an esp8266/esp32 being used and thats what I wrongly assumed.

Until someone can explain what I am doing wrong, I filed a bug here: