Skip to content

Further protocol specific register mapping improvements. - #2099

Merged
wills106 merged 11 commits into
wills106:mainfrom
TCWORLD:tidy-solax-regs
May 31, 2026
Merged

Further protocol specific register mapping improvements.#2099
wills106 merged 11 commits into
wills106:mainfrom
TCWORLD:tidy-solax-regs

Conversation

@TCWORLD

@TCWORLD TCWORLD commented May 30, 2026

Copy link
Copy Markdown
Contributor

Several improvements to the protocol dependent register mappings:

Fix GEN6 EPS Yield Total scaling for Proto>=100

Wrong scaling for GEN6 on newer protocol version.

Tidy Grid Meter/CT Registers

  1. There were some duplicate registers (no enabled by default hence didn't show up in testing)
  2. The registers were out of order which made it hard to see what was going on.
  3. Rename some from Meter to Grid for consistency with the docs and the rest of that register set.
    As these are disabled by default and were largely added in the most recent release, I doubt the rename will cause problems.
  4. Add some of these registers for proto < 100 based on the V3.36 docs.

NOTE: For the grid_reactive_power_l1/2/3 registers, we should probably test on a protocol 100 inverter and see if they have the correct values. Between the old versions, to V1.00. and then in V1.02 docs these changed address in a frankly strange ways. I wonder if it was actually a documentation error in V1.00 compared with V1.02 rather than registers actually moving, but could be wrong. I've left this discrepancy with gating in for now with protocol gating.

Enable extra Meter2 registers for Proto < 100

These exist for GEN3, but were disabled for 4/5/6 except in protocol >=101. However these are present in the G4 V3.36 docs, so I suspect as with the other meter 2 registers these should just be always available.

Exclude GEN4 from battery SoH/SoC total protocol gating

For some reason, even on proto>=100 the GEN4s are reporting incorrect information in the battery totals registers.

Fortunately GEN4 are physically limited to 1 battery, so we can always use the battery base register rather than needing the total registers.

Fixes #2100. Fixes #2102.

Enable runtime registers for X1

These were added for X3 but not X1. The docs don't explictly list them as X3 only.

Change Grid Export Total to U32

According to both old and new docs this should indeed be unsigned. Convert the type and remove remark.

Re-enable registers for < 100.

(Re-)enable some registers for older versions as they exist in the old V3.36 G4 docs.

  1. Pgrid Bias used to be enabled (requested in 2026.05.4 / 2026.05.5 / 2026.05.6 Release - Issue Reporting Thread #2079)
  2. VPP Exit Idle Enable used to be enabled
  3. Main Breaker Limit now enabled. Add different native ranges for X1 vs X3 per docs.
  4. Battery State of Health enabled for GEN6 (requested in [Bug]: Multiple sensors are missing for GEN6 inverter #2085)

TCWORLD added 8 commits May 30, 2026 16:37
Wrong scaling for GEN6 on newer protocol version.
Present in the G4 V3.36 docs.
Used to be enabled. Exists in V3.36 G4 docs.
Used to be enabled. Exists in V3.36 G4 docs.
According to both old and new docs this should indeed be unsigned. Convert the type and remove remark.
These were added for X3 but not X1. The docs don't explictly list them as X3 only.
These exist for GEN3, but were disabled for 4/5/6 except in protocol >=101.
However these are present in the G4 V3.36 docs, so I suspect as with the other meter 2 registers these should just be always available.
1. There were some duplicate registers (no enabled by default hence didn't show up in testing)
2. The registers were out of order which made it hard to see what was going on.
3. Rename some from Meter to Grid for consistency with the docs and the rest of that register set. As these are disabled by default and were largely added in the most recent release, I doubt the rename will cause problems.
4. Add some of these registers for proto < 100 based on the V3.36 docs.
Key is unchanged, just make the ID acronym uppercase.
@TCWORLD

TCWORLD commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

Regarding "Rename some entities from Meter to Grid for consistency" - I suspect based on testing this should have been the other way around, renaming them from Grid to Meter (or Meter 1).
These registers don't appear to work for the CT case. In fact in the old docs they are labelled simply "Meter", while in the new >=100 docs they are labelled as being Meter/CT, so don't really know the best option there. Happy to change to Meter.

TCWORLD added 2 commits May 31, 2026 01:42
Split SoH registers into Battery 1/2 and Total for proto >= 100.
GEN4 are limited to 1 battery, so always use the battery base register rather than the total registers.

For some reason, even on proto>=100 the GEN4s are reporting incorrect information in the battery totals registers.
@wills106
wills106 merged commit b0f7a02 into wills106:main May 31, 2026
13 checks passed
@TCWORLD
TCWORLD deleted the tidy-solax-regs branch July 3, 2026 22:41
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 13, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured_power_2/_l1/_l2/_l3 default-disabled: without a
   meter/CT the 0x70x region returns junk (149 MW readings); addresses
   verified correct against the doc, no register changes.
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured_power_2/_l1/_l2/_l3 default-disabled: without a
   meter/CT the 0x70x region returns junk (149 MW readings); addresses
   verified correct against the doc, no register changes.
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only and its PowerToEV row proves the parenthetical addresses
   carry a systematic -1 typo. The _alt sensors (l1/l2/l3), built on
   that typo and reading Int32 at overlapping odd offsets, are removed;
   the primaries (0x704/0x706/0x708, Int32 per the authoritative
   address column) and measured_power_2 stay default-disabled - a
   meter-attached test shows the firmware never serves per-phase
   values there (handler echoes one buffer at every offset).
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only and its PowerToEV row proves the parenthetical addresses
   carry a systematic -1 typo. The _alt sensors (l1/l2/l3), built on
   that typo and reading Int32 at overlapping odd offsets, are removed;
   the primaries (0x704/0x706/0x708, Int32 per the authoritative
   address column) and measured_power_2 stay default-disabled - a
   meter-attached test shows the firmware never serves per-phase
   values there (handler echoes one buffer at every offset).
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only and its PowerToEV row proves the parenthetical addresses
   carry a systematic -1 typo. The _alt sensors (l1/l2/l3), built on
   that typo and reading Int32 at overlapping odd offsets, are removed;
   the primaries (0x704/0x706/0x708, Int32 per the authoritative
   address column) and measured_power_2 stay default-disabled - a
   meter-attached test shows the firmware never serves per-phase
   values there (handler echoes one buffer at every offset).
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only and its PowerToEV row proves the parenthetical addresses
   carry a systematic -1 typo. The _alt sensors (l1/l2/l3), built on
   that typo and reading Int32 at overlapping odd offsets, are removed;
   the primaries (0x704/0x706/0x708, Int32 per the authoritative
   address column) and measured_power_2 stay default-disabled - a
   meter-attached test shows the firmware never serves per-phase
   values there (handler echoes one buffer at every offset).
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only and its PowerToEV row proves the parenthetical addresses
   carry a systematic -1 typo. The _alt sensors (l1/l2/l3), built on
   that typo and reading Int32 at overlapping odd offsets, are removed;
   the primaries (0x704/0x706/0x708, Int32 per the authoritative
   address column) and measured_power_2 stay default-disabled - a
   meter-attached test shows the firmware never serves per-phase
   values there (handler echoes one buffer at every offset).
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only and its PowerToEV row proves the parenthetical addresses
   carry a systematic -1 typo. The _alt sensors (l1/l2/l3), built on
   that typo and reading Int32 at overlapping odd offsets, are removed;
   the primaries (0x704/0x706/0x708, Int32 per the authoritative
   address column) and measured_power_2 stay default-disabled - a
   meter-attached test shows the firmware never serves per-phase
   values there (handler echoes one buffer at every offset).
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only and its PowerToEV row proves the parenthetical addresses
   carry a systematic -1 typo. The _alt sensors (l1/l2/l3), built on
   that typo and reading Int32 at overlapping odd offsets, are removed;
   the primaries (0x704/0x706/0x708, Int32 per the authoritative
   address column) and measured_power_2 stay default-disabled - a
   meter-attached test shows the firmware never serves per-phase
   values there (handler echoes one buffer at every offset).
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Six hardware-verified fixes (raw Modbus TCP reads cross-checked against
the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only and its PowerToEV row proves the parenthetical addresses
   carry a systematic -1 typo. The _alt sensors (l1/l2/l3), built on
   that typo and reading Int32 at overlapping odd offsets, are removed;
   the primaries (0x704/0x706/0x708, Int32 per the authoritative
   address column) and measured_power_2 stay default-disabled - a
   meter-attached test shows the firmware never serves per-phase
   values there (handler echoes one buffer at every offset).
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Seven hardware-verified fixes (raw Modbus TCP reads cross-checked
against the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only; live testing shows the block has no address decoder
   (any read returns the current internal frame) and no frame contains
   per-phase power. The _alt sensors, built on the doc's off-by-one
   parentheticals, are removed; the primaries are renamed to the doc's
   terminology (Feed-in Power L1/L2/L3, Int32 per the authoritative
   address column) and stay default-disabled. The verified-correct
   meter registers - Feed-in Power 0x43B (doc "Feed In Power", Int32)
   and the 0x43D/0x43F energy counters (Uint32) - are renamed per the
   doc and now enabled by default (they read clean zeros without a
   meter). All 32-bit MIC registers cross-checked for signedness.
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.
7. RTC sensors (hybrid 0x85, MIC 0x318) are now proper TIMESTAMP
   entities: value_function_rtc returns a timezone-aware datetime
   (host local zone attached - the device stores host-local time,
   verified live; Sync RTC writes datetime.now()), matching the EV
   charger's RTC implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bl00d-B0b added a commit to Bl00d-B0b/homeassistant-solax-modbus that referenced this pull request Jul 14, 2026
…r, MIC-G2 sensors

Seven hardware-verified fixes (raw Modbus TCP reads cross-checked
against the official protocol documents):

1. EVC Charge Added - Cumulative read 19660.8 kWh instead of 0.3 kWh:
   the charger sends EQ_Total (0x10, u32) high-word-first. Adds the
   per-sensor order32 override field (read path already honored it)
   and sets order32="big" on charge_added_cum.
2. modbus_min=101/102 gates were unreachable: no device reports more
   than 100 from register 0x82 (the values conflated the protocol
   register with the document revision). Relaxed to 100 after raw-read
   verification; misleading dataclass comments corrected; peakshaving
   complementary pairs re-split at the documented boundary
   (unscaled max=99, X1/X3-scaled min=100).
3. Grid Reactive Power L1/L2 showed ~26 Mvar: 0xC0/0xC2-as-S32 merged
   two S16 values. L1/L2 now use the documented S32 registers 0xDE/0xE0
   for protocol >=100 (raw-verified, phases sum to total) and the
   legacy S16 quad for <=99; the V1.00-derived 0xC0/0xC2 S32 defs are
   removed (doc error confirmed, resolves the open question in wills106#2099).
4. MIC pv_total_power removed: exact computed duplicate of
   pv_power_total (same value_function, same device).
5. MIC-G2 measured power: doc V4.0 marks the whole 0x700-0x70A block
   as EVC-only; live testing shows the block has no address decoder
   (any read returns the current internal frame) and no frame contains
   per-phase power. The _alt sensors, built on the doc's off-by-one
   parentheticals, are removed; the primaries are renamed to the doc's
   terminology (Feed-in Power L1/L2/L3, Int32 per the authoritative
   address column) and stay default-disabled. The verified-correct
   meter registers - Feed-in Power 0x43B (doc "Feed In Power", Int32)
   and the 0x43D/0x43F energy counters (Uint32) - are renamed per the
   doc and now enabled by default (they read clean zeros without a
   meter). All 32-bit MIC registers cross-checked for signedness.
6. MIC-G2 Q Curve select always showed unknown: readback 0x347 is
   byte-packed (mode in low byte, Pf in high byte) but was decoded as
   full u16. Now REGISTER_U8L.
7. RTC sensors (hybrid 0x85, MIC 0x318) are now proper TIMESTAMP
   entities: value_function_rtc returns a timezone-aware datetime
   (host local zone attached - the device stores host-local time,
   verified live; Sync RTC writes datetime.now()), matching the EV
   charger's RTC implementation.

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.

[Bug]: Battery SoC stuck at 0% - 2026.05.5 & 2026.05.4 (broken by #2069) [Bug]: SoC reports 16% when Solax Cloud reports 10%

2 participants