Skip to content

feat(cenplus): support WHO 25 Scenario Plus commands and events - #671

Merged
GreenGrassBlueOcean merged 7 commits into
OpenWebNet-HA:v2-phase1-architecturefrom
GreenGrassBlueOcean:feat/who25-scenario-plus
Oct 9, 2026
Merged

GreenGrassBlueOcean merged 7 commits into
OpenWebNet-HA:v2-phase1-architecturefrom
GreenGrassBlueOcean:feat/who25-scenario-plus

Conversation

@GreenGrassBlueOcean

@GreenGrassBlueOcean GreenGrassBlueOcean commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Note

PHYSICAL TRACE VERIFIED: Unblocked by authentic physical plant trace contributed by @TheDarkWizard in #466 (comment 6085724930) and added in PR #673.

Summary

Companion PR to OpenWebNet-HA/OWNd#91.

Implements support for WHO 25 Scenario Plus commands and events (WHAT 11–15: on, off, increase, decrease, stop), consuming OWNScenarioPlusEvent for bus event dispatching and device registry auto-registration, and exposing the myhome.send_scenario_plus_command service.


1. What is the problem?

In Legrand / BTicino MyHOME installations, WHO 25 is primarily known for CEN+ button push/release/held actions (WHAT 21..28) and dry contact / IR events (WHAT 31..32). However, scenario programmers and touch screens (such as the MH200, MH200N, MH202, MyHomeServer1, and 10" / 3.5" Touch Screens running Legrand's libqtdevices TS10 firmware) also utilize WHO 25 for Scheduled Scenario PLUS control:

  • WHAT = 11#0 (turn_on)
  • WHAT = 12 (turn_off)
  • WHAT = 13#0#5 (increase)
  • WHAT = 14#0#5 (decrease)
  • WHAT = 15 (stop)

Prior to OpenWebNet-HA/OWNd#91, these frames were parsed as generic bare OWNEvent or OWNCommand frames without type information, action parsing, or factory builders.

In MyHOME, there was no integration-level support to:

  1. Receive incoming Scenario Plus events from the bus (OWNScenarioPlusEvent), dispatch them to Home Assistant's event bus, and automatically discover/register the scenario device in the Home Assistant Device Registry.
  2. Send scenario plus control frames (on, off, increase, decrease, stop) to an addressed scenario plus unit on the SCS bus.

2. How is it solved?

  1. Event Dispatching & Auto-Registration (custom_components/myhome/gateway_events.py):

    • Added an event handler for OWNScenarioPlusEvent in MyHOMEGatewayEvents.handle_raw_event().
    • Fires myhome_scenario_plus_event on hass.bus and via per-gateway dispatcher myhome_scenario_plus_event_<MAC> with payload containing object, action, where, gateway_mac, and entry_id.
    • Invokes self.handler._ensure_cen_device(25, raw_obj) to auto-register the scenario plus unit under its gateway in the Home Assistant Device Registry as a CEN+ Scenario Control.
    • Includes graceful backward compatibility fallback if running against older OWNd builds.
  2. Custom Service myhome.send_scenario_plus_command (custom_components/myhome/services.py):

    • Exposes myhome.send_scenario_plus_command with required parameters where and action (on, off, increase, decrease, stop) and optional gateway (targeting specific gateway MAC or defaulting to primary).
    • Uses OWNScenarioPlusCommand classmethods (turn_on, turn_off, increase, decrease, stop) with clean string fallback to safely construct and transmit the OpenWebNet frames.
    • Fully registered in custom_components/myhome/services.yaml with selectors, UI labels, and descriptions in custom_components/myhome/strings.json and translations/en.json.
  3. Documentation Alignment & Anti-Drift:

    • Added section 12 in docs/configuration/services.md with descriptions, parameter tables, and YAML automations examples.
    • Updated docs/configuration/cen_cenplus.md protocol table to include Scenario Plus frame syntax.
    • Synchronized documentation verified with zero anti-drift (scripts/sync_documentation.py --check).

3. How is it tested?

  1. Service Unit Testing (tests/test_services.py):

    • test_send_scenario_plus_command_service: Validates sending all 5 actions (on -> *25*11#0*11##, off -> *25*12*11##, increase -> *25*13#0#5*11##, decrease -> *25*14#0#5*11##, stop -> *25*15*11##), invalid action rejection, missing gateway fallback, and missing where validation.
  2. Gateway Event & Auto-Registration Testing (tests/test_gateway.py):

    • test_gateway_scenarioplus_event_and_auto_registration: Validates listening loop receiving OWNScenarioPlusEvent, firing myhome_scenario_plus_event with expected payload, and auto-registering the scenario device with device registry identifiers (DOMAIN, f"{mac}-25-{where}") attached via gateway device ID.
  3. Full Quality Verification:

    • Unit test suite: 66/66 tests in test_services.py and test_gateway.py passing cleanly.
    • HA Platinum Architecture Validator: 54/54 rules satisfied (scripts/verify_ha_standards.py).
    • Ruff linting: 0 violations across custom_components, tests, docs.
    • Anti-drift sentinel: 0 drift detected across all services, platforms, and markdown links (scripts/sync_documentation.py --check).

4. Where are the traces?

  1. Authentic Physical Plant Trace Captured & Verified in PR test(trace): add authentic MyHomeServer1 WHO 25 scenario plus trace and replay test (#466) #673:

    • Contributed by @TheDarkWizard on issue #466 (comment 6085724930) from a physical BTicino MyHomeServer1 (FW 2.87.13).
    • In-tree trace PR: OpenWebNet-HA/MyHOME#673 (tests/fixtures/traces/issue_466/config_entry-myhome_MyHomeServer1_who25_scenario_plus.json).
    • Replay test: tests/test_issue_466_myhomeserver1_scenarioplus_trace.py (500/500 frames replayed through Home Assistant event dispatcher without exceptions).
  2. On-Wire Evidence:

    • Command transmitted: [tx] *25*11#0*11## (2026-10-09T17:14:12.215385+00:00) sent via myhome.send_message.
    • Monitor echo: [rx] *25*11#0*11## (2026-10-09T17:14:12.298174+00:00) received on the OpenWebNet monitor session 82.8 ms later.
    • Proves conclusively on physical hardware that MyHomeServer1 accepts *25*11#0*11##, puts opcode B1 01 93 00 on the physical SCS bus, and echoes it back to OpenWebNet monitoring sessions.
    • Also confirms OFF syntax: [tx] *25*12#0*11## was not echoed because OFF takes no #0 parameter (*25*12*WHERE##), matching the exact grammar implemented in OWNd#91.
  3. Theoretical / Protocol Background:

    • Legrand libqtdevices tag TS10_1_0_23 (scenario_device.cpp:36-41):
      #define CMD_SCENARIO_PLUS_ON   "11#0"
      #define CMD_SCENARIO_PLUS_OFF  "12"
      #define CMD_SCENARIO_PLUS_INC  "13#0#5"
      #define CMD_SCENARIO_PLUS_DEC  "14#0#5"
      #define CMD_SCENARIO_PLUS_STOP "15"
    • Firmware binaries under own-firmware-oracle (MH202 010024, MHS1 028206) confirm translator mapping to SCS opcodes 93–97.

@GreenGrassBlueOcean GreenGrassBlueOcean changed the title feat(cenplus): support WHO 25 Scenario Plus commands and events (OWNd#91) feat(cenplus): support WHO 25 Scenario Plus commands and events (blocked on physical trace) Oct 9, 2026
@GreenGrassBlueOcean GreenGrassBlueOcean changed the title feat(cenplus): support WHO 25 Scenario Plus commands and events (blocked on physical trace) feat(cenplus): support WHO 25 Scenario Plus commands and events Oct 9, 2026
@GreenGrassBlueOcean

Copy link
Copy Markdown
Contributor Author

📡 Physical Plant Trace Captured & Verified — PR #671 Unblocked! 🎉

We are pleased to report that the required real-world hardware verification has been contributed and integrated into our test corpus:

  • Source: Contributed by @TheDarkWizard on issue #466 (comment 6085724930) from a physical BTicino MyHomeServer1 (FW 2.87.13).
  • Trace PR: Added to the repository in companion PR OpenWebNet-HA/MyHOME#673 (tests/fixtures/traces/issue_466/config_entry-myhome_MyHomeServer1_who25_scenario_plus.json).
  • Deterministic Replay Test: Added tests/test_issue_466_myhomeserver1_scenarioplus_trace.py replaying all 500 on-wire frames without exceptions and asserting WHO 25 scenario plus handling.

Evidence Breakdown:

  • Command: [tx] *25*11#0*11## (2026-10-09T17:14:12.215385+00:00) sent via myhome.send_message.
  • Bus Echo: [rx] *25*11#0*11## (2026-10-09T17:14:12.298174+00:00) received on the OpenWebNet monitor session 82.8 ms later.
  • Physical Proof: Confirms gateway acceptance, translation to SCS bus opcode B1 01 93 00, and broadcast event echo.

With the authentic physical trace permanently locked in CI and all architectural validators satisfied, this PR is now fully unblocked! 🚀

GreenGrassBlueOcean added a commit that referenced this pull request Oct 9, 2026
…nd replay test (#466)

Captured from a physical BTicino MyHomeServer1 gateway (FW 2.87.13) by @TheDarkWizard on 2026-10-09 in response to the community call for real-world WHO 25 scenario plus traces (#466).

Validates gateway acceptance, SCS bus relay, and OpenWebNet monitor echo of Scheduled Scenario PLUS frame *25*11#0*11## (~82.8 ms RTT), unblocking OpenWebNet-HA/OWNd#91 and #671.

Co-authored-by: TheDarkWizard <9061870+TheDarkWizard@users.noreply.github.com>
@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 d548939 into OpenWebNet-HA:v2-phase1-architecture Oct 9, 2026
16 checks passed
@GreenGrassBlueOcean
GreenGrassBlueOcean deleted the feat/who25-scenario-plus branch October 9, 2026 20:09
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