Text only (DECISIONS, DOCS, CHANGELOG): a step load alarms on the same cycle as before; a steadily rising load alarms a little later; with peak_margin_w 0 a period can end up to 10 W over the limit without this alarm, as for 'Load too high' (SAFETY-81). Owner accepted 2026-10-31. test_safety126.py part 2: after a real overrun ends, _peak_landing()'s latch is reset and the night's later landings are quiet (review F3). Co-Authored-By: Claude <noreply@anthropic.com>
2.6 KiB
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. A step load alarms on the same cycle as before. SAFETY-87's case and SAFETY-81's 'Load too high' notification are unchanged.
What the 10 W tolerance costs (review, owner accepted 2026-10-31):
- A steadily rising load alarms a little later, once the projected miss passes 10 W (3 000 -> 4 000 W over 45 min: 56 s later). With the default 50 W margin the alarm still comes before the limit.
- With
peak_margin_w0, a period can end up to 10 W over the limit without this alarm, the tolerance 'Load too high' already accepts (SAFETY-81).
misses_aim() takes the house as meter plus batteries, so an export nets
off (decide()'s projection counts offtake only). A re-alarm while the loop's
draw on held batteries covers the house 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.