Restore switch state after reboot using globals

Hey all,

I have a relay module that uses esp32s3 and I’m trying to restore my relay state (with id relay1) to ‘OFF’ after a power reboot, if it was ‘OFF’ prior to the reboot. I’m using global variables for this. Here’s my attempt:

esphome:
  name: waveshare-6ch-relay
  on_boot:
    then:
      if:
        condition:
           lambda: "return id(relay1_status).state == 'false';"
        then:
          - switch.turn_off: relay1

esp32:
  board: esp32-s3-devkitc-1
  flash_size: 8MB
  framework:
    type: arduino

# Enable logging
logger:
  level: DEBUG
   
ota:
  - platform: esphome

wifi:
  ap: 
    ssid: "6CH-Relay"

captive_portal:

mqtt:
  broker: 1.1.1.1
  username: test1
  password: test0
  keepalive: 4s

globals:
  - id: relay1_status
    type: bool
    restore_value: true
    initial_value: 'false'

switch:
  - platform: gpio
    pin: GPIO1
    id: relay1
    name: Relay 1
    restore_mode: RESTORE_DEFAULT_ON
    on_turn_on:
      then:
        - globals.set:
            id: relay1_status
            value: 'true'
    on_turn_off:
      then:
        - globals.set:
            id: relay1_status
            value: 'false'

I’m getting the following error during compile:

Compiling .pioenvs/waveshare-6ch-relay/src/main.cpp.o
/config/esphome/waveshare-6ch-relay-wifi-mqtt-only.yaml:7:46: warning: character constant too long for its type
            lambda: "return id(relay1_status).state == 'false';"
                                              ^~~~~~~
/config/esphome/waveshare-6ch-relay-wifi-mqtt-only.yaml: In lambda function:
/config/esphome/waveshare-6ch-relay-wifi-mqtt-only.yaml:7:37: error: request for member 'state' in 'relay1_status->esphome::globals::RestoringGlobalsComponent<bool>::value()', which is of non-class type 'bool'
            lambda: "return id(relay1_status).state == 'false';"
                                     ^~~~~
*** [.pioenvs/waveshare-6ch-relay/src/main.cpp.o] Error 1
========================== [FAILED] Took 9.31 seconds ==========================

Not sure what this means,

I also tried :

on_boot:
  then:
    - lambda: |-
        if (!id(relay1_status)) { 
          id(relay1).turn_off();
        }

And this compiled but for some odd reason that I’m struggling to figure out, it didn’t work. relay1 turned on even when it was off prior to a reboot.

Thanks.

Globals don’t have state, use them just like variables.
lambda: “return id(relay1_status) == ‘false’;”

Anyway, you should be able to restore your switch state without globals.

Is your relay active high? Or maybe it should be inverted?
Also be aware that default flash write interval is 1min, if you change the relay state and right after turn the power off, new state is not saved.
You can adjust that if needed:

preferences:
  flash_write_interval: 30s
1 Like

Whoa, changing flash interval worked! Thank you!

You are welcome.
Be aware that in some rare applications, for example if your relay was changing the state every second 24/7, setting interval to 0 would lead to 1/s flash writes and would wear flash 60 times quicker than with default setting.

In normal use you don’t have to worry about it though.

1 Like

That’s good to know. So just to confirm - I have flash interval set to 30s and I’m seeing in logs that esp writes to flash 30s after relay changes state [I initially assumed it’d write to flash every 30s regardless of state changes]. If I set this to 0s, it means esp will write to flash right away. Which, in my case, shouldn’t be harmful since my relay doesn’t change states super often [once in a couple hours maybe]. So I’m safe to set this at 0s?

Yes, would be safe. But in practice, do you need so quick “backup” on your application?
If your relay changes state every 5min, the flash write would be same with default or 0s interval.
Just be aware that in some other application it could be bad idea. Fortunately you see the flash writes on log.

1 Like