MAINT-14: maintenance with no SoC reading: charge times out, drain holds at 0 W #182

Merged
admin merged 3 commits from MAINT-14 into release/1.0 2026-10-08 22:50:53 +02:00
Owner

With no SoC reading, a maintenance charge never ended and a drain kept discharging at full power.

  • Charge: the timeout and the 7-day backstop still run. Failure = MAINT-13 back-off and its one notice. Last SoC seen >= target-3 counts as done.
  • Drain: holds at 0 W (like HOLD), the 12 h timeout still runs. SoC back: normal.
  • Two plain log lines, once per episode (15 min threshold).
  • With a SoC reading nothing changes: 380,000 seeded ticks (N=1 and N=2) are identical to release/1.0.

See DECISIONS/MAINT-14-no-soc-in-maintenance.md. Tests: test_maint14.py (23 mutations, all killed). One existing check in test_maintenance.py changed on purpose (no-SoC drain is now 0 W).

Do not merge: the TEST-23 rig test comes first.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC

With no SoC reading, a maintenance charge never ended and a drain kept discharging at full power. - Charge: the timeout and the 7-day backstop still run. Failure = MAINT-13 back-off and its one notice. Last SoC seen >= target-3 counts as done. - Drain: holds at 0 W (like HOLD), the 12 h timeout still runs. SoC back: normal. - Two plain log lines, once per episode (15 min threshold). - With a SoC reading nothing changes: 380,000 seeded ticks (N=1 and N=2) are identical to release/1.0. See DECISIONS/MAINT-14-no-soc-in-maintenance.md. Tests: test_maint14.py (23 mutations, all killed). One existing check in test_maintenance.py changed on purpose (no-SoC drain is now 0 W). Do not merge: the TEST-23 rig test comes first. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
admin added 1 commit 2026-10-08 20:37:09 +02:00
MAINT-14: maintenance with no SoC reading: charge times out, drain holds at 0 W
checks / unit (pull_request) Successful in 35m13s
infra-pin / fresh (pull_request) Successful in 1s
f39e52efd3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
admin added 1 commit 2026-10-08 21:25:38 +02:00
MAINT-14: accurate no-level wording per phase; name the limit that ended the charge
checks / unit (pull_request) Successful in 34m54s
infra-pin / fresh (pull_request) Successful in 1s
ef35f4b925
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
admin added 1 commit 2026-10-08 22:14:28 +02:00
MAINT-14 review: tests for a HOLD episode after a no-SoC charge, a MAINT-13 state file, and a true twin site at N=2
checks / unit (pull_request) Successful in 34m56s
infra-pin / fresh (pull_request) Successful in 1s
61a61941bb
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Owner

MAINT-14 review (round 2, head ef35f4b; reviewer test push 61a6194)

Router FAIL points from round 1:

  • a. HOLD 15-min line: fixed. HOLD now says "The hold waits for the level to come back." with no time limit; drain and charge keep "The time limit of the {phase} still applies." (maintenance.py _no_soc).
  • b. 7-day backstop with the gate shut: fixed. The reason now says "after the 7-day limit"; the charge-time limit says "after 36 h of charging time".
  • c. Tests: fixed. Section 5b of test_maint14.py covers both.

My checks:

  • Full suite in goodwe-addon-checks:1, --network none: 69 pass, 0 fail.
  • Differential trace re-run myself on 8a17711 and ef35f4b: same hash (ee08fc44...), logs byte-identical. That trace never reaches a stalled or timed-out charge (0 "charge stuck", 0 "takes no more charge"), and those are the paths whose _charge_account changed. A second trace caps the SoC at 90-100 % (60 seeds, 570k ticks, 107 charge failures, 349 stall completions). It is also identical on both trees. Leaving last out is sound: only _no_soc reads it.
  • Downstream (main.py): a 0 W DRAIN is skipped by every place that adds a drain floor or drain pin (they all need setpoint_w > 0). At N=1 a peak floor outranks it, the same as HOLD (SAFETY-86). The maint_failed notice text is unchanged.

Findings:

  1. (low, tests; fixed in 61a6194) 3 test gaps let mutations survive. (R1) _enter not resetting the no-SoC episode survived: added "charge done with no SoC, then HOLD with no SoC: the HOLD line is said". (R7) reading trk["last"] instead of .get survived, and would crash on a MAINT-13 state file: added a restart test from a MAINT-13 charge_track (best 99, no last), which fails at 36 h with no crash. The N=2 "B unchanged" check gave both copies of B the same plan; it now compares against a real twin site with A healthy.
  2. (low, wording, not changed) The new "counts as done" line says "holding 120 min to balance". That is a long time in minutes (UX-08). It matches the existing MAINT-13 lines and the option's unit, so I left it for one sweep of all of them.
  3. (info) A phase name that is not known, with no SoC, now goes down the charge path: it says "The time limit of the banana still applies." and fails after 36 h. Before, it stayed in CHARGE for ever. This is better than before and is only reached from a corrupt state file.
  4. (info) HOLD with no SoC still never ends (MAINT-15). The mutation that makes it end survives, which is expected.

Mutations (mine, not in the dev's 26): R1 to R9. 8 killed; R8 (HOLD ends with no SoC) survives, which is expected since it is out of scope. Details are in the review report.

**MAINT-14 review (round 2, head ef35f4b; reviewer test push 61a6194)** Router FAIL points from round 1: - a. HOLD 15-min line: **fixed**. HOLD now says "The hold waits for the level to come back." with no time limit; drain and charge keep "The time limit of the {phase} still applies." (`maintenance.py` `_no_soc`). - b. 7-day backstop with the gate shut: **fixed**. The reason now says "after the 7-day limit"; the charge-time limit says "after 36 h of charging time". - c. Tests: **fixed**. Section 5b of `test_maint14.py` covers both. My checks: - Full suite in `goodwe-addon-checks:1`, `--network none`: 69 pass, 0 fail. - Differential trace re-run myself on 8a17711 and ef35f4b: same hash (ee08fc44...), logs byte-identical. That trace never reaches a stalled or timed-out charge (0 "charge stuck", 0 "takes no more charge"), and those are the paths whose `_charge_account` changed. A second trace caps the SoC at 90-100 % (60 seeds, 570k ticks, 107 charge failures, 349 stall completions). It is also identical on both trees. Leaving `last` out is sound: only `_no_soc` reads it. - Downstream (`main.py`): a 0 W DRAIN is skipped by every place that adds a drain floor or drain pin (they all need `setpoint_w > 0`). At N=1 a peak floor outranks it, the same as HOLD (SAFETY-86). The `maint_failed` notice text is unchanged. Findings: 1. (low, tests; fixed in 61a6194) 3 test gaps let mutations survive. (R1) `_enter` not resetting the no-SoC episode survived: added "charge done with no SoC, then HOLD with no SoC: the HOLD line is said". (R7) reading `trk["last"]` instead of `.get` survived, and would crash on a MAINT-13 state file: added a restart test from a MAINT-13 `charge_track` (best 99, no `last`), which fails at 36 h with no crash. The N=2 "B unchanged" check gave both copies of B the same plan; it now compares against a real twin site with A healthy. 2. (low, wording, not changed) The new "counts as done" line says "holding 120 min to balance". That is a long time in minutes (UX-08). It matches the existing MAINT-13 lines and the option's unit, so I left it for one sweep of all of them. 3. (info) A phase name that is not known, with no SoC, now goes down the charge path: it says "The time limit of the banana still applies." and fails after 36 h. Before, it stayed in CHARGE for ever. This is better than before and is only reached from a corrupt state file. 4. (info) HOLD with no SoC still never ends (MAINT-15). The mutation that makes it end survives, which is expected. Mutations (mine, not in the dev's 26): R1 to R9. 8 killed; R8 (HOLD ends with no SoC) survives, which is expected since it is out of scope. Details are in the review report.
admin merged commit bf3ac7998c into release/1.0 2026-10-08 22:50:53 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/goodwe-addon#182