Struggling with Light restore_mode

Scenario:
I have in the bedrooms the Sonoff NS Panel EU. These are running Blackymas’ excellent NSPanel_HA code. Releases · Blackymas/NSPanel_HA_Blueprint · GitHub

Relay 1 of the NSPanel has a ceiling downlight attached. Relay 1 is configured in the NSPanel as ‘fallback’ which means if the NSPanel_HA cannot reach the HASS server, it will fallback to having the buttons on the front directly control the relay. This means even if WiFi or HASS is down, the light can still be turned on or off.

The downlight is a DETA DET902HA. I have replaced the Tuya processor in the driver with a pin-for-pin compatible ESP8255. This works very well.

The NSPanel relay 1 stays on all the time, and when not in fallback mode button1 turns the light on and off with interception from Adaptive lighting.

The problem is in the ESPHome code for the downlight, specifically around restore_mode.

In theory:

  • RESTORE_DEFAULT_ON - Attempt to restore state and default to ON.
    …should be perfect. If HASS is up, then the light should restore its state when cold booted. If HASS is down, then state restore should fail and the light should come on. That way when the NSPanel_HA is in fallback mode, pressing the button turns on the relay, the downlight boots and after a short delay should fail to restore state and turn the light on.

Unfortunatley what happens is that the light comes on regardless. Even in similar cases (light loses WiFi, reboots) the light comes on.

I also tried restore_and_on with same effect.

Any ideas?

ESPHome: 2025.6.3

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: <redacted>

ota:
  - platform: esphome
    password: <redacted>

  # Enable fallback hotspot (captive portal) in case wifi connection fails


captive_portal:

substitutions:
  device_name: bed2-esp-det902ha-1
  friendly_name: "Bed 2 RGBW Downlight 01"

esphome:
  name: ${device_name}
  friendly_name: ${friendly_name}
#  on_boot:
#      priority: 600
#      then:
#          - light.turn_on:
#              id: downlight
#              color_mode: COLOR_TEMPERATURE
#              brightness: 90%
#              color_temperature: 4500K
#              transition_length: 8s
              
  
esp8266:
  board: esp01_1m
  restore_from_flash: true


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 172.16.130.230
    gateway: 172.16.130.1
    subnet: 255.255.254.0
    dns1: 172.16.128.2
    dns2: 172.16.128.3
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp-Det902Ha-04-Bed2-1"
    password: <redacted>


sensor:
  - platform: uptime
    name: ${friendly_name} Uptime

  - platform: wifi_signal
    name: ${friendly_name} Signal Strength

output:
  - platform: esp8266_pwm
    pin: GPIO12
    id: output_cw
    zero_means_zero: true
  - platform: esp8266_pwm
    pin: GPIO5
    id: output_b
  - platform: esp8266_pwm
    pin: GPIO13
    id: output_g
    zero_means_zero: true
  - platform: esp8266_pwm
    pin: GPIO4
    id: output_r
  - platform: esp8266_pwm
    pin: GPIO14
    id: output_ww
    zero_means_zero: true

light:
  - platform: rgbww
    id: downlight
    color_interlock: true
    restore_mode: RESTORE_DEFAULT_ON
    name: "RGBWW"
    red: output_r
    green: output_g
    blue: output_b
    warm_white: output_ww
    cold_white: output_cw
    cold_white_color_temperature: 5700 K
    warm_white_color_temperature: 3000 K
    default_transition_length: 4s
    gamma_correct: 2.8
    effects:
      - pulse:
      - random:
      - random:
          name: Random Fast
          transition_length: 1s
          update_interval: 2s

Logs from a cold startup below:

INFO ESPHome 2025.6.3
INFO Reading configuration /config/esphome/esp-det902ha-04-bed2-1.yaml...
INFO Starting log output from 172.16.130.230 using esphome API
INFO Successfully resolved bed2-esp-det902ha-1 @ 172.16.130.230 in 0.000s
INFO Successfully connected to bed2-esp-det902ha-1 @ 172.16.130.230 in 0.003s
INFO Successful handshake with bed2-esp-det902ha-1 @ 172.16.130.230 in 2.370s
[13:20:44][I][app:137]: ESPHome version 2025.6.3 compiled on Jul 11 2025, 08:06:31
[13:20:44][C][wifi:613]: WiFi:
[13:20:44][C][wifi:434]:   Local MAC: 70:03:9F:42:2D:AC
[13:20:44][C][wifi:439]:   SSID: [redacted]
[13:20:44][C][wifi:442]:   IP Address: 172.16.130.230
[13:20:44][C][wifi:446]:   BSSID: [redacted]
[13:20:44][C][wifi:446]:   Hostname: 'bed2-esp-det902ha-1'
[13:20:44][C][wifi:446]:   Signal strength: -54 dB ▂▄▆█
[13:20:44][C][wifi:455]:   Channel: 11
[13:20:44][C][wifi:455]:   Subnet: 255.255.254.0
[13:20:44][C][wifi:455]:   Gateway: 172.16.130.1
[13:20:44][C][wifi:455]:   DNS1: 172.16.128.2
[13:20:44][C][wifi:455]:   DNS2: 172.16.128.3
[13:20:44][C][logger:211]: Logger:
[13:20:44][C][logger:211]:   Max Level: DEBUG
[13:20:44][C][logger:211]:   Initial Level: DEBUG
[13:20:44][C][logger:217]:   Log Baud Rate: 115200
[13:20:44][C][logger:217]:   Hardware UART: UART0
[13:20:44][C][uptime.sensor:033]: Uptime Sensor 'Bed 2 RGBW Downlight 01 Uptime'
[13:20:44][C][uptime.sensor:033]:   State Class: 'total_increasing'
[13:20:44][C][uptime.sensor:033]:   Unit of Measurement: 's'
[13:20:44][C][uptime.sensor:033]:   Accuracy Decimals: 0
[13:20:44][C][uptime.sensor:033]:   Device Class: 'duration'
[13:20:44][C][uptime.sensor:033]:   Icon: 'mdi:timer-outline'
[13:20:44][C][uptime.sensor:034]:   Type: Seconds
[13:20:44][C][esp8266_pwm:022]: ESP8266 PWM:
[13:20:44][C][esp8266_pwm:023]:   Pin: GPIO12
[13:20:44][C][esp8266_pwm:024]:   Frequency: 1000.0 Hz
[13:20:44][C][esp8266_pwm:022]: ESP8266 PWM:
[13:20:44][C][esp8266_pwm:023]:   Pin: GPIO5
[13:20:44][C][esp8266_pwm:024]:   Frequency: 1000.0 Hz
[13:20:44][C][esp8266_pwm:022]: ESP8266 PWM:
[13:20:44][C][esp8266_pwm:023]:   Pin: GPIO13
[13:20:44][C][esp8266_pwm:024]:   Frequency: 1000.0 Hz
[13:20:44][C][esp8266_pwm:022]: ESP8266 PWM:
[13:20:44][C][esp8266_pwm:023]:   Pin: GPIO4
[13:20:44][C][esp8266_pwm:024]:   Frequency: 1000.0 Hz
[13:20:44][C][esp8266_pwm:022]: ESP8266 PWM:
[13:20:44][C][esp8266_pwm:023]:   Pin: GPIO14
[13:20:44][C][esp8266_pwm:024]:   Frequency: 1000.0 Hz
[13:20:44][C][light:092]: Light 'RGBWW'
[13:20:44][C][light:094]:   Default Transition Length: 4.0s
[13:20:44][C][light:094]:   Gamma Correct: 2.80
[13:20:44][C][captive_portal:089]: Captive Portal:
[13:20:44][C][esphome.ota:073]: Over-The-Air updates:
[13:20:44][C][esphome.ota:073]:   Address: 172.16.130.230:8266
[13:20:44][C][esphome.ota:073]:   Version: 2
[13:20:44][C][esphome.ota:080]:   Password configured
[13:20:44][C][safe_mode:018]: Safe Mode:
[13:20:44][C][safe_mode:019]:   Boot considered successful after 60 seconds
[13:20:44][C][safe_mode:019]:   Invoke after 10 boot attempts
[13:20:44][C][safe_mode:019]:   Remain for 300 seconds
[13:20:44][C][api:182]: API Server:
[13:20:44][C][api:182]:   Address: 172.16.130.230:6053
[13:20:44][C][api:187]:   Using noise encryption: YES
[13:20:44][C][wifi_signal.sensor:010]: WiFi Signal 'Bed 2 RGBW Downlight 01 Signal Strength'
[13:20:44][C][wifi_signal.sensor:010]:   State Class: 'measurement'
[13:20:44][C][wifi_signal.sensor:010]:   Unit of Measurement: 'dBm'
[13:20:44][C][wifi_signal.sensor:010]:   Accuracy Decimals: 0
[13:20:44][C][wifi_signal.sensor:010]:   Device Class: 'signal_strength'
[13:20:44][C][mdns:122]: mDNS:
[13:20:44][C][mdns:122]:   Hostname: bed2-esp-det902ha-1

Esp restores the state from it’s own memory, not from HASS. You have configured to save the state in flash memory, so it survives any kind of boot.

OK that makes sense, thank you.

I’ll look at trying to use the on_boot priority to detect if API is missing after a boot and turn the light on.

You could use restore mode ALWAYS_ON and then turn it off when / if API is connected.
on_client_connected:

1 Like

Thank you, that is the search term I was looking for a never finding :heart_eyes:

You’re welcome!