Skip to content

Commit c56322b

Browse files
Bl00d-B0bclaude
andcommitted
fix: EVC energy word order, unreachable protocol gates, reactive power, 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>
1 parent 2178c86 commit c56322b

3 files changed

Lines changed: 43 additions & 111 deletions

File tree

custom_components/solax_modbus/const.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,9 @@ class BaseModbusSensorEntityDescription(SensorEntityDescription):
204204
"""Base class for modbus sensor declarations."""
205205

206206
allowedtypes: int = 0 # overload with ALLDEFAULT from plugin
207-
modbus_min: int | None = None # Minimum supported Modbus protocol document version, e.g. 102 for V001.02.
208-
modbus_max: int | None = None # Maximum supported Modbus protocol document version.
207+
order32: str | None = None # per-sensor 32-bit word order override ("big"/"little"); None = plugin default
208+
modbus_min: int | None = None # Minimum protocol version as reported by register 0x82 (e.g. 100 for V001.00); not the document revision.
209+
modbus_max: int | None = None # Maximum protocol version as reported by register 0x82.
209210
scale: float | dict[Any, Any] | Callable[[Any, Any, dict[str, Any]], Any] = (
210211
1 # can be float, dictionary or callable function(initval, descr, datadict)
211212
)
@@ -252,8 +253,8 @@ class BaseModbusButtonEntityDescription(ButtonEntityDescription):
252253
"""Base class for modbus button declarations."""
253254

254255
allowedtypes: int = 0 # overload with ALLDEFAULT from plugin
255-
modbus_min: int | None = None # Minimum supported Modbus protocol document version, e.g. 102 for V001.02.
256-
modbus_max: int | None = None # Maximum supported Modbus protocol document version.
256+
modbus_min: int | None = None # Minimum protocol version as reported by register 0x82 (e.g. 100 for V001.00); not the document revision.
257+
modbus_max: int | None = None # Maximum protocol version as reported by register 0x82.
257258
register: int | None = None
258259
command: int | None = None
259260
blacklist: list[str] | None = None # none or list of serial number prefixes
@@ -268,8 +269,8 @@ class BaseModbusSelectEntityDescription(SelectEntityDescription):
268269
"""Base class for modbus select declarations."""
269270

270271
allowedtypes: int = 0 # overload with ALLDEFAULT from plugin
271-
modbus_min: int | None = None # Minimum supported Modbus protocol document version, e.g. 102 for V001.02.
272-
modbus_max: int | None = None # Maximum supported Modbus protocol document version.
272+
modbus_min: int | None = None # Minimum protocol version as reported by register 0x82 (e.g. 100 for V001.00); not the document revision.
273+
modbus_max: int | None = None # Maximum protocol version as reported by register 0x82.
273274
register: int | None = None
274275
option_dict: dict[int, str] | None = None
275276
reverse_option_dict: dict[str, int] | None = None # autocomputed
@@ -288,8 +289,8 @@ class BaseModbusSwitchEntityDescription(SwitchEntityDescription):
288289
"""Base class for modbus switch declarations."""
289290

290291
allowedtypes: int = 0 # overload with ALLDEFAULT from plugin
291-
modbus_min: int | None = None # Minimum supported Modbus protocol document version, e.g. 102 for V001.02.
292-
modbus_max: int | None = None # Maximum supported Modbus protocol document version.
292+
modbus_min: int | None = None # Minimum protocol version as reported by register 0x82 (e.g. 100 for V001.00); not the document revision.
293+
modbus_max: int | None = None # Maximum protocol version as reported by register 0x82.
293294
register: int | None = None
294295
register_bit: int | None = None
295296
blacklist: list[str] | None = None # none or list of serial number prefixes
@@ -307,8 +308,8 @@ class BaseModbusTimeEntityDescription(TimeEntityDescription):
307308
"""Base class for modbus time declarations."""
308309

309310
allowedtypes: int = 0 # overload with ALLDEFAULT from plugin
310-
modbus_min: int | None = None # Minimum supported Modbus protocol document version, e.g. 102 for V001.02.
311-
modbus_max: int | None = None # Maximum supported Modbus protocol document version.
311+
modbus_min: int | None = None # Minimum protocol version as reported by register 0x82 (e.g. 100 for V001.00); not the document revision.
312+
modbus_max: int | None = None # Maximum protocol version as reported by register 0x82.
312313
scale: float | dict[Any, Any] | Callable[[Any, Any, dict[str, Any]], Any] = 1
313314
read_scale_exceptions: list[Any] | None = None
314315
read_scale: float = 1
@@ -336,8 +337,8 @@ class BaseModbusNumberEntityDescription(NumberEntityDescription):
336337
"""Base class for modbus number declarations."""
337338

338339
allowedtypes: int = 0 # overload with ALLDEFAULT from plugin
339-
modbus_min: int | None = None # Minimum supported Modbus protocol document version, e.g. 102 for V001.02.
340-
modbus_max: int | None = None # Maximum supported Modbus protocol document version.
340+
modbus_min: int | None = None # Minimum protocol version as reported by register 0x82 (e.g. 100 for V001.00); not the document revision.
341+
modbus_max: int | None = None # Maximum protocol version as reported by register 0x82.
341342
register: int | None = None
342343
read_scale_exceptions: list[Any] | None = None
343344
read_scale: float = 1

0 commit comments

Comments
 (0)