SAFETY-40 review: integrator-bound WARNING gets its own notification id
A later anti-windup notice could replace a write-path BUG SIGNAL notice
under the shared goodwe_output_clamp id (escalation ignores the budget).
The WARNING now uses goodwe_integrator_bound and points to DOCS; the
cadence sentence in DOCS is corrected. Tests pin both ids (red on fd14569).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
fd14569a71
commit
55a6d5dcdb
@@ -102,6 +102,9 @@ T0 = datetime(2026, 8, 30, 9, 0, 0, tzinfo=timezone.utc)
|
||||
# which is also the device rating, so this is the bound the alarm is written at.
|
||||
LIVE_MAX_W = 5000.0
|
||||
CLAMP_ID = "goodwe_output_clamp"
|
||||
# SAFETY-40: the integrator-bound WARNING has its own id, so it can never
|
||||
# replace a BUG SIGNAL notice still on screen.
|
||||
BOUND_ID = "goodwe_integrator_bound"
|
||||
|
||||
|
||||
def check(name, cond):
|
||||
@@ -461,7 +464,7 @@ def wired(grid, cycles=40, batt=0.0, track=True, **over):
|
||||
def clamp_notes(hass):
|
||||
return [d for dom, svc, d in hass.calls
|
||||
if (dom, svc) == ("persistent_notification", "create")
|
||||
and d.get("notification_id") == CLAMP_ID]
|
||||
and d.get("notification_id") in (CLAMP_ID, BOUND_ID)]
|
||||
|
||||
|
||||
# THE 10.3 RUNAWAY, replayed. "With the inverter switched off entirely, an
|
||||
@@ -500,8 +503,9 @@ print(f" the loop clamped on {ctl_r.clamp_wd.engagements} of {60} cycles, "
|
||||
f"notification(s)")
|
||||
check("AC 3: and it ALARMED - silently clipping this is the defect",
|
||||
ctl_r.clamp_wd.engagements > 0 and len(notes_r) >= 1)
|
||||
check("...with its own notification_id, not shared with any other guard",
|
||||
all(d["notification_id"] == CLAMP_ID for d in notes_r))
|
||||
check("...with its own notification_id, not shared with any other guard - "
|
||||
"on a default install the integrator bound's (SAFETY-40)",
|
||||
all(d["notification_id"] == BOUND_ID for d in notes_r))
|
||||
check("...one episode, re-asserted rather than one per cycle",
|
||||
ctl_r.clamp_wd.episodes == 1 and len(notes_r) < ctl_r.clamp_wd.engagements)
|
||||
# SAFETY-40: on a default install this runaway is the INTEGRATOR bound, so it
|
||||
@@ -1971,6 +1975,9 @@ notes_i = clamp_notes(hass_i)
|
||||
check("it still NOTIFIES (not suppressed), under a title that claims no bug",
|
||||
notes_i and all("integrator bound" in n["title"]
|
||||
and "exceeded" not in n["title"] for n in notes_i))
|
||||
check("...under its OWN notification_id, so it cannot replace a BUG SIGNAL "
|
||||
"notice still on screen",
|
||||
notes_i and all(n["notification_id"] == BOUND_ID for n in notes_i))
|
||||
check("...logged as a WARNING, not an ERROR",
|
||||
any(x.levelno == logging.WARNING and "anti-windup" in x.getMessage()
|
||||
for x in log_i)
|
||||
@@ -2003,7 +2010,8 @@ check("...and the 14 768 W rationale is still in its ERROR",
|
||||
for x in log_o))
|
||||
check("...under the 'exceeded the rating' title, with a red status row",
|
||||
clamp_notes(hass_o)
|
||||
and all("exceeded the rating" in n["title"] for n in clamp_notes(hass_o))
|
||||
and all("exceeded the rating" in n["title"]
|
||||
and n["notification_id"] == CLAMP_ID for n in clamp_notes(hass_o))
|
||||
and any(not c["warn"] and "OUTPUT CLAMP ENGAGED" in c["text"]
|
||||
for c in red_o))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user