Skip to content

fix(heating): 13xxx and 23xxx are holiday days in heating / conditioning mode - #88

Closed
gdluck wants to merge 1 commit into
OpenWebNet-HA:masterfrom
gdluck:fix/who4-holiday-days
Closed

gdluck wants to merge 1 commit into
OpenWebNet-HA:masterfrom
gdluck:fix/who4-holiday-days

Conversation

@gdluck

@gdluck gdluck commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Requested by A · project thread

Depends on OpenWebNet-HA/MyHOME#650: MyHOME's copy of the OWNd edge tests (tests/test_message_edges.py) asserts the old auto reading for *4*13001*1## / *4*23001*1##, so this PR's downstream "MyHOME test suite" job (which runs MyHOME v2-phase1-architecture against this checkout, .github/workflows/myhome-conformance.yml:70-86) stays red until #650 is merged. OWNd's own checks are green.

Before: *4*13001*1## and *4*23001*1## were read as AUTO (both ranges sat in the generic-mode list next to 33xxx).

After: 13xxx reads as HEAT and 23xxx as COOL, and all three ranges expose the day count as holiday_days (*4*23001*1## → mode = cool, holiday_days = 1; *4*33004*#0## → auto, 4).

Evidence

Spec. p. 5 and p. 64, WHAT table: 13xxx = holiday days, heating mode; 23xxx = holiday days, conditioning mode; 33xxx = holiday days, generic mode; xxx = 1..255 days.

libqtdevices TS10_1_0_23. thermal_device.cpp:

 58: 	SUM_HOLIDAY = 23000,             // holiday operation (programma ferie)
 68: 	WIN_HOLIDAY = 13000,             // holiday operation (programma ferie)
258: 	case SUM_HOLIDAY:
259: 		values_list[DIM_PROGRAM] = program;
260: 		values_list[DIM_STATUS] = ST_HOLIDAY;
261: 		values_list[DIM_SEASON] = SE_SUMMER;
303: 	case WIN_HOLIDAY:
304: 		values_list[DIM_PROGRAM] = program;
305: 		values_list[DIM_STATUS] = ST_HOLIDAY;
306: 		values_list[DIM_SEASON] = SE_WINTER;

23xxx sets the summer season, 13xxx the winter season; the client never maps either to automatic.

Firmware. bt_termo, identical on MyHomeServer1, F454, F459, F461, F450 (results/termo*.tsv):

Frame Reply Bus body Reading
*4*13004*#0## NACK none monitor-only WHAT (Spec p. 64), not a command
*4*23004*#0## NACK none same
*4*33002#3115*#0## ACK D1 00 03 02 C1 05 02 0E holiday command: byte 7 = 02 days, byte 8 = program 15
*4*33005#3102*#0## ACK D1 00 03 02 C1 05 05 01 5 days, program 2

So the firmware carries the day count of the holiday WHATs as a real value (byte 7), and the heating / conditioning variants are status reports the central unit sends, which is what OWNd parses here.

How

OWNd/message/heating.py: 23001-23255 moves to the COOL range, 13001-13255 to the HEAT range, 33xxx stays AUTO; each sets holiday_days = mode % 1000. New holiday_days property. Tests: the two test_mode_auto_weekly_* cases in tests/test_message_edges.py encoded the old reading and are replaced by test_mode_holiday_*. pytest: 1239 passed, 1 skipped.


How to check. libqtdevices quotes are from tag TS10_1_0_23 of OpenWebNet-HA/libqtdevices (BTicino's 2010 touch-screen client, used only as a second client, not as the reference). Firmware rows are replays of the exact frame on the original gateway translator binaries (ARM, from the MyHomeServer1, F454, F459, F461 and F450 images) under QEMU on a fake SCS bus: ACK = *#*1##, NACK = *#*0##, the bus body is what the program put on the SCS bus (hex, without the A8 / checksum / A3 framing). Spec = Legrand/BTicino "Open Web Net Language, WHO = 4" v2.0.0 (2013-11-27). Raw logs, command lists, the harness and the report are in firmware_validation.zip (results/<program>[_<image>].tsv, results/*.cl / *.stub / *.mon, REPORT.md). The firmware images themselves are not included.

Split out of #86 so each change can be checked on its own; the eight slices (#87-#94) merge together in any order without conflicts, and the merged union passes 1285 tests with 100 % coverage of OWNd/message (checked locally on 2026-10-07 after the review rework of #94).

🤖 Generated with Claude Code

https://claude.ai/code/session_018oHp1P4vxxoFnaLUUZpbpZ

…ing mode

OWNd put the 13001-13255 and 23001-23255 WHATs in the AUTO range. The
Legrand WHO 4 specification v2.0.0 (p. 5 and p. 64) defines 13xxx as
"holiday days, heating mode" and 23xxx as "holiday days, conditioning
mode", next to 33xxx for the generic mode. libqtdevices TS10_1_0_23 has
WIN_HOLIDAY = 13000 and SUM_HOLIDAY = 23000 (thermal_device.cpp:68, :58)
and sets the season to winter / summer for them (:303-307, :258-262).
On the gateway firmware these WHATs are monitor-only: bt_termo answers
NACK with no bus frame to *4*13004*#0## and *4*23004*#0## on all five
images, while the holiday *commands* *4*33002#3115*#0## and
*4*33005#3102*#0## are forwarded with the day count in byte 7 (02, 05).

13xxx now reads as heat, 23xxx as cool, and all three ranges expose the
day count as holiday_days.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018oHp1P4vxxoFnaLUUZpbpZ
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@gdluck

gdluck commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #97, which carries this change verbatim together with the other WHO 4 heating fixes. Closing as agreed in OpenWebNet-HA/MyHOME#649.

@gdluck gdluck closed this Oct 7, 2026
GreenGrassBlueOcean added a commit that referenced this pull request Oct 16, 2026
…#88, #89, #94)

Consolidate the four domain-focused WHO 4 heating improvements into a single cohesive branch:
1. WHAT 1 / 0 decoded as season (MESSAGE_TYPE_SEASON: hvac_season) with typed .season
   attribute (heating / conditioning), leaving .mode as None so season updates do
   not flip active AUTO/manual operating modes (OWNd#94).
2. WHAT 115#/215#/315# parameter read as weekly program (1..16), not negative temperature,
   exposing .program and .scenario properties on OWNHeatingEvent (OWNd#87).
3. WHAT 13xxx (heating) and 23xxx (conditioning) holiday days assigned to respective
   seasonal modes rather than generic auto, exposing .holiday_days (OWNd#88).
4. WHATs 22, 23, 24, 30, and 31 recognized as central unit system status frames with
   descriptive telemetry logs, leaving mode as None (OWNd#89).

Co-authored-by: gdluck <9041273+gdluck@users.noreply.github.com>
GreenGrassBlueOcean added a commit that referenced this pull request Oct 16, 2026
…d-heating

fix(heating): correct season status, holiday programs, and CU diagnostics (#87, #88, #89, #94)
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