Skip to content

DRV-41: fix esphome_fan DESIGNATE_PRESET handler#60

Merged
svc-finitelabs[bot] merged 1 commit into
mainfrom
agent/DRV-41-fix-designate-preset
May 23, 2026
Merged

DRV-41: fix esphome_fan DESIGNATE_PRESET handler#60
svc-finitelabs[bot] merged 1 commit into
mainfrom
agent/DRV-41-fix-designate-preset

Conversation

@svc-finitelabs

Copy link
Copy Markdown
Contributor

Fixes DRV-41. Reported by Dwayne Newsome via #56.

Problem

RFP.DESIGNATE_PRESET in drivers/esphome_fan/driver.lua was broken end-to-end:

  1. Wrong param key. Handler read tParams.SPEED, but the C4 fan proxy sends tParams.PRESET. PRESET_SPEED was always nil.
  2. Value never applied. on() sent {has_state=true, state=true} only, so even with the key fixed, Turn On Fan would ignore the designated preset.
  3. Value not persisted. Driver restart (firmware update, reboot) dropped the setting.
  4. No NOTIFY. Proxy never received PRESET_SPEED, so Composer/Navigator never reflected the designated value.

Symptom from Dwayne's trace:

RFP.DESIGNATE_PRESET(5001, DESIGNATE_PRESET, {"PRESET":"5"})
Preset speed set to nil

Fix

  • Read tParams.PRESET, clamp to [1, DISCRETE_LEVELS], persist via lib.persist, and SendToProxy(PROXY_BINDING, "PRESET_SPEED", { SPEED = tostring(n) }, "NOTIFY") on every change.
  • Hydrate PRESET_SPEED from persist in OnDriverLateInit and re-emit the NOTIFY so Navigator stays in sync across restarts.
  • on() now includes has_speed_level/speed_level when PRESET_SPEED is set, so every ON entry point (RFP.ON, RFP.TOGGLE from off, DO_CLICK on ON/TOGGLE bindings, BUTTON_ACTION top/toggle) starts at the designated speed.
  • RFP.GET_CURRENT_STATE re-emits the PRESET_SPEED NOTIFY for Navigator reconnects.

Behavior matches the reference drivers cited on the ticket (lutron_ra2_select_fan, confio_fan, lutron_leap_fan_controller, chowmain_*, DriverWorks_IR_generic_fan, control4_lux_2_wire_switch).

Test plan

  • Composer -> Designate Preset -> speed 5 on a 5-speed fan -> trace shows Preset speed set to 5, Navigator preset chip reflects 5.
  • Programming -> Turn ON Fan -> fan reports speed 5 (matches PRESET_SPEED), not last speed, not nil.
  • Driver restart -> PersistGetValue("PRESET_SPEED") returns 5, NOTIFY is re-emitted on OnDriverLateInit.
  • Set preset out of range (0, 99) -> handler logs warning, prior value retained.

The Composer "Designate Preset" command was broken end-to-end:

- The handler read tParams.SPEED but the C4 fan proxy sends tParams.PRESET,
  so PRESET_SPEED was always nil.
- The captured value was never applied; on() ignored it and the user could
  not later issue "Turn On Fan" at the designated speed.
- The value was not persisted, so driver restarts dropped it.
- The proxy was never notified, so Navigator/Composer never reflected the
  designated preset.

Fixes:

- Read tParams.PRESET, clamp to [1, DISCRETE_LEVELS], persist via lib.persist,
  and NOTIFY the proxy on every change.
- Hydrate PRESET_SPEED in OnDriverLateInit and re-emit the NOTIFY.
- Apply the preset in on(): when PRESET_SPEED is set, the ENTITY_COMMAND
  includes has_speed_level/speed_level so all entry points (RFP.ON, TOGGLE
  from off, top-button, ON_BINDING DO_CLICK, BUTTON_ACTION) start at the
  designated speed.
- Re-emit the PRESET_SPEED NOTIFY in GET_CURRENT_STATE so Navigator stays
  in sync when reconnecting.

Reported by Dwayne Newsome via #56.
@svc-finitelabs svc-finitelabs Bot force-pushed the agent/DRV-41-fix-designate-preset branch from 101dfd4 to 2ed35af Compare May 22, 2026 04:06
@svc-finitelabs svc-finitelabs Bot merged commit aa125c5 into main May 23, 2026
1 check passed
@svc-finitelabs svc-finitelabs Bot deleted the agent/DRV-41-fix-designate-preset branch May 23, 2026 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant