C300 DC decoded with wrong offsets by the c300 profile (SoC 0%, temperature, in/out, serial, ac_output/light exceptions)
Library: SolixBLE (SolixBLE/devices/c300.py, master)
Via: HaSolixBLE v3.5.0 (Home Assistant, connected through an ESPHome Bluetooth proxy)
Device:
SolixBLE_C300_DC_issue.md
, firmware 1.0.1
Summary
The c300 profile connects and streams fine, but several fields are decoded from the wrong keys for the DC variant. The device's own LCD is used as ground truth below. Some fields raise on every telemetry update, some read constant/implausible values, and the serial number is read from the wrong key.
Exceptions on every update
# ac_output -> PortStatus(self._parse_int("b7", begin=1))
ValueError: 87 is not a valid PortStatus
File ".../SolixBLE/devices/c300.py", line 238, in ac_output
# light -> LightStatus(self._parse_int("cf", begin=1))
KeyError: 'cf'
File ".../SolixBLE/device.py", line 323, in _parse_int
File ".../SolixBLE/devices/c300.py", line 313, in light
On the DC, b7 is a constant 0x57 (=87, not a PortStatus) and there is no cf key in the telemetry at all. Since the DC has no AC output and (apparently) no light, both properties should probably be gated / marked unsupported for this model.
Ground truth (device LCD) vs. parsed
| Property |
key |
raw value |
parsed |
LCD / actual |
verdict |
battery_percentage |
bb |
0100 |
0 |
82 % |
wrong (82 is not present as a raw byte anywhere in the frame) |
temperature |
b9 |
0101 |
1 |
— (implausible) |
wrong |
power_in (total) |
ad |
020200 |
2 |
IN 57 W |
wrong — 2 equals the output |
power_out (total) |
ae |
020000 |
0 |
OUT 2 W |
wrong |
solar_power_in |
ac |
023900 |
57 |
IN 57 W |
matches the real input |
ac_power_in |
a5 |
023900 |
57 |
(no AC) |
mirrors the input |
time_remaining |
a4 /10 |
020100 |
0.1 |
1.0 "Recharge Hrs" |
factor-10 / unit off |
serial_number |
c5 |
022c01 |
"300" (0x012c) |
real serial in c3 |
wrong key (c5 looks like rated power = 300 W) |
software_version |
b1 |
026500 |
"1.0.1" |
fw 1.0.1 |
correct |
charging_status |
ba |
0102 |
Charging |
charging |
plausible |
usb_port_c1/c2 |
bd/be |
0101 |
Output |
C2 in use |
plausible |
Notable finds
- Serial number is in
c3, not c5: c3 = 00 <ascii> → AZVUW00F095… (ASCII). c5 = 022c01 → 0x012c = 300, likely rated power (300 W).
af = 02d032 / 02c132 → 0x32d0≈13008 / 0x32c1≈13009 → looks like battery voltage in mV (~13.0 V); currently unmapped.
- SoC (82 %) does not appear as any raw byte in the frame, so it is either derived (from voltage?) or lives in a field that needs a charge-state sweep to identify. Happy to capture frames across a full charge/discharge to pin it down.
Raw telemetry dumps (two consecutive frames, DC, fw 1.0.1)
Value format appears to be [type/len byte][little-endian payload], with _parse_int(key, begin=1) skipping the first byte.
{'a1': '31', 'a2': '0300000000', 'a3': '020700', 'a4': '020100', 'a5': '023900', 'a6': '020000', 'a7': '020000', 'a8': '020100', 'a9': '020000', 'aa': '020000', 'ab': '020000', 'ac': '023900', 'ad': '020200', 'ae': '020000', 'af': '02d032', 'b0': '028900', 'b1': '026500', 'b2': '027e00', 'b3': '028900', 'b4': '028900', 'b5': '011d', 'b6': '0102', 'b7': '0157', 'b8': '0164', 'b9': '0101', 'ba': '0102', 'bb': '0100', 'bc': '0100', 'bd': '0101', 'be': '0101', 'bf': '0100', 'c0': '0100', 'c1': '0100', 'c2': '0100', 'c3': '00415a565557303046303935…', 'c4': '020000', 'c5': '022c01', 'c6': '020000', 'c7': '0102', 'c8': '0100', 'c9': '0100', 'ca': '0100', 'cb': '023c00', 'cc': '0100', 'cd': '0100', 'f7': '0301000000', 'f8': '040100000000010000000000000000000000000000'}
{'a1': '31', ... 'a4': '020000', ... 'ad': '020100', ... (otherwise identical)}
(Serial in c3 truncated on purpose; full ASCII value available on request.)
Environment notes
- Transport is stable; this is purely a decode-mapping issue for the DC variant.
- I can enable debug logging and capture additional frames on demand (e.g. toggling each output, or sweeping SoC) to help map the remaining keys — just say which manipulations would help most.
C300 DC decoded with wrong offsets by the
c300profile (SoC 0%, temperature, in/out, serial,ac_output/lightexceptions)Library: SolixBLE (
SolixBLE/devices/c300.py,master)Via: HaSolixBLE v3.5.0 (Home Assistant, connected through an ESPHome Bluetooth proxy)
Device:
SolixBLE_C300_DC_issue.md
, firmware 1.0.1
Summary
The
c300profile connects and streams fine, but several fields are decoded from the wrong keys for the DC variant. The device's own LCD is used as ground truth below. Some fields raise on every telemetry update, some read constant/implausible values, and the serial number is read from the wrong key.Exceptions on every update
On the DC,
b7is a constant0x57(=87, not aPortStatus) and there is nocfkey in the telemetry at all. Since the DC has no AC output and (apparently) no light, both properties should probably be gated / marked unsupported for this model.Ground truth (device LCD) vs. parsed
battery_percentagebb0100temperatureb90101power_in(total)ad020200power_out(total)ae020000solar_power_inac023900ac_power_ina5023900time_remaininga4/10020100serial_numberc5022c01c3c5looks like rated power = 300 W)software_versionb1026500charging_statusba0102usb_port_c1/c2bd/be0101Notable finds
c3, notc5:c3 = 00 <ascii>→AZVUW00F095…(ASCII).c5 = 022c01→0x012c= 300, likely rated power (300 W).af=02d032/02c132→0x32d0≈13008 /0x32c1≈13009 → looks like battery voltage in mV (~13.0 V); currently unmapped.Raw telemetry dumps (two consecutive frames, DC, fw 1.0.1)
Value format appears to be
[type/len byte][little-endian payload], with_parse_int(key, begin=1)skipping the first byte.(Serial in
c3truncated on purpose; full ASCII value available on request.)Environment notes