Skip to content

Modes

Three modes, set from Home Assistant and stored on the ESP32. Default is Off.

Mode Behaviour
Off Automatic mechanisms off. The LED follows Home Assistant on/off only
Schedule Daily start/end window on the device clock (can cross midnight)
Night Lux hysteresis: on at or below Night On Lux, off at or above Night Off Lux
flowchart TD
  T[Mode changes, or every 15 s] --> S[apply_mode script]
  S --> M{Mode?}
  M -->|Off| O[Do nothing]
  M -->|Schedule| C{Inside the window?}
  C -->|yes| ON[LED on]
  C -->|no| OFF[LED off]
  M -->|Night| L{Lux reading}
  L -->|at or below On| D[Dark: LED on]
  L -->|at or above Off| B[Bright: LED off]
  L -->|in between| K[Keep the last answer]

Mode select

select:
  - platform: template
    name: Mode
    id: control_mode
    icon: mdi:cog
    optimistic: true
    restore_value: true
    initial_option: "Off"
    options:
      - "Off"
      - "Schedule"
      - "Night"
    on_value:
      then:
        - script.execute: apply_mode
Key What it does
optimistic: true Takes the value Home Assistant sends and reports it back
restore_value: true Saves the choice in NVS across reboots
initial_option First-boot default: Off
on_value Runs apply_mode immediately when the mode changes

Schedule and Night settings

Schedule uses two Home Assistant time entities so hour and minute commit together (avoids applying a half-edited window). Night uses two lux number entities. All are optimistic with restore_value: true, so Home Assistant sets them and the device keeps the last value after reboot and while offline.

datetime:
  - platform: template
    type: time
    name: Schedule Start
    id: sched_start
    entity_category: config
    icon: mdi:clock-start
    optimistic: true
    restore_value: true
    initial_value: "18:00:00"

  - platform: template
    type: time
    name: Schedule End
    id: sched_end
    entity_category: config
    icon: mdi:clock-end
    optimistic: true
    restore_value: true
    initial_value: "23:00:00"

number:
  - platform: template
    name: Night On Lux
    id: night_on_lx
    entity_category: config
    unit_of_measurement: lx
    min_value: 0
    max_value: 1000
    step: 1
    initial_value: 20
    optimistic: true
    restore_value: true
    mode: box

Night Off Lux uses the same number pattern with default 40 lx (range 0–2000).

Entity Type First-boot default
Schedule Start time 18:00
Schedule End time 23:00
Night On Lux number 20 lx
Night Off Lux number 40 lx

Out of the box, Schedule runs 18:00–23:00, and Night turns on at 20 lx and off at 40 lx. entity_category: config groups them under Configuration on the device page in Home Assistant (expand that section if you only see Mode).

Mode Label

text_sensor:
  - platform: template
    name: Mode Label
    id: mode_label
    entity_category: diagnostic
    update_interval: 2s
    lambda: |-
      if (!id(control_mode).has_state())
        return {"Off"};
      return {id(control_mode).current_option().str()};

Read-only diagnostic text that repeats the current mode name. Useful on a dashboard card; falls back to Off until the select has a value. The TFT also draws the mode name from control_mode directly.

Apply loop

interval:
  - interval: 15s
    then:
      - script.execute: apply_mode

apply_mode runs on mode change and every 15 seconds. It only toggles the LED when the answer differs from the current state.

  • Off: does nothing to the LED.
  • Schedule: compares local time to the window. Equal start and end means an empty window (LED off). Start later than end means the window crosses midnight (e.g. 22:00–06:00). Needs a valid clock — after a cold boot with no network it waits for SNTP.
  • Night: keeps an on-device flag night_is_dark. At or below Night On Lux the flag turns on; at or above Night Off Lux it turns off; in between it keeps the last value (hysteresis). Keep On below Off. The flag is not saved across reboot.

The screen always shows the current mode name. See Lux and LED for how HA overrides interact with Schedule and Night.

Next: Display