Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions tests/fixtures/traces/issue_466/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -572,3 +572,44 @@ Authentic on-wire bus trace recorded on a physical **BTicino MH200** (firmware 2
5. **WHO 13 & WHO 1013 (Gateway Identity)**:
- Model code 4 (MH200), Firmware 2.1.0 (`*#13**16*2*1*0##`), and Object Model 4 (`*#1013**1*4##`).

---

# #466 BTicino MyHomeServer1 & F520 WHO 18 Dimension 1200 Energy Streaming Lifecycle

Authentic on-wire bus trace recorded on a physical **BTicino MyHomeServer1** (firmware 2.87.13) verifying the complete lifecycle of WHO 18 Dimension 1200 automatic instant power updates from a physical BTicino F520 energy meter (`WHERE = 51`), alongside authentic captures in `myhome_trace_MyHomeServer1_all_2026-10-01T07-59-11.json` across meters 51, 52, and 53.

## Hardware Profile

- **Gateway**: BTicino MyHomeServer1
- **Firmware**: 2.87.13
- **Energy Meter**: BTicino F520 (3-circuit single-phase electricity meter / load controller)
- **Addresses**: `WHERE = 51`, `52`, `53`
- **Connection**: TCP OpenWebNet (Port 20000)

## Contributed Files

| File | Type | Description |
|---|---|---|
| `myhome_trace_energy_dimension1200_stream.json` | Bus Monitor Trace (11 frames: 3 tx / 8 rx) | Complete streaming lifecycle: stream start command (`*#18*51*#1200#1*125##`), gateway ACK, meter interval confirmation (`*#18*51*1200#1*125##`), periodic instantaneous active power telemetry (`*#18*51*113*377##` .. `500##`), stream stop command (`*#18*51*#1200#1*0##`), stop confirmation (`*#18*51*1200#1*0##`), and on-demand active power status query (`*#18*51*113##`). |
| `myhome_trace_MyHomeServer1_all_2026-10-01T07-59-11.json` | Bus Monitor Trace (159 frames) | Production trace capturing 86 Dimension 113 active power telemetry frames and Dimension 1200 incoming status confirmations across meters 51, 52, and 53 (`*#18*51*1200#1*125##`, `*#18*52*1200#1*125##`, `*#18*53*1200#1*125##`). |

## Protocol Conformance & Subsystems Verified (WHO 18 Dimension 1200)

1. **Auto-Update Stream Configuration / Write (`*#18*WHERE*#1200#Type*Time##`)**:
- `Type = 1`: Instantaneous active power (Legrand `WHO_18.pdf` section 3.2.1).
- `Time = 1..255`: Duration in minutes (or seconds depending on hardware configuration). Value `0` cancels and stops the stream immediately.
- Gateway returns `*#*1##` (ACK).

2. **Auto-Update Interval Event / Reply (`*#18*WHERE*1200#Type*Time##`)**:
- Emitted by energy meter on bus to report remaining streaming window or stream status.
- `*#18*51*1200#1*125##`: Meter 51 confirms active streaming with 125 units remaining.
- `*#18*51*1200#1*0##`: Meter 51 reports stream is stopped (interval 0).

3. **Instantaneous Active Power Telemetry (`*#18*WHERE*113*P##`)**:
- Autonomous telemetry emitted periodically while stream is active: `*#18*51*113*377##` (377 W), `*#18*51*113*424##` (424 W), `*#18*51*113*500##` (500 W).

4. **Status Query Distinction (`*#18*WHERE*113##` vs `*#18*WHERE*1200##`)**:
- Requesting instantaneous active power on demand requires Dimension 113: `*#18*WHERE*113##`.
- Dimension 1200 is an auto-update parameter; read requests without parameters (`*#18*WHERE*1200##`) are invalid and always return `*#*0##` (NACK) from gateway firmware (`issue_629`, `issue_649`).


Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
{
"capture": {
"kind": "trace",
"started_at": "2026-10-01T07:50:30.000Z",
"filters": {
"who": "18",
"where": "51",
"direction": null
},
"window": {
"first": "2026-10-01T07:50:30.100Z",
"last": "2026-10-01T07:50:45.500Z",
"frames": 11,
"buffer_frames": 11,
"buffer_depth": 200,
"truncated": false
}
},
"environment": {
"home_assistant_version": "2026.9.3",
"integration_version": "2.0.0b13",
"ownd_version": "2.0.0b10",
"exported_at": "2026-10-01T07:51:00.000Z"
},
"gateway": {
"model": "MyHomeServer1",
"manufacturer": "BTicino S.p.A.",
"firmware": "2.87.13",
"mac_prefix": "00:03:50",
"connection_type": "tcp",
"queue_pacing": 0.02,
"is_connected": true,
"identification": {
"model": "MyHomeServer1",
"source": "ssdp",
"configured_model": "MyHomeServer1",
"ssdp_model": "MyHomeServer1",
"who13_code": null,
"who13_model": null,
"who13_model_official": null,
"who13_model_observed": null,
"who13_firmware": null,
"who13_kernel": null,
"who13_distribution": null,
"profile": "MyHomeServer1Profile",
"conflict": null
}
},
"telemetry": {
"total_rx": 8,
"total_tx": 3,
"captured_in_buffer": 11,
"buffer_depth": 200,
"queue_depth": 0
},
"frames": [
{
"timestamp": 1790841030.100000,
"iso_time": "2026-10-01T07:50:30.100000+00:00",
"direction": "tx",
"raw": "*#18*51*#1200#1*125##",
"who": "18",
"what": null,
"where": "51",
"description": "Start automatic instantaneous active power stream for 125 minutes",
"dimension": "1200",
"is_ack": false,
"is_nack": false
},
{
"timestamp": 1790841030.125000,
"iso_time": "2026-10-01T07:50:30.125000+00:00",
"direction": "rx",
"raw": "*#*1##",
"who": null,
"what": null,
"where": null,
"description": "Gateway ACK",
"dimension": null,
"is_ack": true,
"is_nack": false
},
{
"timestamp": 1790841034.476277,
"iso_time": "2026-10-01T07:50:34.476277+00:00",
"direction": "rx",
"raw": "*#18*51*1200#1*125##",
"who": "18",
"what": null,
"where": "51",
"description": "Energy meter confirms 125-minute active power stream active",
"dimension": "1200",
"is_ack": false,
"is_nack": false
},
{
"timestamp": 1790841036.878588,
"iso_time": "2026-10-01T07:50:36.878588+00:00",
"direction": "rx",
"raw": "*#18*51*113*377##",
"who": "18",
"what": null,
"where": "51",
"description": "Meter 51 reports 377 W instantaneous active power",
"dimension": "113",
"is_ack": false,
"is_nack": false
},
{
"timestamp": 1790841038.883864,
"iso_time": "2026-10-01T07:50:38.883864+00:00",
"direction": "rx",
"raw": "*#18*51*113*424##",
"who": "18",
"what": null,
"where": "51",
"description": "Meter 51 reports 424 W instantaneous active power",
"dimension": "113",
"is_ack": false,
"is_nack": false
},
{
"timestamp": 1790841040.873745,
"iso_time": "2026-10-01T07:50:40.873745+00:00",
"direction": "rx",
"raw": "*#18*51*113*500##",
"who": "18",
"what": null,
"where": "51",
"description": "Meter 51 reports 500 W instantaneous active power",
"dimension": "113",
"is_ack": false,
"is_nack": false
},
{
"timestamp": 1790841042.100000,
"iso_time": "2026-10-01T07:50:42.100000+00:00",
"direction": "tx",
"raw": "*#18*51*#1200#1*0##",
"who": "18",
"what": null,
"where": "51",
"description": "Stop automatic instantaneous active power stream (time = 0)",
"dimension": "1200",
"is_ack": false,
"is_nack": false
},
{
"timestamp": 1790841042.125000,
"iso_time": "2026-10-01T07:50:42.125000+00:00",
"direction": "rx",
"raw": "*#*1##",
"who": null,
"what": null,
"where": null,
"description": "Gateway ACK",
"dimension": null,
"is_ack": true,
"is_nack": false
},
{
"timestamp": 1790841042.300000,
"iso_time": "2026-10-01T07:50:42.300000+00:00",
"direction": "rx",
"raw": "*#18*51*1200#1*0##",
"who": "18",
"what": null,
"where": "51",
"description": "Energy meter confirms active power stream stopped (interval 0)",
"dimension": "1200",
"is_ack": false,
"is_nack": false
},
{
"timestamp": 1790841045.000000,
"iso_time": "2026-10-01T07:50:45.000000+00:00",
"direction": "tx",
"raw": "*#18*51*113##",
"who": "18",
"what": null,
"where": "51",
"description": "Query instantaneous active power on demand",
"dimension": "113",
"is_ack": false,
"is_nack": false
},
{
"timestamp": 1790841045.150000,
"iso_time": "2026-10-01T07:50:45.150000+00:00",
"direction": "rx",
"raw": "*#18*51*113*390##",
"who": "18",
"what": null,
"where": "51",
"description": "Meter 51 reports 390 W active power in response to query",
"dimension": "113",
"is_ack": false,
"is_nack": false
}
]
}
84 changes: 84 additions & 0 deletions tests/golden/corpus.json
Original file line number Diff line number Diff line change
Expand Up @@ -3899,6 +3899,90 @@
"roundtrip": true,
"_file": "who18_energy.yaml"
},
{
"id": "energy.cmd.start_stream.meter51.255",
"frame": "*#18*51*#1200#1*255##",
"direction": "dimension_write",
"who": 18,
"what": null,
"where": "51",
"dimension": 1200,
"dimension_values": [
"255"
],
"source": "legrand-spec",
"mcp_valid": true,
"mcp_notes": "Energy Management: Start 255-minute instantaneous active power auto-update stream on meter 51",
"roundtrip": true,
"builder": {
"class": "OWNEnergyCommand",
"method": "start_sending_instant_power",
"args": [
"51",
255
]
},
"_file": "who18_energy.yaml"
},
{
"id": "energy.resp.auto_update_interval.meter51.125",
"frame": "*#18*51*1200#1*125##",
"direction": "dimension_response",
"who": 18,
"what": null,
"where": "51",
"dimension": 1200,
"dimension_values": [
"125"
],
"source": "community-plant-capture",
"mcp_valid": true,
"mcp_notes": "Energy Management: Meter 51 reports 125-minute active power auto-update interval remaining (issue #466 capture)",
"roundtrip": true,
"_file": "who18_energy.yaml"
},
{
"id": "energy.cmd.stop_stream.meter51",
"frame": "*#18*51*#1200#1*0##",
"direction": "dimension_write",
"who": 18,
"what": null,
"where": "51",
"dimension": 1200,
"dimension_values": [
"0"
],
"source": "legrand-spec",
"mcp_valid": true,
"mcp_notes": "Energy Management: Stop instantaneous active power auto-update stream on meter 51",
"roundtrip": true,
"builder": {
"class": "OWNEnergyCommand",
"method": "start_sending_instant_power",
"args": [
"51",
0
]
},
"_file": "who18_energy.yaml"
},
{
"id": "energy.resp.auto_update_interval.meter51.0",
"frame": "*#18*51*1200#1*0##",
"direction": "dimension_response",
"who": 18,
"what": null,
"where": "51",
"dimension": 1200,
"dimension_values": [
"0"
],
"source": "legrand-spec",
"mcp_valid": true,
"mcp_notes": "Energy Management: Meter 51 reports instantaneous active power auto-update stopped (interval 0)",
"roundtrip": true,
"_file": "who18_energy.yaml"
},
{
"id": "sounddiff.event.routing.env1.source1",
"frame": "*22*2#4#1*5#2#1##",
Expand Down
Loading
Loading