Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Add WPL33 heat pump support#373

Open
mhosse wants to merge 13 commits into
kr0ner:masterkr0ner/OneESP32ToRuleThemAll:masterfrom
mhosse:wpl33-supportmhosse/OneESP32ToRuleThemAll:wpl33-supportCopy head branch name to clipboard
Open

Add WPL33 heat pump support#373
mhosse wants to merge 13 commits into
kr0ner:masterkr0ner/OneESP32ToRuleThemAll:masterfrom
mhosse:wpl33-supportmhosse/OneESP32ToRuleThemAll:wpl33-supportCopy head branch name to clipboard

Conversation

@mhosse

@mhosse mhosse commented Jul 18, 2026

Copy link
Copy Markdown

Summary

Adds full support for the Stiebel-Eltron WPL33 heat pump variant as a
new device family, following the same conventions as the existing WPL13/17/23 profiles.
Along the way this also fixes a couple of small pre-existing issues and adds a generally
useful, opt-in addition to the shared wp_core component.

What's new

  • yaml/wpl33.yaml: new device profile, gated by the -DWPL_33 build flag (mirrors
    wpl13.yaml/wpl17.yaml/wpl23.yaml).
  • Independent from wpl_base.yaml (unlike WPL13/17/23): a large fraction of the properties
    wpl_base.yaml assumes exist turned out to never return real data on this unit, confirmed via
    live CAN bus logs from a real device. Rather than fight !extend/!remove around baked
    on_boot lambda code (doesn't clean up after itself), wpl33.yaml opts in explicitly to
    everything it actually needs, one property at a time — easy to trim further as more turn out
    to be unsupported.
  • CAN bus specifics for this unit: 20kbps bit rate (vs. the family default 50kbps), Heizmodul
    on CAN id 0x500 (vs. default 0x514), datetime synced via the Manager CAN node instead of
    Kessel.
  • WPL33-specific Betriebsart (operating mode) strings in mapper.cpp — this unit's mode
    names differ from WPL13/17/23.

New shared templates (usable by any future device family)

  • templates/wp_text.yaml: string-valued CAN properties (Type::et_err_nr, et_dev_id,
    etc.) as text_sensor, actively polled — parallel to wp_temperature.yaml/wp_generic.yaml
    for numeric properties.
  • templates/wp_binary_property.yaml: bool-typed CAN properties as proper binary_sensor
    entities, instead of forcing them through a numeric sensor (which crashes with
    bad_variant_access on a bool-holding value).
  • templates/wp_generic_passive.yaml / templates/wp_text_passive.yaml: for properties
    the unit broadcasts unsolicited (never in response to a request) — identical to
    wp_generic.yaml/wp_text.yaml but without any queueRequest calls, so they're never
    actively polled, only passively received.
  • templates/wp_datetime.yaml: parameterized with a target CAN node (wpl_base.yaml
    passes it through via a new datetime_target substitution), since WPL33 needs Manager
    instead of the family default Kessel.

Diagnostics: opt-in unmapped-property tracker

components/wp_core/unmapped_tracker.h — logs and persists (via flash) any CAN property id
that arrives on the bus but has no property.h entry, exposed as a text_sensor. Purely a
discovery aid for extending property.h on new/unfamiliar units; off by default
(core.yaml's track_unmapped_properties substitution) since it writes to flash on every
newly-seen id. Prunes entries on load once their property id gets a real mapping, so the list
doesn't accumulate stale/fixed ids forever.

Fixes picked up along the way (affect all device families)

  • Migrated the deprecated esphome.platformio_options.build_flags/build_unflags to the new
    flat esphome.build_flags across every device config (support for the old key is being
    removed in ESPHome 2026.12.0). build_unflags was dropped outright rather than migrated —
    it's silently ignored under the native ESP-IDF toolchain, so it was already dead.
  • esp32-poe-technik.yaml: added a commented-out wpl33 package line for discoverability,
    matching how wpl13/wpl17/wpl23 are already listed (not enabled — this example config
    runs THZ504).

Testing

  • Built, flashed, and run on a real WPL33 unit (20+ properties confirmed against live CAN
    telemetry; several properties present in the original draft were confirmed dead on this
    hardware and removed to reduce bus load; a few genuinely missing ones were added back with
    corrected CAN node targets).
  • esphome config validated for every touched device family (wpl13/17/23, thz304/404/504/
    5_5_eco, ttf07) to confirm the shared-file changes (wpl_base.yaml, core.yaml, template
    renames) don't regress anything outside WPL33.

root and others added 13 commits July 18, 2026 01:51
Moved these three out of wpl_base.yaml's shared assumptions (MFG/HK1/MFG,
inherited from WPL13/17/23) into per-variant declarations, since WPL33's
unit only responds on HK1/Kessel/Manager respectively. WPL13/17/23 keep
their existing MFG/HK1/MFG targets unchanged, now declared locally instead
of via the shared package.
The old key is deprecated (removal planned for 2026.12.0) and build_unflags
is silently ignored under the native ESP-IDF toolchain anyway -- RTTI is
already handled via sdkconfig_options in core.yaml.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core.yaml's Home Assistant Sensors block unconditionally writes HA's own
room temperature/humidity to CanNode::HK1 via these properties for every
device family. They were dropped in the earlier property.h cleanup because
wpl33.yaml itself doesn't poll them (confirmed dead as a read via FET), which
broke the WPL33 build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Discovery aid for extending property.h: logs (once per newly-seen id) and
persists via flash any CAN property id that arrives on the bus but has no
property.h entry, and exposes the running list as a diagnostic text_sensor.
Off by default (core.yaml's track_unmapped_properties substitution) since it
writes to flash on every newly-seen id -- override per-device to "true" to
enable. Confirmed working on the WPL33 unit, already surfacing real ids.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
GERAETEKONFIGURATION, ACCESS_EEPROM, and INITIALISIERUNG arrive on the bus
unprompted (confirmed via the unmapped-property tracker) and must never be
actively requested -- templates/wp_generic_passive.yaml is templates/wp_generic.yaml
minus both queueRequest calls (no self-poll, no one-shot request at boot),
registering only a receive callback. INITIALISIERUNG is wired up once per
CAN node it was seen on (HK1/Kessel/Manager/Heizmodul).

Also reworded the property.h comments for the WPL33 block to name the
specific properties they describe, and added blank lines between groups --
the association between comment and property was previously ambiguous.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
No longer clear why this had its own et_err_nr/text_sensor path for WPL33
only -- likely leftover from an early test. Since no actual error codes have
come up in practice, align it with every other device family: plain numeric
error code via templates/wp_generic.yaml.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
track() only checked for duplicates before appending -- nothing ever removed
an entry once its property id got a real property.h mapping, so the flash
state kept showing already-fixed ids forever. Now checks each loaded entry
against property.h and drops (and re-saves) any that no longer resolve to
"UNKNOWN".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both are broadcast unsolicited by the unit on Heizmodul (confirmed via the
unmapped-property tracker) alongside the properties added earlier.
BUSKONFIGURATION is untyped, wired up like GERAETEKONFIGURATION/ACCESS_EEPROM/
INITIALISIERUNG. GERAETE_ID is string-valued (Type::et_dev_id, a
major-minor device id) rather than numeric, so it needs a new
templates/wp_text_passive.yaml -- templates/wp_text.yaml minus the
queueRequest calls, mirroring how wp_generic_passive.yaml relates to
wp_generic.yaml.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
# Conflicts:
#	yaml/core.yaml
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

Morty Proxy This is a proxified and sanitized view of the page, visit original site.