Skip to content

docs: describe battery cell struct registers and bat_mng_struct profile layouts - #53

Open
pluskal wants to merge 2 commits into
svalouch:mainfrom
pluskal:docs/undocumented-battery-registers
Open

docs: describe battery cell struct registers and bat_mng_struct profile layouts#53
pluskal wants to merge 2 commits into
svalouch:mainfrom
pluskal:docs/undocumented-battery-registers

Conversation

@pluskal

@pluskal pluskal commented Aug 15, 2026

Copy link
Copy Markdown

This PR adds documentation only — no functional changes: description= strings for the struct-type battery registers and the bat_mng_struct.profile_* object IDs in registry.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 against battery.min_cell_voltage / battery.max_cell_voltage (matches to 0.1 mV) and battery.temperature (~30 °C, matches).
  • battery.cells_resist[N] — 96 bytes = 24 records of resistance 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 (branch cell_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 (branch battery_data_decoding). Verified that the decoded values match the granular battery.cells_stat[N].u_max.value/.index/.time registers.
  • bat_mng_struct.profile_pdc / profile_pdc_max / profile_load / profile_pext — 192 bytes = <48f little-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.py still parses (ast.parse) and the description column alignment follows the existing file style.

🤖 Generated with Claude Code

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>
Copilot AI lite review requested due to automatic review settings August 15, 2026 18:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 for battery.cells[N], battery.cells_resist[N], and battery.cells_stat[N] struct-type OIDs in registry.py.
  • Added description= strings for bat_mng_struct.profile_* OIDs describing their 48×float32 (192-byte) daily profile payload layout.
  • Added a “Struct-type registers” section to docs/inverter_registry.rst summarizing 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.

Comment thread src/rctclient/registry.py Outdated
Comment on lines +877 to +881
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'),

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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