SAFETY-126: a landing error on the aim is not an overrun
During the night grid charge under the peak reserve the guard alarmed (ERROR PEAK_GUARD_FLOOR_LIMITED, "Battery stopped limiting the peak") and the Batteries "Why" said "The peak limit needs power" at quarter ends, while every quarter landed on the aim. The charge lands the period 0-7 W over the aim and excess_w()'s 900 / remaining turns that into tens of kW in the last second; with nothing able to give, check_peak_floor_limited() alarmed on any wanted > 0. Each cycle the guard wants power, _peak_landing() asks misses_aim(): with the batteries at 0 W, does the period end more than ALARM_MISS_W over the aim? If not, the decision is within_aim: no reserve alarm, no red peak row, no "Why" peak. The claim and the commands are unchanged. A real overrun under the reserve alarms on the same cycle as before. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
cc9bbeb73e
commit
40595e42ae
@@ -0,0 +1,42 @@
|
||||
# SAFETY-126 - a landing error on the aim is not an overrun
|
||||
|
||||
**Status: FIXED on release/1.0 (after 0.19.2).** Tests: `test_safety126.py`.
|
||||
|
||||
**Cause.** A grid charge under the peak limit is sized to land the 15-minute
|
||||
period on the aim (SAFETY-125), so the period ends 0-7 W over it. In the last
|
||||
second `peakguard.excess_w()` multiplies that by 900 / remaining (3 000 at
|
||||
0.3 s left, 90 000 at 0.01 s), so `decide()` wants tens of kW
|
||||
(`wanted > 0`, peakguard.py `decide()`). With every battery under the peak
|
||||
reserve that is floor-limited at 0 W, and `check_peak_floor_limited()`
|
||||
alarmed on it at once: SAFETY-87 graded only the case where another battery
|
||||
could give. With one battery able, the guard asked it for its rating for that
|
||||
cycle and the Batteries "Why" said "The peak limit needs power". The
|
||||
add-on's own charge is not the cause: `wanted` already counts it as
|
||||
stoppable.
|
||||
|
||||
**Rule.** Each cycle the guard wants power, `Controller._peak_landing()`
|
||||
asks `peakguard.misses_aim()`: with the batteries at 0 W from now on, does
|
||||
the period end more than `ALARM_MISS_W` (10 W) over the aim? This is
|
||||
`load_too_high()` with nothing to give, without `decide()`'s gain. If not, and
|
||||
no real miss was seen since the guard took hold, the decision is
|
||||
`within_aim`. Such a decision raises no reserve alarm (ERROR,
|
||||
notification, red row), no red "Load too high" row, no "Why" peak and
|
||||
no "Battery stopped limiting the peak" event hint. The claim, the floor and the
|
||||
commands are unchanged.
|
||||
|
||||
**Still alarms.** House load the batteries cannot cover under the reserve:
|
||||
the period would end over the aim with the batteries at 0 W, so the alarm
|
||||
fires on the same cycle as before (both under the reserve; a 6 500 W house
|
||||
during the night charge). SAFETY-87's case (others able, graded on the limit
|
||||
for `ALARM_HOLD_S`) and SAFETY-81's 'Load too high' notification are unchanged.
|
||||
A period heading at most 10 W over the aim no longer alarms with nothing able
|
||||
to give. That is SAFETY-81's landing tolerance. `misses_aim()` takes the house
|
||||
as meter plus batteries, so an export nets off. `decide()`'s projection counts
|
||||
offtake only. So a re-alarm while the loop's draw on held batteries covers the
|
||||
house with some export, and the period lands under the aim, is gone too
|
||||
(test_safety126.py part 2, modes off: 2 notifications, was 4).
|
||||
|
||||
**Not changed.** The one-cycle floor itself: at a period's last instant the
|
||||
guard still asks an able battery for its rating, or stops a charge, for a
|
||||
landing error. That is control, outside the alarm path. Raise a card if it
|
||||
should go.
|
||||
Reference in New Issue
Block a user