Skip to content

fix(climate): eliminate 10s command session timeouts on F455 and add authentic trace fixture (#674) - #675

Merged
GreenGrassBlueOcean merged 1 commit into
v2-phase1-architecturefrom
test/issue-674-f455-climate-trace
Oct 9, 2026
Merged

GreenGrassBlueOcean merged 1 commit into
v2-phase1-architecturefrom
test/issue-674-f455-climate-trace

Conversation

@GreenGrassBlueOcean

@GreenGrassBlueOcean GreenGrassBlueOcean commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Eliminates 10-second command session timeouts and queue lockups on physical SCS gateways (Legrand F455, F454, MH200N, MH202, etc.) during climate entity startup/polling, and locks in the authentic 16-zone F455 physical plant trace fixture and replay test suite contributed by @gdluck on #674.


1. What is the problem?

When installing or starting up MyHOME v2 on plants connected through physical SCS gateways (such as the Legrand F455 in #674), Home Assistant experiences severe startup stalls and command session timeouts every few seconds (~161 seconds of total lockup for a 16-zone plant):

  1. Unanswerable Point-to-Point Zone Status Requests (*#4*Z##):
    • In standard OpenWebNet WHO 4 (WHO_4 2.pdf), dimension-less status requests *#4*WHERE## are only defined for WHERE = 0 (general plant sweep) and WHERE = #0 (99-zone central unit).
    • Individual zone status requests *#4*Z## (zones 1..99) are not part of the standard SCS bus protocol. Physical thermostats (LN4691, 3550, etc.) on the SCS bus have no telegram handler for dimension-less *#4*Z##.
  2. Gateway Architecture Asymmetry:
    • Physical bridge gateways (F455, F454, MH200N, MH202) forward incoming command frames directly to the physical SCS bus. Because the bus is silent, the gateway sends no response back to Home Assistant.
    • In contrast, MyHomeServer1 (Linux-based server analyzed in #649) runs the bt_luci software daemon which intercepts *#4*Z## in software and replies directly from its internal SQLite/RAM cache.
  3. Serial Command Session Timeout Cascades:
    • message_has_state() unconditionally marked climate entities as requiring polling (_poll_on_add = True), causing all 16 zones to issue *#4*Z## queries sequentially via async_update().
    • OWNd command session waited COMMAND_TIMEOUT = 10 seconds per request before timing out:
      WARNING (MainThread) [custom_components.myhome] [F455 gateway - 192.168.1.136] Timed out awaiting the complete response for '*#4*35##'; command session closed.
    • OWNd disconnected the TCP socket, reconnected, performed HMAC-SHA256 authentication, and popped the next zone request.
    • For 16 zones: 16 × 10.08 s = ~161.3 seconds (~2.7 minutes) of serial timeouts locking up the primary command session, blocking any lighting or cover commands queued behind it.
  4. Redundant Polling:
    • The initial startup sweep *#4*0## already caused physical thermostats to spontaneously broadcast their full state (dimensions 0, 12, 13, 14, 19, 20) on the monitor session. The point-to-point queries were completely redundant.

2. How is it solved?

  1. Gateway Capability Detection (custom_components/myhome/gateway.py):
    • Added supports_zone_status property on MyHOMEGatewayHandler.
    • Returns False for physical SCS bridge gateways (F455, F454, MH200, MH201, MH202, F452, F453, F458, F459, F461, H4684).
    • Returns True for MyHomeServer1 (which provides software cache synthesis) and mock gateways.
  2. Suppress Point-to-Point Queries on Physical Gateways (custom_components/myhome/climate.py):
    • During __init__, sets self._poll_on_add = False if not self._central and not self._gateway_supports_zone_status.
    • In async_update(), returns immediately without querying *#4*Z## when connected to physical gateways.
  3. Discovery & Event Dispatcher Alignment:
    • custom_components/myhome/discovery.py: In message_has_state(), marks climate entities as having received state if not entity._gateway_supports_zone_status, preventing forced poll-on-add.
    • custom_components/myhome/gateway_events.py: Guards OWNHCmd.status(where) on dimension 14 with supports_zone_status check.

3. How is it tested?

  1. Deterministic Replay Test Suite (tests/test_issue_674_f455_climate_trace.py):
    • test_f455_climate_trace_replay_without_exceptions: Replays all 67 on-wire frames through the gateway dispatcher into Home Assistant without errors or unhandled exceptions.
    • test_f455_climate_entities_state_derived: Verifies all 16 climate zones are correctly populated from spontaneous monitor frames (temperatures, setpoints, offsets, HVAC modes, actuator states).
    • test_gateway_supports_zone_status_capability: Verifies physical gateways return supports_zone_status == False and MyHomeServer1 / mock return True.
    • test_climate_skips_zone_status_poll_on_physical_gateways: Verifies _poll_on_add = False and async_update() does not dispatch unanswerable *#4*Z## commands on physical gateways.
  2. Privacy & Hygiene Gates:
    • tests/test_fixture_privacy.py: PASSED (0 LAN address leaks; sanitized to RFC 5737 documentation prefix 192.0.2.136).
    • tests/test_device_health_corpus.py: PASSED (conforms to float epoch timestamps and trace schema).
  3. Quality & Standard Gates:
    • All 203 unit and integration tests passing in WSL Ubuntu (~/.venvs/myhome314/bin/python).
    • Ruff linting: 0 violations (ruff check custom_components tests scripts).
    • Architectural validator (scripts/verify_ha_standards.py): 54/54 rules satisfied (Bronze, Silver, Gold, Platinum).
    • Anti-drift sentinel (scripts/sync_documentation.py --check): Clean documentation sync.

4. Where are the traces?

  1. Authentic Raw Log:
    • tests/fixtures/traces/issue_674/home-assistant_2026-10-09T17-34-15.609Z.log: Verbatim 315-line Home Assistant log contributed by @gdluck on #674.
  2. Structured Trace Archive:
    • tests/fixtures/traces/issue_674/myhome_trace_f455_climate_timeouts_2026-10-09.json: Structured archive containing all 67 RX OpenWebNet frames and 16 timeout records with float epoch timestamps, ISO timestamps, and parsed message types.
  3. Documentation & Hardware Profile:
    • tests/fixtures/traces/issue_674/README.md: Complete hardware profile (Legrand F455, FW 1.1.2, 16 heating zones, no central unit #0), chronology of 16 timeouts, side-by-side comparison with MyHomeServer1, and root cause breakdown.

Co-authored-by: gdluck 9041273+gdluck@users.noreply.github.com

@GreenGrassBlueOcean
GreenGrassBlueOcean force-pushed the test/issue-674-f455-climate-trace branch from d8ea9be to 31adc99 Compare October 9, 2026 18:19
…ical gateways (#674)

In OpenWebNet WHO=4, dimension-less status requests (*#4*Z##) are only supported on MyHomeServer1 (which caches state in software). On physical SCS gateways (F455, F454, MH200N, MH202, etc.), *#4*Z## is forwarded directly to the SCS bus, where physical thermostats have no handler for it, causing a 10.08-second command session timeout per zone (accumulating over 160 seconds of queue lockup across 16 zones).

- Skip *#4*Z## polls on physical gateways in MyHOMEClimate.async_update()

- Disable _poll_on_add for physical gateways during startup/discovery

- Avoid firing *#4*Z## status requests upon receiving dimension 14 frames on physical gateways

- Add authentic F455 16-zone trace fixture and replay conformance test suite

Co-authored-by: gdluck <16568285+gdluck@users.noreply.github.com>
@GreenGrassBlueOcean
GreenGrassBlueOcean force-pushed the test/issue-674-f455-climate-trace branch from 31adc99 to ec1bd8b Compare October 9, 2026 18:37
@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
GreenGrassBlueOcean merged commit e26ac7e into v2-phase1-architecture Oct 9, 2026
16 checks passed
@GreenGrassBlueOcean
GreenGrassBlueOcean deleted the test/issue-674-f455-climate-trace branch October 9, 2026 19:56
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