Skip to content

feat(sonoff): retain SWV irrigation plan slots by index#12669

Draft
MaxRink wants to merge 1 commit into
Koenkk:masterfrom
MaxRink:sonoff-swv-read-irrigation-plan
Draft

feat(sonoff): retain SWV irrigation plan slots by index#12669
MaxRink wants to merge 1 commit into
Koenkk:masterfrom
MaxRink:sonoff-swv-read-irrigation-plan

Conversation

@MaxRink

@MaxRink MaxRink commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

What

Adds per-slot retention for SONOFF SWV/SWV-ZFE irrigation plan reports:

  • keeps the existing irrigation_plan_report as the last report received
  • adds irrigation_plan_report_0 ... irrigation_plan_report_5 so reports are retained by plan_index instead of overwritten
  • documents the limitation that the device protocol reports a single plan object at a time and no confirmed safe active per-slot read command is known yet

Why

The valve supports up to 6 irrigation plan slots, but the current converter exposes only the last pushed report. When the device reports another slot, Home Assistant loses the previous slot state. Retaining by plan_index lets HA show/read each slot independently once the device has pushed it.

Discovery / live test

Tested on live SONOFF SWV-ZFE Bewässerungsventil (0xa4c1381456c7ffff, firmware 1.0.7) in Zigbee2MQTT 2.12.1-dev.

Safe discovery steps:

  • Existing irrigation_schedule_status GET reads attribute irrigationScheduleStatus and does not trigger plan reports.
  • Existing plan report state before the change showed only the last pushed report (plan_index: 2).
  • A conservative candidate command using custom cluster 0xfc11, command id 0x09, payload [0] was sent once and again after restart. Zigbee2MQTT logged the outgoing customClusterEwelink.readIrrigationPlan({data:[0]}), but the device did not return an irrigationPlanReport; therefore active on-demand read is not included in this PR.

Live deployed fallback build confirmed:

  • Zigbee2MQTT starts healthy.
  • HA discovery/state includes irrigation_plan_report_0 ... _5 alongside the legacy irrigation_plan_report.
  • Slot entities are initially empty until the device pushes those specific slots, which is expected for retention-only behavior.

Screenshot: plan-slots-01-devtools-states.png captured from HA Developer Tools.

Validation

  • corepack pnpm run check passes (Biome prints an existing schema-version info).
  • corepack pnpm run build passes.
  • corepack pnpm exec vitest run test/sonoff.test.ts has the new retention test passing; one unrelated existing SWV configure test fails in this sandbox because installed zigbee-herdsman@10.6.2 makes Device.save() access undefined internals.
  • corepack pnpm test has the Sonoff tests including the new test passing; one unrelated batteryState.test.ts test times out at 5s in this sandbox.

cc @CubeZ2mDeveloper

Related: Koenkk/zigbee2mqtt#32545, #12647

@github-actions

Copy link
Copy Markdown
Contributor

External review required

This PR modifies files that require review from their code owners before merging.

@CubeZ2mDeveloper:

  • src/devices/sonoff.ts

Once reviewed, add the external-reviewer-approved label to unblock this check.

@MaxRink

MaxRink commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

@CubeZ2mDeveloper — a question on the SWV/SWV-ZFE irrigation-plan protocol, if you can help:

This PR retains irrigationPlanReport (0x09) responses per plan_index so each configured slot is individually visible in Home Assistant. But it's currently passive — the per-slot entities only populate when the device pushes a report (e.g. on plan create/change). There doesn't appear to be a documented on-demand read command.

Is there a command to actively request an irrigation plan by index (so a controller can read slots 0–5 on demand and show all configured plans)? The custom customClusterEwelink cluster exposes commands readRecord, irrigationPlanSettings (0x06, write), irrigationPlanRemove, rainDelay, and the irrigationPlanReport (0x09) response. I tried issuing 0x09 with a plan_index payload but the device sent no report back.

Specifically:

  1. Is there a read/query command ID (and payload format) that makes the device emit irrigationPlanReport for a given plan_index (or dump all slots)?
  2. Does the device proactively report all configured plans at any point (interview / reconnect / after a schedule-status read), or only the last-changed plan?
  3. If there's no read command, is retaining pushed reports per index (as here) the right approach, or would you prefer a different model?

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