docs: describe battery cell struct registers and bat_mng_struct profile layouts - #53
docs: describe battery cell struct registers and bat_mng_struct profile layouts#53pluskal wants to merge 2 commits into
Conversation
Add description= strings to the registry entries for battery.cells[0..6], battery.cells_resist[0..6], battery.cells_stat[0..6] and the four bat_mng_struct.profile_* object IDs, and add a short "Struct-type registers" section to the registry documentation page summarizing the payload layouts. All layouts were verified live against a Power Storage 6.0 (BMS software 5615, 4 battery modules) via the port 8899 protocol: - battery.cells[N]: 96 bytes = 24 x (temperature uint8 [degC], voltage uint16 LE [mV], status uint8); cross-checked against battery.min_cell_voltage / battery.max_cell_voltage (matches to 0.1 mV) and battery.temperature. - battery.cells_resist[N]: 96 bytes = 24 x (resistance uint16 BE [1/256 mOhm], 2 bytes padding); format by @sfudeus (cell_resist). - battery.cells_stat[N]: 48 bytes = u_min/u_max/t_min/t_max, each (cell index uint32 LE, unix timestamp uint32 LE, value float32 LE); format by @sfudeus (battery_data_decoding); values match the granular battery.cells_stat[N].* registers. - bat_mng_struct.profile_pdc / profile_pdc_max / profile_load / profile_pext: 192 bytes = <48f LE, one Watt value per 30-minute slot starting at 00:00; first described by @SaxonWood in svalouch#49. Verified to produce plausible daily curves. Documentation only, no functional changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR enhances the registry/documentation for “struct-type” inverter registers by adding description strings for composite battery-related OIDs and by documenting the binary payload layouts in the registry docs page, to make reverse-engineered formats discoverable via the generated CSV tables and Sphinx docs.
Changes:
- Added
description=strings forbattery.cells[N],battery.cells_resist[N], andbattery.cells_stat[N]struct-type OIDs inregistry.py. - Added
description=strings forbat_mng_struct.profile_*OIDs describing their 48×float32 (192-byte) daily profile payload layout. - Added a “Struct-type registers” section to
docs/inverter_registry.rstsummarizing the verified binary layouts.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/rctclient/registry.py | Adds descriptions for composite/struct-type battery OIDs and bat_mng_struct.profile_* layout notes (used in generated registry CSV). |
| docs/inverter_registry.rst | Documents the struct-type register payload layouts and references the existing decoding types where applicable. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| ObjectInfo(group=ObjectGroup.BAT_MNG_STRUCT, object_id=0x3B0C6A53, index=203, request_data_type=DataType.STRING, name='bat_mng_struct.profile_pdc_max', description='Estimated maximum PV (DC) power profile [W]: 48 x float32 LE, one value per 30-minute slot of the day starting at 00:00'), | ||
| ObjectInfo(group=ObjectGroup.BAT_MNG_STRUCT, object_id=0x9DC927AA, index=570, request_data_type=DataType.UNKNOWN, name='bat_mng_struct.profile_load', description='Estimated load power profile [W]: 48 x float32 LE, one value per 30-minute slot of the day starting at 00:00'), | ||
| ObjectInfo(group=ObjectGroup.BAT_MNG_STRUCT, object_id=0xB2FB9A90, index=633, request_data_type=DataType.FLOAT, name='bat_mng_struct.k_trust', description='How fast the actual prediction can be trusted [0..10]'), | ||
| ObjectInfo(group=ObjectGroup.BAT_MNG_STRUCT, object_id=0xDE68F62D, index=777, request_data_type=DataType.STRING, name='bat_mng_struct.profile_pext'), | ||
| ObjectInfo(group=ObjectGroup.BAT_MNG_STRUCT, object_id=0xDF6EA121, index=781, request_data_type=DataType.STRING, name='bat_mng_struct.profile_pdc'), | ||
| ObjectInfo(group=ObjectGroup.BAT_MNG_STRUCT, object_id=0xDE68F62D, index=777, request_data_type=DataType.STRING, name='bat_mng_struct.profile_pext', description='Estimated external power profile [W]: 48 x float32 LE, one value per 30-minute slot of the day starting at 00:00'), | ||
| ObjectInfo(group=ObjectGroup.BAT_MNG_STRUCT, object_id=0xDF6EA121, index=781, request_data_type=DataType.STRING, name='bat_mng_struct.profile_pdc', description='Estimated PV (DC) power profile [W]: 48 x float32 LE, one value per 30-minute slot of the day starting at 00:00'), |
There was a problem hiding this comment.
Good catch — fixed in a5d5ce2. All three are now DataType.UNKNOWN, matching profile_load which already used it; the CLI then falls back to the hexdump path in cli.py instead of attempting an ASCII decode of float32 payloads. A dedicated 48×float32 decoder type would be a natural follow-up but is out of scope for this docs PR.
The four bat_mng_struct.profile_* registers carry binary 48 x float32 LE payloads (documented in this PR); decoding them as STRING truncates at the first NUL or raises UnicodeDecodeError in the CLI. profile_load was already UNKNOWN - align the remaining three so the CLI falls back to a hexdump (cli.py handles DataType.UNKNOWN that way) until a dedicated decoder type exists. Suggested by Copilot review on PR svalouch#53. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This PR adds documentation only — no functional changes:
description=strings for the struct-type battery registers and thebat_mng_struct.profile_*object IDs inregistry.py(they flow into the generated registry CSV tables), plus a short "Struct-type registers" section on the registry docs page summarizing the payload layouts.Verification
All layouts were verified live today against a Power Storage 6.0 (BMS software 5615, 4 battery modules) via the port 8899 protocol:
battery.cells[N]— 96 bytes = 24 records of 4 bytes:temperature [°C] uint8,cell voltage [mV] uint16 LE,status uint8. Cross-checked againstbattery.min_cell_voltage/battery.max_cell_voltage(matches to 0.1 mV) andbattery.temperature(~30 °C, matches).battery.cells_resist[N]— 96 bytes = 24 records ofresistance uint16 BE(unit 1/256 mOhm) + 2 bytes padding. Matches the decoder already merged in Add support for cell resistance data #51; format originally determined by @sfudeus (branchcell_resist).battery.cells_stat[N]— 48 bytes =u_min/u_max/t_min/t_max, each(cell index uint32 LE (0-based), unix timestamp uint32 LE, value float32 LE). Matches the decoder merged in Add explicit support for battery cell data and battery module history #48; format by @sfudeus (branchbattery_data_decoding). Verified that the decoded values match the granularbattery.cells_stat[N].u_max.value/.index/.timeregisters.bat_mng_struct.profile_pdc/profile_pdc_max/profile_load/profile_pext— 192 bytes =<48flittle-endian, one Watt value per 30-minute slot of the day starting at 00:00, as first described by @SaxonWood in Decoding bat_mng_struct.profile... OIDs #49. Verified to decode into plausible daily curves (PV ~31 kWh, load ~34 kWh for the day). Per the ticket, no decoder is added here — descriptions only.The descriptions on the granular
battery.cells_stat[N].*subfields were left untouched.src/rctclient/registry.pystill parses (ast.parse) and the description column alignment follows the existing file style.🤖 Generated with Claude Code