Skip to content

Add support for WPE-I (brine/water, no DHW) - #367

Open
adrai wants to merge 2 commits into
kr0ner:masterfrom
adrai:wpe-i-support
Open

adrai wants to merge 2 commits into
kr0ner:masterfrom
adrai:wpe-i-support

Conversation

@adrai

@adrai adrai commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Closes the WPE-I part of #363. Everything below is panel verified on a WPE-I 08 HK 230 Premium (video and photo evidence available on request). Depends on #366 for the wxx_base.yaml layer.

What the WPE-I shares with the WPL models, all matching the panel exactly: water and refrigerant temperatures, HK1/HK2 setpoints and heat curves, energy counters (16.829 MWh), efficiency (6.34), VERDICHTER_STARTS (2209) and the low byte Betriebsart map. So WPE_I joins the existing property groups, and shared properties live in shared sections:

  • WAERMEERTRAG_2WE_HEIZ_SUM_KWH/MWH moved to the common block, they are served by every family
  • WP_WASSERVOLUMENSTROM, REGELABWEICHUNG and LAUFZEIT_VD_HEIZEN moved to a shared WPE_I || WPL_17 section
  • LAUFZEIT_NHZ1, NHZ2 and NHZ1_2 moved to a shared WPE_I || WPL_17 || WPL_23 section

What is specific to the WPE-I (yaml/wpe-i.yaml, -DWPE_I):

  • No integrated DHW, so the variant includes wxx_base.yaml rather than wpl_base.yaml
  • 0x02e2 is WP_WASSERVOLUMENSTROM as on the WPL17, not the WPL13 status word. It tracks the circulation flow (raw 280/285 = 28.0/28.5 l/min next to VOLUMENSTROM 27.7), and the panel's Prozessdaten page shows the same value.
  • Betriebsart is sent as a low byte (raw 0x02 captured while the panel showed Programmbetrieb), so WPE_I does not apply the WPL_13 shift. The select is verified for read and write: switching the mode from the ESP round trips, the pump broadcasts the new value and the panel follows.
  • Own status words, identified with a controlled standby experiment and the panel photographed in each state. WAERMEPUMPEN_STATUS (0x4eda) with bit 4 = passive cooling active, and the plant status arriving as a broadcast towards the room unit with bit 2 = Heizkreispumpe 2. Both words are exposed as raw diagnostic sensors and only the verified bits become binary sensors, so the remaining bits can be identified from recorded history.
  • Runtime counters, panel exact: LAUFZEIT_VD_HEIZEN 6327 h and LAUFZEIT_NHZ1/NHZ2/NHZ1_2 0/0/4 h. LAUFZEIT_VD_KUEHLEN answers 0x8000 because the WPE-I only cools passively, so it is not exposed.
  • Invalid ranges are clamped rather than decoded centrally, as suggested in Decode Elster sentinel values as unavailable instead of garbage numbers #364: MINTEMP/MAXTEMP (HK2) and REGELABWEICHUNG use clamp with ignore_out_of_range, so the marker words the WPM sends for "AUS" (0x9000) and "not available" (0x8000) leave the entity unavailable instead of publishing an impossible value.
  • Room values note: the physical FET2 display values are not addressable via the standard indices, so the RAUM* entities show the active room reference, which is the intended behaviour of the FET emulation.

Tested on a WPE-I 08 HK 230 Premium with an ESP32-C6-Zero (esp32_can), ESPHome 2026.6.5, running in production since 2026-07-09. Since the property.h move also touches the THZ sections, I config validated all nine model manifests and compiled wpe-i, wpl17, wpl23, thz504 and thz304.

@github-actions

Copy link
Copy Markdown

Hello! This is an automated message regarding your pull request. We've noticed that this PR has been inactive for a while, with no updates or activity in the last 30 days. If no further updates or responses are provided within the next 7 days, this pull request will be closed as stale. If you're still actively working on this PR, please leave a comment to let us know. We're happy to keep it open and review your changes. Otherwise, feel free to reopen the PR if you have more work to contribute in the future. Thank you for your understanding and contributions!

@github-actions github-actions Bot added the Stale label Aug 18, 2026
@adrai

adrai commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

not stale

@kr0ner kr0ner removed the Stale label Aug 18, 2026
@github-actions

Copy link
Copy Markdown

Hello! This is an automated message regarding your pull request. We've noticed that this PR has been inactive for a while, with no updates or activity in the last 30 days. If no further updates or responses are provided within the next 7 days, this pull request will be closed as stale. If you're still actively working on this PR, please leave a comment to let us know. We're happy to keep it open and review your changes. Otherwise, feel free to reopen the PR if you have more work to contribute in the future. Thank you for your understanding and contributions!

@github-actions github-actions Bot added the Stale label Sep 17, 2026
@adrai

adrai commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

no, please don't close this....

@kr0ner kr0ner removed the Stale label Sep 17, 2026
Comment thread components/wp_core/property.h Outdated
// 0x02e2 carries the water volume flow here, as on the WPL17 — NOT the
// WPL13 status word (observed raw 280/285 = 28.0/28.5 l/min while idle
// in passive cooling, matching VOLUMENSTROM 0x4f47 = 27.7 l/min)
PROPERTY(WP_WASSERVOLUMENSTROM, 0x02e2, Type::et_dec_val);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this duplicates the value,please create a new section that is valid for WPE_I and WPL17 and move the common parts there.

Comment thread components/wp_core/property.h Outdated
Comment on lines +372 to +375
PROPERTY(LAUFZEIT_VD_HEIZEN, 0x4efb);
PROPERTY(LAUFZEIT_NHZ1, 0x0259);
PROPERTY(LAUFZEIT_NHZ2, 0x025a);
PROPERTY(LAUFZEIT_NHZ1_2, 0x0805);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this duplicates the value,please create a new section that is valid for WPE_I, WPL17 and WPL23 and move the common parts there.

Comment thread components/wp_core/property.h Outdated
Comment on lines +369 to +370
PROPERTY(WAERMEERTRAG_2WE_HEIZ_SUM_KWH, 0x0928);
PROPERTY(WAERMEERTRAG_2WE_HEIZ_SUM_MWH, 0x0929, Type::et_double_val);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be common for all heatpumps

address kr0ner#363

The WPM family is not limited to the WPL models. The WPE-I speaks the
same protocol but has no integrated DHW, and its Manager does not serve
the BETRIEBS_STATUS word (verified on a WPE-I 08 HK 230 Premium, where
the panel showed Heizkreispumpe 2 running while all twelve binaries
stayed off).

Split wpl_base.yaml the same way txx_base.yaml and thz_base.yaml are
layered:
- wxx_base.yaml carries everything common to WPL and WPE
- wpl_base.yaml includes it and adds the WPL specific parts, namely the
  Manager BETRIEBS_STATUS binaries and the four DHW energy counters

No behavior change for wpl13, wpl17 and wpl23: they keep including
wpl_base.yaml and end up with exactly the same entities as before.
@adrai

adrai commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review, all three points addressed. WAERMEERTRAG_2WE_HEIZ_SUM_KWH/MWH moved to the common block, WP_WASSERVOLUMENSTROM, REGELABWEICHUNG and LAUFZEIT_VD_HEIZEN into a shared WPE_I/WPL_17 section, and LAUFZEIT_NHZ1/NHZ2/NHZ1_2 into a shared WPE_I/WPL_17/WPL_23 section, so the WPE_I block only holds what is really specific to it.

The variant now builds on the new wxx_base.yaml from #366, the sentinel decoding from #364 is gone in favour of the clamp filters you proposed there, and everything is squashed into one commit.

Since the property.h move also touches the THZ sections I built wpe-i, wpl17, wpl23, thz504 and thz304 locally against 2026.6.5 and config validated all nine models.

@adrai
adrai marked this pull request as ready for review September 17, 2026 19:52
Copilot AI lite review requested due to automatic review settings September 17, 2026 19:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The WPE-I status callback can leave PASSIVKUEHLUNG_AKTIV in a stale/undefined state when the standby word (0x8000) is received, which can produce incorrect HA state.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR adds a new ESPHome configuration variant for Stiebel Eltron WPE-I (brine/water, no integrated DHW) and refactors shared WPL/WPE YAML into a new common base to reduce duplication and enable WPE-I to reuse the established WPL entity set.

Changes:

  • Introduces yaml/wpe-i.yaml variant with -DWPE_I, adding WPE-I-specific sensors/callback decoding and omitting DHW packages.
  • Refactors shared WPL YAML into a new yaml/wxx_base.yaml, and updates yaml/wpl_base.yaml to consume it.
  • Extends the C++ property and mapper definitions to include WPE-I properties and Betriebsart mapping.
File summaries
File Description
yaml/wxx_base.yaml New shared base YAML for WXX/WPL/WPE common entities, CAN setup, and core packages.
yaml/wpl_base.yaml Refactored to include wxx_base.yaml and keep only WPL-specific plant status + DHW packages.
yaml/wpe-i.yaml New WPE-I variant config with build flag, status word callbacks, and WPE-I-specific sensors.
components/wp_core/property.h Adds WPE-I properties and adjusts property-group conditionals to include WPE-I.
components/wp_core/mapper.cpp Includes WPE_I in Betriebsart mapping selection.
README.md Updates the architecture diagram to reflect the new wxx_base.yaml layer.
esp32-standalone.yaml Adds (commented) include option for yaml/wpe-i.yaml.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread yaml/wpe-i.yaml
address kr0ner#363

Panel verified against a WPE-I 08 HK 230 Premium: the WPE-I speaks the
same WPM protocol as the WPL models (temperatures, setpoints, heat
curves, energy counters, VERDICHTER_STARTS and efficiency all match the
panel exactly), so the variant builds on wxx_base.yaml and WPE_I joins
the existing property groups.

Properties it shares with other models live in common sections instead
of being repeated:
- WAERMEERTRAG_2WE_HEIZ_SUM_KWH/MWH move to the common block, they are
  served by every family
- WP_WASSERVOLUMENSTROM, REGELABWEICHUNG and LAUFZEIT_VD_HEIZEN move to
  a shared WPE_I/WPL_17 section
- LAUFZEIT_NHZ1, NHZ2 and NHZ1_2 move to a shared WPE_I/WPL_17/WPL_23
  section

What is specific to the WPE-I:
- no integrated DHW, so it includes wxx_base.yaml rather than
  wpl_base.yaml
- 0x02e2 is the water volume flow as on the WPL17, not the WPL13
  WAERMEPUMPEN_STATUS word (raw 280/285 = 28.0/28.5 l/min next to
  VOLUMENSTROM = 27.7 l/min). The WPE-I reports its own status on 0x4eda
  (bit 4 = passive cooling active, verified by switching the pump to
  standby and watching the valve follow) and the plant status arrives as
  a broadcast towards the room unit, so both words are exposed as raw
  sensors and only the verified bits become binary sensors.
- runtime counters, panel exact: LAUFZEIT_VD_HEIZEN 6327 h and
  LAUFZEIT_NHZ1/NHZ2/NHZ1_2 0/0/4 h. LAUFZEIT_VD_KUEHLEN answers 0x8000
  because the WPE-I only cools passively, so it is not exposed.
- MINTEMP/MAXTEMP (HK2) and REGELABWEICHUNG are clamped to their valid
  range with ignore_out_of_range, so the marker words the WPM sends for
  "AUS" (0x9000) and "not available" (0x8000) leave the entity
  unavailable instead of publishing an impossible value

Unlike WPL_13 builds, WPE_I does not shift the Betriebsart raw value by
8 bits: the WPE-I sends PROGRAMMSCHALTER (0x4f1b) as a low byte (raw
0x02 = Programm, verified while the panel showed PROGRAMMBETRIEB).
@adrai

adrai commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Good catch from the bot: the callback skipped publishing when the standby word (0x8000) arrives, so PASSIVKUEHLUNG_AKTIV would keep its previous value while the pump sits in standby. It now publishes false in that case, which also matches what the panel shows: the valve goes back to the heating position when the pump parks. Pushed.

@adrai
adrai requested a review from kr0ner September 17, 2026 20:14
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.

3 participants