Skip to content

feat(exposes): add withDefault for composite feature defaults#12667

Closed
MaxRink wants to merge 1 commit into
Koenkk:masterfrom
MaxRink:composite-atomic-ha-metadata
Closed

feat(exposes): add withDefault for composite feature defaults#12667
MaxRink wants to merge 1 commit into
Koenkk:masterfrom
MaxRink:composite-atomic-ha-metadata

Conversation

@MaxRink

@MaxRink MaxRink commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an optional per-feature default value to exposes via a new withDefault(value) builder on Base, and seeds defaults on the SONOFF cyclic timed/quantitative irrigation composites.

Why

A composite must be written to the device as one complete object in a single message; its fields are not independently writable (this is the whole point of composite — see #12495 and #12510 which were reverted by #12647 because the SONOFF valve needs the full config in one write and new/empty plan slots have no cached state to merge).

A companion Home Assistant composite-editor card (and potentially other consumers) needs sensible per-field defaults so it can pre-fill a new/empty composite slot and build a complete payload. This adds that capability without changing any converter logic — only optional metadata.

Changes

  • src/lib/exposes.ts: optional Base.default + withDefault(), preserved through clone/copy (only when set, so serialized exposes are unchanged when unused).
  • src/devices/sonoff.ts: .withDefault(...) on the cyclic timed/quantitative irrigation composite features (values within declared ranges).
  • test/utils.test.ts: tests for setting/cloning and non-serialization when unset.

Companion work

Consumed by a Zigbee2MQTT change that discovers settable composites for Home Assistant and a custom Lovelace card that edits them (linked separately).

Adds an optional per-feature `default` (via `withDefault`) so consumers
(e.g. a Home Assistant composite editor card) can pre-fill fields of a
new/empty atomic composite slot and build a complete payload. A composite
must be written to the device as one complete object in a single message;
individually writing fields breaks devices like the SONOFF valve (see
Koenkk#12495/Koenkk#12510 reverted by Koenkk#12647). Seeds defaults on the SONOFF cyclic
timed/quantitative irrigation composites.
@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 11, 2026

Copy link
Copy Markdown
Contributor Author

Closing: the composite editor no longer needs converter-provided defaults. The Home Assistant card derives sensible field defaults directly from the expose schema (numeric → value_min, enum → first value, binary → value_off, text → ""), so this withDefault change is unnecessary. Keeping the composite atomic per the #12647 discussion.

@MaxRink MaxRink closed this Jul 11, 2026
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