48 lines
2.3 KiB
Markdown
48 lines
2.3 KiB
Markdown
# MAINT-15 - the balancing hold ends on time with no SoC reading
|
|
|
|
**Status: for review.** Tests: `test_maint15.py`. No option added.
|
|
|
|
**The fault.** `step()` sent every tick with no SoC to `_no_soc()`, and for
|
|
HOLD that returned 0 W without the time check. A hold that lost its reading
|
|
never ended: `last_completed` was never written and the next due date never
|
|
moved. Harmless for power (0 W), but the cycle was stuck. This was left open
|
|
in MAINT-14.
|
|
|
|
## Rule
|
|
|
|
1. **HOLD ends at `hold_min` whether or not there is a reading.** One helper,
|
|
`Maintenance._hold()`, holds the time check and is used by both paths. When
|
|
the time is up it writes `last_completed`, goes IDLE and logs the same
|
|
"cycle COMPLETE" line. Before the time is up it commands 0 W as before.
|
|
2. **Text.** The 15-min "no battery level" line in HOLD now reads "The hold
|
|
still ends at its normal time." Still once per episode.
|
|
|
|
## Why
|
|
|
|
HOLD is reached only after the charge counted as done. Every entry into HOLD
|
|
is in `step()` or `_no_soc()` and follows a charge that reached the target,
|
|
stalled near full (MAINT-13) or timed out near full (MAINT-13/14). Nothing else
|
|
sets the phase to HOLD (`_enter(HOLD` has four call sites, all after a done
|
|
charge). The hold is a wait for the BMS to balance; it never needed the level.
|
|
So a hold that ends with no reading is a completed cycle. The "cycle COMPLETE"
|
|
line is true without a reading: it names minutes of hold, not a level.
|
|
|
|
## Cost
|
|
|
|
- If the level was lost during the hold, the cycle is recorded as complete
|
|
without anyone seeing the final level. The charge had counted as done, so this
|
|
is the same trust MAINT-14 already gives a charge that ends with no reading.
|
|
|
|
## What this does not cover
|
|
|
|
- It does not check that the pack is still full at the end of the hold.
|
|
- It does not say why the reading was lost.
|
|
- With a reading, nothing changes. `test_maint15.py` section 7 compares the new
|
|
HOLD tick by tick with a frozen copy of the release/1.0 HOLD branch (phase,
|
|
setpoint, owner, events, `last_completed`) at four `hold_min` values. A wider
|
|
trace of the whole cycle (800 seeded runs against db9e231) was run outside the
|
|
repo; its script and log are kept under `scratch/MAINT-15/` of the dev
|
|
workspace, not in this repository.
|
|
- A state file written by an older version with `phase: hold` loads and ends on
|
|
time; the file is not changed in format.
|