SAFETY-90 review: count the start-up seconds like a gap

While the add-on is down the batteries are at 0 W (it sets 0 W when it
stops; the ESP32 watchdog after 30 s), so the import before its first
reading was the house, not the aim. Those seconds now count at
gap_w(limit, the import seen first), and after a restart the restored
reading's held 30 s is topped up the same way. Status row: "counted as
high use". Tests take the pre-start import as the house (batteries at
0 W) and add restarts of 10/60/150 s with a restored averager.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Claude (SAFETY-90 review)
2026-10-05 12:24:33 +02:00
parent 9d3fbe1be9
commit 8dfe91e1d2
5 changed files with 120 additions and 43 deletions
@@ -22,7 +22,7 @@ resort (SAFETY-91 test, O2).
up to `gap_w` too. The guard then grades the quarter as usual, so it is not
blind and gives what keeps the quarter at the aim.
- **The bound.** The count is at or above the true import as long as, during
the gap, the house load stayed at or under the higher of the loads seen just
the gap, the house load (less solar) stayed at or under the higher of the loads seen just
before and just after it, or under the limit, and the batteries did not
start charging (during a gap they hold their last command, then go to 0 W).
It never counts the gap below the limit. A load that rises above all three
@@ -33,14 +33,21 @@ resort (SAFETY-91 test, O2).
- **While the gap lasts** nothing changes: the reading is too old to steer by,
the guard is blind (floor 0 W) and the "inputs missing" stop sets 0 W, as
before.
- **Before the first reading** (start-up or restart mid-quarter) nothing is
known, not even the house load, so a conservative count has no basis: the
connection rating would make every restart drain at full power and raise
"Load too high". Those seconds count **at the aim**, so the guard keeps the
rest of the quarter on the aim, and the page says so: the status row "Peak
guard: part of this 15-minute period was not measured, counted as on
target" and the home line "Part of this 15-minute period was not measured." /
"Een deel van dit kwartier is niet gemeten." until the quarter ends.
- **Before the first reading** (start-up or restart mid-quarter) the
add-on was down, so the batteries were at 0 W (it sets 0 W when it stops,
the ESP32 watchdog after 30 s). Those seconds count like a gap, at
`gap_w(the limit, the import seen first)`; after a restart the restored
reading's held `meter_max_age_s` is topped up the same way. The bound is
the gap's, with only the "after" side known. A load the batteries cannot
make up then raises "Load too high", which is true: that quarter is going
over. The page says so: the status row "Peak guard: part of this
15-minute period was not measured, counted as high use" and the home line
"Part of this 15-minute period was not measured." / "Een deel van dit
kwartier is niet gemeten." until the quarter ends.
*Review:* the first version counted them at the aim, with "nothing is
known" as the reason. The first reading does show the load, and with the
batteries at 0 W the import was that load, not the aim: a 60 s restart
during a 6500 W HOLD landed 3653 W against 3450 W.
- The bill record (`quarter_blocks`) is unchanged: it still banks only what
was measured. The estimate steers the guard and is never banked.
- The action log gets one `PEAK_GUARD_GAP` row per gap, with the seconds and
@@ -61,7 +68,8 @@ it, gap starting 300 s in; 10 s battery lag; aim 3450 W):
| gap across the edge, next quarter, N=1 / N=2 | 4100.0 / 3621.2 | 3446.3 / 3382.2 |
| house 3000 -> 6500 W inside a 60 s gap, N=1 | 5255.6 | 3368.3 |
| house 6500 -> 2000 W late in a 5 min gap, N=1 | 3629.2 | 3145.1 |
| start-up 450 s into the quarter, N=1 (first half at the aim) | 4975.0 | 3450.0 |
| start-up 450 s in, N=1, house 5000 W (batteries at 0 W before it) | 5000.0 | 3450.0 |
| restart, down 60 s / 150 s, N=1, house 6500 W | 4039.1 / 5483.3 | 3450.0 / 3450.0 |
| meter never drops, N=1 and N=2 | | rows identical |
**Not changed.** The late-reading edge (SAFETY-91 test, O1): a reading late by