浏览代码

Fix CHARGER state decode tables (cross-check vs protocol v1.4.15)

The decode tables for registers 15201 (Charger workstate), 15202 (MPPT
state), and 15203 (Charging state) were wrong -- I had derived them
from a misreading of the protocol document and never validated against
the official values.

Correct values from PH1800/PV1800/EP1800/PV3500/EP3500 RS485 Modbus
RTU communication Protocol 1.4.15.xlsx:

  15201 Charger workstate:
    0=Initialization mode, 1=SelfTest mode, 2=Work mode, 3=Stop mode
    (was: 0=Init, 1=Standby, 2=Charging, 3=Fault, 4=Flash)

  15202 MPPT state:
    0=Stop, 1=MPPT, 2=Current limiting
    (was: 0=Stop, 1=Start, 2=Normal work, 3=MPPT limit, 4=Float)

  15203 Charging state:
    0=Stop, 1=Absorb charge, 2=Float charge, 3=EQ charge
    (was: 0=Stop, 1=Precharge, 2=CC, 3=CV, 4=Float, 5=Current derating)

The fix was triggered by the user sharing a Scribd link to the same
protocol document (document 881604771, v1.4.15). The XLSX in the
taHC81/MUST-ESPhome GitHub repo is the same file, so I cross-checked
the new values against the official Unit column.

register-map.md is updated with the corrected tables and a note about
the change for anyone who has old log output.

Live verification: register 15201 returns 1 on this unit when running,
which the new decode correctly renders as 'SelfTest mode'.
lrosales 1 月之前
父节点
当前提交
19e65c7838
共有 2 个文件被更改,包括 35 次插入 和 27 次删除
  1. 22 13
      docs/register-map.md
  2. 13 14
      must_pv1800_monitor.py

+ 22 - 13
docs/register-map.md

@@ -80,36 +80,37 @@ all of them in one response when asked.
 
 ## Decoded state values
 
+These are the canonical values from protocol v1.4.15, verified by
+cross-checking the XLSX shipped with the
+[taHC81/MUST-ESPhome](https://github.com/taHC81/MUST-ESPhome) repo
+against the same document uploaded to
+[Scribd](https://www.scribd.com/document/881604771/) (document 881604771).
+
 ### Charger workstate (15201)
 
 | Value | Meaning |
 |-------|---------|
 | 0 | Initialization mode |
-| 1 | Standby |
-| 2 | Charging |
-| 3 | Fault |
-| 4 | Flash |
+| 1 | SelfTest mode |
+| 2 | Work mode |
+| 3 | Stop mode |
 
 ### MPPT state (15202)
 
 | Value | Meaning |
 |-------|---------|
 | 0 | Stop |
-| 1 | Start |
-| 2 | Normal work |
-| 3 | MPPT limit |
-| 4 | Float |
+| 1 | MPPT |
+| 2 | Current limiting |
 
 ### Charging state (15203)
 
 | Value | Meaning |
 |-------|---------|
 | 0 | Stop |
-| 1 | Precharge |
-| 2 | CC (constant current) |
-| 3 | CV (constant voltage) |
-| 4 | Float |
-| 5 | Current derating |
+| 1 | Absorb charge |
+| 2 | Float charge |
+| 3 | EQ charge (equalization) |
 
 ### Inverter workstate (25201)
 
@@ -123,6 +124,14 @@ all of them in one response when asked.
 | 5 | Stop |
 | 6 | GridCharging |
 
+> **Note:** Earlier versions of this file and the monitor script had
+> incorrect values for 15201–15203. They were originally derived from
+> a misreading of the protocol document. If you ran the script before
+> the 2026-09-10 fix, you may have seen "Standby", "Charging",
+> "Float" etc. where the correct values are "SelfTest mode", "Work
+> mode", "Float charge". The protocol doc and the live readings agree;
+> the old decode tables did not.
+
 ## Notes on this unit
 
 - Battery voltage grade is 24 V (24V battery system).

+ 13 - 14
must_pv1800_monitor.py

@@ -657,32 +657,31 @@ def s16(v: int) -> int:
 
 
 # ---------------------------------------------------------------------------
-# Decoded value tables (from PH1800/PV1800/EP1800/PV3500/EP3500 protocol v1.4.15)
+# Decoded value tables
 # ---------------------------------------------------------------------------
+# Cross-checked against the official protocol document
+# `PH1800 PV1800 EP1800 PV3500 EP3500 RS485 Modbus RTU communication
+# Protocol 1.4.15.xlsx` (taHC81/MUST-ESPhome repo; the same document
+# shared on Scribd as document 881604771).
 
 CHARGER_WORKSTATE = {
     0: "Initialization mode",
-    1: "Standby",
-    2: "Charging",
-    3: "Fault",
-    4: "Flash",
+    1: "SelfTest mode",
+    2: "Work mode",
+    3: "Stop mode",
 }
 
 MPPT_STATE = {
     0: "Stop",
-    1: "Start",
-    2: "Normal work",
-    3: "MPPT limit",
-    4: "Float",
+    1: "MPPT",
+    2: "Current limiting",
 }
 
 CHARGING_STATE = {
     0: "Stop",
-    1: "Precharge",
-    2: "CC",
-    3: "CV",
-    4: "Float",
-    5: "Current derating",
+    1: "Absorb charge",
+    2: "Float charge",
+    3: "EQ charge",
 }
 
 INVERTER_WORKSTATE = {