@@ -76,6 +76,38 @@ def _row_to_dict(row: tuple, columns: list[str]) -> dict[str, Any]:
7676 return dict (zip (columns , row ))
7777
7878
79+ # Working-mode status codes (Register 0) → human-readable label.
80+ # Source: EG4-18KPV-12LV Modbus protocol, Table 9 "Working modes definition".
81+ _STATE_LABELS = {
82+ 0x00 : "Standby" ,
83+ 0x01 : "Fault" ,
84+ 0x02 : "Programming" ,
85+ 0x04 : "PV on-grid" ,
86+ 0x08 : "PV charging battery" ,
87+ 0x0C : "PV charging battery + on-grid" ,
88+ 0x10 : "Battery on-grid" ,
89+ 0x14 : "PV + battery on-grid" ,
90+ 0x20 : "AC charge (grid → battery)" ,
91+ 0x28 : "PV + AC charge" ,
92+ 0x40 : "Battery off-grid" ,
93+ 0x80 : "PV off-grid" ,
94+ 0x88 : "PV charge + off-grid" ,
95+ 0xC0 : "PV + battery off-grid" ,
96+ }
97+
98+
99+ def _state_label (value ) -> str :
100+ """Return a human-readable label for a raw working-mode state value."""
101+ try :
102+ code = int (value )
103+ except (TypeError , ValueError ):
104+ return str (value )
105+ label = _STATE_LABELS .get (code )
106+ if label is None :
107+ return f"Unknown ({ code } )"
108+ return f"{ label } ({ code } )"
109+
110+
79111# ── endpoints ────────────────────────────────────────────────────────────────
80112
81113@app .get ("/api/status" )
@@ -105,6 +137,13 @@ def api_status():
105137 for row in cur .fetchall ()
106138 }
107139
140+ # Human-readable working-mode label alongside the raw state code.
141+ if "state" in registers :
142+ registers ["state_label" ] = {
143+ "value" : _state_label (registers ["state" ]["value" ]),
144+ "unit" : "" ,
145+ }
146+
108147 return {
109148 "snapshot_id" : snap_id ,
110149 "timestamp" : ts_aware .isoformat (),
@@ -285,6 +324,13 @@ def api_summary():
285324 "unit" : "°F" ,
286325 }
287326
327+ # Human-readable working-mode label alongside the raw state code.
328+ if "state" in registers :
329+ registers ["state_label" ] = {
330+ "value" : _state_label (registers ["state" ]["value" ]),
331+ "unit" : "" ,
332+ }
333+
288334 return {
289335 "snapshot_id" : snap_id ,
290336 "timestamp" : ts_aware .isoformat (),
0 commit comments