From d48c6b971dcdd06c520c429cc0498c4dd3ef0603 Mon Sep 17 00:00:00 2001 From: glenn schrooyen Date: Wed, 2 Sep 2026 15:02:58 +0200 Subject: [PATCH] DEV-02: correct the operator instruction the latch rename made wrong MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HANDOVER.md told an operator to "delete `sign_tripped` from /data/state.json" to clear a sign-disagreement trip by hand. After this card that key is a FOSSIL: the live latch is `unit//sign_tripped`, and the flat one is left in the file only so a rollback finds its latch and is never read again. Following the old instruction would delete a key that clears nothing, on the one path an operator reaches while staring at a FAILSAFE banner - so the instruction would look like it had failed. DOCS.md's §SAFETY-02 section named the file but not the key; it now names both, and says why there is one per inverter. No code change; the suite is unaffected and green. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU --- HANDOVER.md | 12 +++++++++++- goodwe_controller/DOCS.md | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/HANDOVER.md b/HANDOVER.md index 192db71..9364ae3 100644 --- a/HANDOVER.md +++ b/HANDOVER.md @@ -83,7 +83,17 @@ rejected. ⚠️ **If you are testing the failsafe by hand, note that stopping and starting the add-on will not clear a trip.** That is the point of it; use the *Start / stop -control* button twice, or delete `sign_tripped` from `/data/state.json`. +control* button twice, or delete the trip from `/data/state.json`. + +⚠️ **DEV-02 renamed that key and the old name is now a fossil.** There is one +`SignWatchdog` per inverter, so the latch lives under +`unit//sign_tripped` — `unit/inverter-a/sign_tripped` on a +single-inverter site. The pre-DEV-02 flat `sign_tripped` is still written in +the file on purpose (so a rollback finds its latch) and is **never read again**, +so deleting it clears nothing. An install upgrading is migrated on first start, +and if the latch cannot be made to survive that migration the controller +re-arms it from the old key and says so in the log rather than coming up +disarmed. ⚠️ `test_loop.py` takes about **95 seconds** (measured 93 s) and that is not a bug. It drives the real control loop, which sleeps 1 s a tick, eight times over, to prove a diff --git a/goodwe_controller/DOCS.md b/goodwe_controller/DOCS.md index 850a93f..862553e 100644 --- a/goodwe_controller/DOCS.md +++ b/goodwe_controller/DOCS.md @@ -306,7 +306,9 @@ does. That is deliberate on both counts: always vanishes the instant the trip works. A watchdog that took that as proof the fault was over would hand the inverter straight back to the loop that was driving the wrong way, three minutes later, forever. -- The trip is written to `/data/state.json` and restored on startup. Restarting +- The trip is written to `/data/state.json` — under + `unit//sign_tripped`, one key per inverter since DEV-02, so a trip + caused by one inverter cannot latch another — and restored on startup. Restarting the add-on is the first thing most people try when they see a red banner, and a latch that a restart clears would bring the controller back **armed, into the same fault, unattended** — and under a Supervisor that restarts a crashed add-on