Skip to content

vaillant: consolidate HW5103 configuration updates - #660

Open
Clauslarsen75 wants to merge 4 commits into
john30:masterfrom
Clauslarsen75:hmu-hw5103-combined
Open

vaillant: consolidate HW5103 configuration updates#660
Clauslarsen75 wants to merge 4 commits into
john30:masterfrom
Clauslarsen75:hmu-hw5103-combined

Conversation

@Clauslarsen75

@Clauslarsen75 Clauslarsen75 commented Sep 4, 2026

Copy link
Copy Markdown

Consolidates several pending HW5103 configuration improvements into one tested configuration. Includes the base/install configuration values and required percent2/hysteresis types from #607 (including the noise-reduction work related to #606), Status07 operating-mode decoding from #614. Tested on a real Vaillant HMU HW5103 system and compiled successfully with TypeSpec 1.12.0. PowerConsumptionHmu is already present in current master and is not modified here. Credit to @stgm, @buliwyf42, @maiksensi and the contributors/reporters on the referenced PRs and issues.

@Clauslarsen75

Copy link
Copy Markdown
Author

@john30 - all changed verified and tested with local upload

@buliwyf42

Copy link
Copy Markdown

Thank you for putting this together — having the HW5103 work in one tested place is really helpful, and the Status07 and #607 parts look good to me.

One thing I'd like to add before the Errorhistory part goes in, because I think there may be a subtlety worth checking first.

Errorhistory may be fixable rather than removable

Errorhistory has a master field index (index,m,UCH), so the request needs to carry it: NN=03, DD=01 01 <index>. The raw query quoted in #638 is 3108b503020101NN=02, without the index byte. When the request is incomplete the HMU answers with a single 00, which looks exactly like "register not implemented".

This is genuinely easy to miss, because ebusd itself produces the same picture: a message with an m field can't be polled without an argument, so any integration config that pulls Errorhistory into the poll list (filter-seen in mqtt-hassio.cfg, for example) generates the same 1-byte reply and the same invalid position in the log. I ran into that on my own system a while back and drew the same conclusion at first.

With an index supplied, my HMU (MF=Vaillant;ID=HMU00;SW=0902;HW=5103) does return full 10-byte records. Raw log, unedited:

>3108b5030301010052<000a0200091411241600ff001b>00   index 0
>3108b5030301010153<000a0243121609241600ff0071>00   index 1
>3108b5030301010250<000a0247071209241600ff00f1>00   index 2
>3108b5030301010351<000a0206122604241600000047>00   index 3
>3108b5030301010456<000a0233142504241600000030>00   index 4
>3108b503030101095b<000a010000000000ffff000092>00   index 9

Payload split as status(1) time(2) date(3) error(2) + 2 trailing:

index status time date error
0 02 0009 141124 1600
1 02 4312 160924 1600
2 02 4707 120924 1600
3 02 0612 260424 1600
4 02 3314 250424 1600
9 01 0000 000000 ffff

status=2 → entry present, status=1 → empty slot, error=0xffff → none.

What actually breaks the decode: the field types

The device sends BCD, while errorhistory in _templates.tsp uses the hex variants (scalar time2 extends VTM, scalar date extends HDA3). Checked with ebusctl decode against the bytes above:

field current type bytes result BCD type result
time VTM 4312 ERR: argument value out of valid range BTM 12:43
date HDA:3 141124 ERR: argument value out of valid range BDA:3 14.11.2024
date HDA:3 160924 22.09.2036 — no error, just wrong BDA:3 16.09.2024

The last row is the one that worries me a little: HDA:3 doesn't fail there, it returns a plausible-looking but incorrect date. error: UIN is fine (1600 → 22), and the two trailing bytes are ignored by ebusd. This holds across all seven indices I read.

So a HW5103-local override of those two field types might get the message working instead of dropping it. I'm happy to prepare that as a separate small PR against 08.hmu.HW5103.tsp if that's useful, so it doesn't hold up the rest of #660 — whatever fits your plans best.

One caveat I should be upfront about: #638 is on SW=0522 and I'm on SW=0902, and @chrizzzp already found in that same issue that PowerConsumptionHmu only exists from SW>=0901. So I can't rule out that 0522 really has no error history, and my measurements may simply not transfer. @MarkBovee, if you have a moment, would you mind re-testing with the index byte included — 3108b50303010100? That would settle it either way, and if 0522 still answers 00, removing the message for HW5103 makes complete sense to me.

One small question

BuildingCircuitFlow: the l/hL/h change is a unit rename on an existing register, so it will show up as a changed unit on already-configured Home Assistant sensors. Intentional (SI capitalisation), or incidental? Either is fine, just wanted to mention it.

Status07 / #614

Status07 here is #614 as-is — that's completely fine by me, and thank you for the credit. Just so it doesn't get merged twice, @john30: #614 and this PR now carry the same model, so whichever lands first will make the other conflict. I'm glad to close #614 if #660 is the better path forward.

@Clauslarsen75

Clauslarsen75 commented Sep 5, 2026 via email

Copy link
Copy Markdown
Author

@Clauslarsen75

Copy link
Copy Markdown
Author

Thank you for putting this together — having the HW5103 work in one tested place is really helpful, and the Status07 and #607 parts look good to me.

One thing I'd like to add before the Errorhistory part goes in, because I think there may be a subtlety worth checking first.

Errorhistory may be fixable rather than removable

Errorhistory has a master field index (index,m,UCH), so the request needs to carry it: NN=03, DD=01 01 <index>. The raw query quoted in #638 is 3108b503020101NN=02, without the index byte. When the request is incomplete the HMU answers with a single 00, which looks exactly like "register not implemented".

This is genuinely easy to miss, because ebusd itself produces the same picture: a message with an m field can't be polled without an argument, so any integration config that pulls Errorhistory into the poll list (filter-seen in mqtt-hassio.cfg, for example) generates the same 1-byte reply and the same invalid position in the log. I ran into that on my own system a while back and drew the same conclusion at first.

With an index supplied, my HMU (MF=Vaillant;ID=HMU00;SW=0902;HW=5103) does return full 10-byte records. Raw log, unedited:

>3108b5030301010052<000a0200091411241600ff001b>00   index 0
>3108b5030301010153<000a0243121609241600ff0071>00   index 1
>3108b5030301010250<000a0247071209241600ff00f1>00   index 2
>3108b5030301010351<000a0206122604241600000047>00   index 3
>3108b5030301010456<000a0233142504241600000030>00   index 4
>3108b503030101095b<000a010000000000ffff000092>00   index 9

Payload split as status(1) time(2) date(3) error(2) + 2 trailing:

index status time date error
0 02 0009 141124 1600
1 02 4312 160924 1600
2 02 4707 120924 1600
3 02 0612 260424 1600
4 02 3314 250424 1600
9 01 0000 000000 ffff
status=2 → entry present, status=1 → empty slot, error=0xffff → none.

What actually breaks the decode: the field types

The device sends BCD, while errorhistory in _templates.tsp uses the hex variants (scalar time2 extends VTM, scalar date extends HDA3). Checked with ebusctl decode against the bytes above:

field current type bytes result BCD type result
time VTM 4312 ERR: argument value out of valid range BTM 12:43
date HDA:3 141124 ERR: argument value out of valid range BDA:3 14.11.2024
date HDA:3 160924 22.09.2036 — no error, just wrong BDA:3 16.09.2024
The last row is the one that worries me a little: HDA:3 doesn't fail there, it returns a plausible-looking but incorrect date. error: UIN is fine (1600 → 22), and the two trailing bytes are ignored by ebusd. This holds across all seven indices I read.

So a HW5103-local override of those two field types might get the message working instead of dropping it. I'm happy to prepare that as a separate small PR against 08.hmu.HW5103.tsp if that's useful, so it doesn't hold up the rest of #660 — whatever fits your plans best.

One caveat I should be upfront about: #638 is on SW=0522 and I'm on SW=0902, and @chrizzzp already found in that same issue that PowerConsumptionHmu only exists from SW>=0901. So I can't rule out that 0522 really has no error history, and my measurements may simply not transfer. @MarkBovee, if you have a moment, would you mind re-testing with the index byte included — 3108b50303010100? That would settle it either way, and if 0522 still answers 00, removing the message for HW5103 makes complete sense to me.

One small question

BuildingCircuitFlow: the l/hL/h change is a unit rename on an existing register, so it will show up as a changed unit on already-configured Home Assistant sensors. Intentional (SI capitalisation), or incidental? Either is fine, just wanted to mention it.

Status07 / #614

Status07 here is #614 as-is — that's completely fine by me, and thank you for the credit. Just so it doesn't get merged twice, @john30: #614 and this PR now carry the same model, so whichever lands first will make the other conflict. I'm glad to close #614 if #660 is the better path forward.

Thanks for the detailed analysis — I tested this on my own HW5103 before replying.

My system is:

MF=Vaillant; ID=HMU00; SW=0905; HW=5103

I verified the identification directly from the bus:

b5484d55303009055103

I then tested Errorhistory with the index byte included, using the same source address as in your examples:

hex -s 31 08b50303010100
hex -s 31 08b50303010101
hex -s 31 08b50303010109

All three requests complete successfully, but return no data payload on my SW0905.

So this is interestingly different from your HW5103/SW0902, which returns the full 10-byte records with the indexed request.

That suggests Errorhistory behaviour may be software-version dependent even within HW5103, rather than purely hardware dependent.

I agree that removing Errorhistory for all HW5103 devices would therefore be too broad. It may make more sense to keep the definition and handle the supported SW range separately, if we can establish where the behaviour changes.

Regarding BuildingCircuitFlow: the l/hL/h change was intentional. The actual value and scaling are unchanged; this was only to use the Home Assistant-compatible unit spelling.

Thanks again for catching the indexed Errorhistory detail — it revealed a useful SW0902 vs SW0905 difference.

@Clauslarsen75

Clauslarsen75 commented Sep 8, 2026 via email

Copy link
Copy Markdown
Author

@Clauslarsen75

Clauslarsen75 commented Sep 8, 2026 via email

Copy link
Copy Markdown
Author

@Clauslarsen75

Copy link
Copy Markdown
Author

Additional HW5103 telemetry

The PR also adds two additional read-only values, both live-verified on:

MF=Vaillant; ID=HMU00; SW=0905; HW=5103

Air intake temperature

Adds:

AirIntakeTemp

Register:

B51A 05 FF 32 26

Live test:

31 08 B51A 05 FF 32 26

Response:

ff083e28010000000000

Decoded value:

18.5 °C

Generated CSV uses D2C with unit °C.

Cooling operating hours

Adds:

RunStatsCoolHours

Register:

B509 540200 BB 0B

Live test:

31 08 B509 540200 BB 0B

Response:

0201bb0b5b020000

Decoded value:

603 h

This complements the existing B509 runtime statistics:

  • RunStatsHMUHours (B8 0B)
  • RunStatsHcHours (B9 0B)
  • RunStatsHwcHours (BC 0B)

During verification of PR #604, the corresponding B51A Hours* values were also tested:

  • Hours = 7738 h
  • HoursHc = 4419 h
  • HoursCool = 603 h
  • HoursHwc = 879 h

Hours, HoursHc and HoursHwc were found to be exact duplicates of the existing B509 RunStats* values and were therefore not added here.

For cooling hours, the corresponding B509 register was identified as BB 0B, returning exactly the same 603 h as the B51A HoursCool value. Therefore RunStatsCoolHours was added to the existing B509 RunStats family instead of adding the duplicate B51A HoursCool message.

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.

2 participants