Files
goodwe-addon/goodwe_controller/DECISIONS/SAFETY-126-landing-error-is-not-an-overrun.md
T
glenn schrooyenandClaude a66a7f1a0f
checks / unit (pull_request) Successful in 18m11s
infra-pin / fresh (pull_request) Successful in 2s
SAFETY-126 round 2: state what the 10 W tolerance costs; test the latch reset
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>
2026-10-31 11:52:27 +01:00

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_w 0, 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.