Files
goodwe-addon/goodwe_controller/DECISIONS/SAFETY-121-bound-every-quarter.md
T
glenn schrooyenandClaude Opus 5.5 24f31a9c3a
checks / unit (pull_request) Successful in 44m29s
infra-pin / fresh (pull_request) Successful in 1s
SAFETY-121 review: DECISIONS limits state the jitter spread and the slow-cycle case
The jittery-meter numbers depend on the draw (review: 4, 4, 5 of 11 at the
quarter edge; up to 4 quiet quarters at 20 s; first warning up to 61 min
later). Above about 40 s per cycle, a short bound can still use up the
budget when the wire changes hands every few cycles. Text only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:55:24 +02:00

5.7 KiB

SAFETY-121 - a recurring overload warns every quarter

Status: for review. Tests: test_safety119.py (parts 2, 4, 5, 6). Follows DECISIONS/SAFETY-119-bound-after-hand-back.md.

The defect (TEST-23, SAFETY-119 rig test F-1). 5 s meter, 2 x 2500 W, cap 5000 W, maintenance charge, no forecast, house 5100 W. bee7431 warned once in 70 min (04:31:01), then not at 04:45, 05:00 or 05:15. Base 75f0804 warned at every quarter start. The loop held the wire once a quarter, at its start, and was at its bound on 4 or 5 cycles. SAFETY-119's settle (12 cycles, 60 s at 5 s) covered all of them, and 5 cycles a quarter fit in its budget of 8 per 900 s.

Why the simulation said "every quarter". test_safety119.py fed the meter one cycle behind the battery reading (delay counts cycles: 5 s at a 5 s meter). Just after the loop leaves its rail, the guard's charge headroom (house = meter + battery) is then off by up to 5000 W, the charge pulls 2000 W, the guard steps in again, and the two chase each other: 8 to 10 hand-backs and about 20 bound cycles a quarter at 5 s (rig: 1 and 4-5). With the meter read in the same cycle (delay 0, the rig's shape) the sim gives the rig's numbers: 3 to 5 bound cycles a quarter at 5 s, all inside SAFETY-119's settle, and bee7431 warns in 0 to 2 of 7 quarters. The test now runs both shapes.

Decision. After a hand-back the loop's bound is hidden until 4 cycles (HANDBACK_CYCLES) and 22 s (SHORT_SPAN_S) have passed; across all hand-backs on at most 11 cycles (ROLLING_BOUND_CYCLES) in any 900 s. The budget no longer follows the cycle length, and the cycle length is not tracked. A stop ends the settle and keeps the budget. An over-rating always counts. Commands are unchanged.

Why it holds for any number of bound cycles a quarter. The settle is fixed: at most 3 cycles or 22 s after a hand-back, whichever is longer. A bound that lasts past it counts on its first cycle after it. So one hand-back a quarter, with the loop at its rail past the settle, warns in that quarter, whether it is 1 bound cycle or 100. A bound that never lasts past a settle counts once more than 11 are hidden within 900 s. Hidden are only shapes with at most 11 bound cycles in 900 s, each within 3 cycles or 22 s of a hand-back. That is the quarter-edge kick: in every steady-meter run below it is on the 1st to 3rd cycle after its hand-back (up to 30 s at a 30 s meter). In the rig's shape at 5 s the bound comes 30 to 55 s after the hand-back.

Sweep (goodwe-addon-checks:1, 2 h runs, scratch/SAFETY-121/dev/). Quarter edge = test_safety119 part 1 (house 800 W, cap 2500 W, no forecast). Overload = part 4 (2 x 2500 W, cap 5000 W, house 5050 or 5100 W, seeds 0-3). "Delay 1" is the old sim, "delay 0" the rig's shape.

meter quarter edge, runs with a warning (new / bee7431 / no fix) overload delay 1, quarters warned of 7 (new / bee7431 / no fix) overload delay 0, 5100 W (new / bee7431 / no fix)
1 s 0/70 / 0/70 / 68/70 7 / 7 / 7 7 / 7 / 7
2 s 0/70 / 0/70 / 39/70 7 / 7 / 7 7 / 7 / 7
3 s 0/70 / 0/70 / 40/70 7 / 7 / 7 7 / 7 / 7 (5050 W: 7 / 1-7 / 7)
5 s 0/70 / 0/70 / 40/70 7 / 7 / 7 7 / 0-2 / 7
10 s 0/70 / 0/70 / 40/70 7 / 7 / 7 7 / 0 / 7
15 s 0/70 / 0/70 / 40/70 7 / 4-7 / 7 no fix warns 0-1 (5300 W: 7 / 0 / 7)
20 s 0/60 / 0/60 / 30/60 7 / 5-7 / 7 no fix warns 0 (5300 W: 7 / 0 / 7)
30 s 0/60 / 0/60 / 30/60 7 / 3-5 / 7 no fix warns 0 (5300 W: 6-7 / 0 / 6-7)

Quarter-edge seeds: 1-30 with the meter in the same cycle, and 1-40 (1-30 at 20 and 30 s) with the test's 1-2 cycle delay. 5300 W: seeds 1-5. Commands identical to no fix and to bee7431 in all 1013 runs (these and the limits below). Choosing the numbers: the runs above were recorded without the fix and replayed through candidate rules; with 3, 4 or 5 cycles, budgets 9 to 13 met both cases at 1-30 s. 8 warns at the quarter edge (2 s, seed 25) and 14 misses quarters in the rig's shape (1 s, 5050 W), both checked in part 4. 11 is the middle, and 4 the middle of 3 to 5; with a jittery meter (below) 3 gave more false alarms, 5 more quiet quarters (replay).

First warning after one hand-back (the loop at its rail; later than no fix by): 11 s at 1 s, 22 s at 2 s, 24 s at 3 s, 25 s at 5 s (default), 30 s at 10 s, 45 s at 15 s, 60 s at 20 s, 90 s at 30 s, 180 s at 60 s. bee7431: 10, 20, 30, 40, 80, 90, 80, 120, 240 s. In the overload runs at 1 to 30 s, the first warning was at most 90 s later than without the fix.

Limits (measured, not fixed).

  • A meter that jitters by 30 % with cycle_floor_s 15 (11 seeds): with the test's 1-2 cycle meter delay the quarter edge warns on 2 of 11 seeds at 15 s, 2 at 20 s and 5 at 30 s (bee7431: 4, 0, 10; no fix: 11 each); with the meter in the same cycle on none (no fix: 10, 9, 11). The overload at 5100 W leaves up to 4 quiet quarters in a row at 15 and 20 s (bee7431: no warning at all on some seeds); at 5200 W at most 1. Its first warning came up to 61 min later than without the fix. The numbers depend on the jitter draw: the review's draw gave 4, 4 and 5 of 11 at the quarter edge (bee7431: 4, 1, 9) and up to 2 and 4 quiet quarters at 15 and 20 s.
  • With cycles over about 40 s, a bound that is never past a settle uses up 11 in 900 s only if the wire changes hands every few cycles; otherwise it is never counted (part 5 prints it at 60 s).
  • Hidden as designed: a real bound with the kick's shape (at most 11 cycles in 900 s, each within 3 cycles or 22 s of a hand-back).

Re-pinned. test_safety84 (all six) and test_safety87 (n1_crossing, n1_above, n1_charge_low): only OUTPUT_CLAMP log rows differ from bee7431 and from no fix; commands, claims, guard and phases are the same.