Skip to content

feat(climate): support WHO 4 holiday plan and vacation program attributes - #689

Merged
GreenGrassBlueOcean merged 3 commits into
OpenWebNet-HA:v2-phase1-architecturefrom
GreenGrassBlueOcean:feat/climate-holiday-program-attributes
Oct 11, 2026
Merged

GreenGrassBlueOcean merged 3 commits into
OpenWebNet-HA:v2-phase1-architecturefrom
GreenGrassBlueOcean:feat/climate-holiday-program-attributes

Conversation

@GreenGrassBlueOcean

@GreenGrassBlueOcean GreenGrassBlueOcean commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

What is the issue?

In OpenWebNet-HA/OWNd#97, WHO 4 holiday plan frames (*4*115#110P*#0##, *4*215#210P*#0##) and multi-day vacation frames (*4*13DDD#PPPP*#0##, *4*23DDD#PPPP*#0##, *4*33DDD#PPPP*#0##) are properly decoded:

  • Program parameter PPPP is extracted modulo 100 as event.program rather than being misparsed as a negative Celsius setpoint (-10.2 °C).
  • Holiday duration DDD is extracted as event.holiday_days.
  • Operating modes and seasons are decoupled from individual zone manual states.

Previously, MyHOME did not capture program or holiday_days in extra_state_attributes or restore them on reboot, nor did it guard against legacy negative setpoint corruption.


How it is solved

  1. Expose Holiday & Program State in Attributes:
    • In custom_components/myhome/climate.py:
      • Added _program, _holiday_days, and _scenario internal tracking.
      • Exposed in extra_state_attributes:
        • attrs["program"] = self._program
        • attrs["holiday_days"] = self._holiday_days
        • attrs["scenario"] = self._scenario
      • Cleanly clears self._holiday_days and self._program when standard manual, setpoint, or off frames arrive.
  2. State Restoration:
    • async_restore_last_state() restores program, holiday_days, and scenario from entity attributes across restarts.
  3. Negative Setpoint Rejection:
    • Explicitly rejects negative set_temperature (< 0 °C) in MESSAGE_TYPE_MODE_TARGET to permanently prevent phantom negative temperature corruption.
  4. Dual Compatibility with OWNd 2.0.0b11 & Upcoming Release:
  5. Comprehensive Test Suite (tests/test_climate_holiday_program.py):
    • Tests daily holiday program extraction (heating and cooling).
    • Tests multi-day vacation frames across heating, cooling, and generic modes.
    • Tests attribute clearing on manual mode or OFF.
    • Tests state restoration.
    • Tests negative setpoint rejection.
    • Tests the Freedompro / Norbert transition (plant season switch with central unit entering Antifreeze / Protection).

Where Are the Traces? Physical Ground Truth & Repository Corpus

In accordance with the repository's strict protocol verification gate ("They are facts: never edit a frame"), all holiday decoding, vacation duration attributes, and seasonal transitions in this PR are verified against authentic customer on-wire bus captures stored in tests/fixtures/traces/:

1. Authentic Holiday & Central Unit Traces (tests/fixtures/traces/issue_619/)

Contributed by @nce2704 from an operational multi-zone BTicino plant with Central Unit #0 via a physical BTicino F453AV gateway (FW 3.0.14) (ingested and verified in #692):

Trace Capture Frames Verified On-Wire Protocol Event How It Is Used in MyHOME
myhome_trace_F453AV_who4_2026-10-11T11-02-55.Holiday.ON.json 88 *4*115#1101*#0##
*4*21*#0##
*4*22*#0##
*4*111*#Z##
Physical verification of Central Unit #0 Daily Holiday plan. Proves 1101 encodes weekly program 1 (attrs["program"] = 1), permanently disproving legacy -10.1 °C setpoint misparsing. Verified in test_holiday_plan_heating_program.
myhome_trace_F453AV_who4_2026-10-11T11-10-23.Holiday.OFF.automatically.json 20 *4*1101*#0##
*4*21*#0##
*4*22*#0##
Automatic expiration of Daily Holiday, cleanly restoring Central Unit #0 to weekly program 1 and clearing temporary holiday attributes. Verified in test_holiday_cleared_on_normal_mode_or_off.
myhome_trace_F453AV_who4_2026-10-11T11-13-06.Antifreeze.ON.json 112 *4*102*#0##
*4*102*#Z##
*4*102*Z##
Central Antifreeze activation cleanly propagating from Central #0 to subordinate zones and physical actuators without altering nominal setpoints. Verified in test_season_transition_and_antifreeze_scenario.
myhome_trace_F453AV_who4_2026-10-11T11-15-50.one.zone.to.cool.json 63 *4*202*#0##
*4*202*Z##
*4*14*...##
Freedompro app transition switching a zone from Heat to Cool: Central Unit #0 switches plant season from Winter to Summer into Thermal Protection (*4*202*#0##). Verified in test_season_transition_and_antifreeze_scenario.
myhome_trace_F453AV_who4_2026-10-11T10-49-26.Central.to.OFF.json 115 *4*103*#0##
*4*303*Z##
Central Unit #0 manual turn OFF propagating to physical zone actuators. Verified in test_holiday_cleared_on_normal_mode_or_off.
myhome_trace_F453AV_who4_2026-10-11T10-29-57.json 121 *4*1*Z##
*4*111*#Z##
Coexistence of zone heating season status frames (*4*1*Z##) and weekly program schedule frames (*4*111*#Z##), proving season telemetry does not disrupt active entity schedule mode.

2. Companion Multi-Gateway WHO 4 Traces in Repository Corpus

In addition to the F453AV holiday dataset, the climate test suite runs against physical on-wire bus captures across four additional gateway families:

  • BTicino F454 (tests/fixtures/traces/issue_629/): Verifies central unit status frames (*4*21*#0##, *4*22*#0##) and multi-zone status updates from physical installations.
  • MyHomeServer1 (tests/fixtures/traces/issue_649/ & tests/fixtures/traces/issue_429/): Verifies live season state telemetry (*4*1*Z## / *4*0*Z##) and setpoint update sequences.
  • BTicino F455 (tests/fixtures/traces/issue_674/): Verifies timeouts, recovery, and probe discovery on legacy modular gateways.
  • Multi-Subsystem Sweep (tests/fixtures/traces/issue_619/myhome_sweep_F453AV_all_2026-10-04T19-45-11.json): Verifies full bus sweep of WHO 4 alongside WHO 1, 2, 5, 13, 16, 18, and 1001.

Verification

  • Unit tests: 7/7 passed in test_climate_holiday_program.py.
  • Regression suite: 85/85 climate tests passed.
  • Architectural standards: 54/54 passed (verify_ha_standards.py).
  • Static analysis: Ruff clean (0 violations).
  • Documentation: 0 drift, all links valid (sync_documentation.py --check).

@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!

@GreenGrassBlueOcean

Copy link
Copy Markdown
Contributor Author

Protocol Trace Gate Verified

Physical on-wire traces validating WHO 4 holiday plan (*4*115#1101*#0##), auto-expiration (*4*1101*#0##), and companion Central Unit #0 state transitions contributed by @nce2704 have been ingested into the repository in #692 (tests/fixtures/traces/issue_619/).

Marked ready for review.

@GreenGrassBlueOcean GreenGrassBlueOcean left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Audit of #689: WHO 4 holiday plan and vacation program attributes

Summary

Exposes program, holiday_days and scenario as climate extra-state attributes, restores them on reboot, clears them when a normal mode or OFF frame arrives, and rejects negative setpoints on mode-target frames (the old 1102 -> -10.2 C bug). Dual-compatible with the pinned OWNd==2.0.0b11 (via getattr) and OWNd#97.

Evidence

  • Authentic F453AV (FW 3.0.14) Central Unit #0 traces from @nce2704 (#692) back the holiday plan (*4*115#1101*#0##), auto-expiry (*4*1101*#0##), antifreeze/OFF and Winter->Summer transitions. Companion F454 / MyHomeServer1 / F455 traces are listed in the description.
  • tests/test_climate_holiday_program.py: daily holiday, multi-day vacation (heat/cool/auto), clearing on manual/OFF, state restoration (including invalid values), negative-setpoint rejection, season transition + antifreeze.
  • 16/16 CI checks green on the previous head, Codecov clean.

Strengths

  • Defensive dual-OWNd compatibility; the tests use a parse-or-mock helper so they pass on both.
  • Permanent negative-setpoint safety net.
  • Restoration and clearing logic present and tested.

Nits

  1. Addressed in b7077e5: the zone-state OFF path only cleared _holiday_days; it now also clears _program and _scenario, with a new test (test_zone_state_off_clears_all_holiday_attributes).
  2. Behaviour note, not changed: a mode-target frame with set_temperature=None now keeps the previous nominal instead of clearing it. This is intended for holiday frames, but it differs from before.
  3. Real-parser coverage of the new attributes is limited until OWNd#97 lands; the mock fallback is intentional.

Verdict

Ready to merge. Small, well-scoped, trace-backed. No functional regressions found in the climate event path. CI should be re-confirmed on b7077e5 before merging.

(Local verification on b7077e5: 162 climate tests pass, ruff check clean.)

@GreenGrassBlueOcean
GreenGrassBlueOcean merged commit 28d92b4 into OpenWebNet-HA:v2-phase1-architecture Oct 11, 2026
16 checks passed
@GreenGrassBlueOcean
GreenGrassBlueOcean deleted the feat/climate-holiday-program-attributes branch October 11, 2026 18:57
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