UX-08 phase 2a: short, plain notifications, and a ratchet for the rest
Every HA notification the add-on raises now has a title of at most 5 everyday words and a one-sentence body; a red alarm may use three so no action is lost. The texts live in app/messages.py, the rule in STYLE.md, and the detail that moved out in DOCS.md "Notifications", which each body links to. No notification_id, trigger or cadence changed. test_messages.py enforces the rule on every notification, fails any notification worded outside app/messages.py, and ratchets the kinds not yet rewritten (rows, banners, refusals, logs, options) through a shrinking allowlist of 200. Six tests re-pinned from prose to meaning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LyR88rXETvwhTgx6yHE39p
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
2503de124e
commit
50ccea3dd7
@@ -22,6 +22,7 @@ from datetime import datetime, timedelta, timezone
|
||||
|
||||
from named_absence import nth, present
|
||||
|
||||
from app import messages # noqa: E402
|
||||
from app.watchdog import (
|
||||
SignWatchdog, SignWatchdogConfig, loop_is_following,
|
||||
)
|
||||
@@ -1105,12 +1106,22 @@ check("...under a fixed notification_id of its own, so a second episode "
|
||||
for c in _notes1 + _notes2)
|
||||
and len({c[2]["notification_id"] for c in _notes1 + _notes2}) == 1)
|
||||
_msg = nth(_notes2, 0)[2]["message"]
|
||||
|
||||
|
||||
def _says_three(m):
|
||||
"""UX-08: the three things only this alarm can say, in its plain words
|
||||
(messages.circulating): the meter cannot see it, control is stopped at
|
||||
0 W, and if the grid does not move a person at the isolator is next."""
|
||||
return ("meter cannot see this" in m and "Control is stopped" in m
|
||||
and "every inverter is set to 0 W" in m and "isolator" in m
|
||||
and "if the grid power does not change" in m)
|
||||
|
||||
|
||||
check("...and the message tells the operator the three things only this alarm "
|
||||
"can: that the meter cannot see it, that control has been stopped, and "
|
||||
"that if the grid reading does not move afterwards one inverter is no "
|
||||
"longer listening and a human at the isolator is the last actuator",
|
||||
"METER CANNOT SEE" in _msg and "CONTROL HAS BEEN STOPPED" in _msg
|
||||
and "isolator" in _msg)
|
||||
_says_three(_msg))
|
||||
check("...and it does not raise the same card on every cycle - a per-PROCESS "
|
||||
"flag, deliberately not persisted, is what makes 'has a human been shown "
|
||||
"this' a different question from 'is this site tripped'",
|
||||
@@ -1262,8 +1273,8 @@ check("PRECONDITION: both runs actually tripped and actually raised the card, "
|
||||
and len(_notes_g) == 1 and len(_notes_s) == 1)
|
||||
|
||||
# --- AC 4: THE ATTRIBUTION ITSELF -------------------------------------------
|
||||
_WHO_G = "Right now garage is discharging while shed charges."
|
||||
_WHO_S = "Right now shed is discharging while garage charges."
|
||||
_WHO_G = "garage was discharging while shed was charging"
|
||||
_WHO_S = "shed was discharging while garage was charging"
|
||||
check("⚠️ THE ALARM NAMES THE TWO PACKS AND SAYS WHICH WAY EACH ONE IS PULLING. "
|
||||
"`circulation.py` calls this the first thing somebody woken at 3 a.m. "
|
||||
"needs and impossible to reconstruct from the watts alone, and until this "
|
||||
@@ -1284,12 +1295,14 @@ check("...and the RESTING pack is not named. `cellar` is on the roster, is read
|
||||
"beside a 6 kW loop is not reported as one of its two participants",
|
||||
"cellar" not in _msg_g and "cellar" not in _msg_s
|
||||
and _cg.inverters[2].batt == _REST_W)
|
||||
check("...and the sentence sits with the figure, not instead of it: the same "
|
||||
"card still carries the watts, the window and the three things only this "
|
||||
"alarm can say",
|
||||
all("CIRCULATING_POWER" in m and "METER CANNOT SEE" in m
|
||||
and "CONTROL HAS BEEN STOPPED" in m and "isolator" in m
|
||||
for m in (_msg_g, _msg_s)))
|
||||
# UX-08: the watts and the window moved out of the card into the reason the
|
||||
# log line and the status row carry; the card keeps the three things.
|
||||
check("...and the sentence sits with the three things only this alarm can say, "
|
||||
"while the watts and the window stay in the reason behind it",
|
||||
all(_says_three(m) for m in (_msg_g, _msg_s))
|
||||
and all("CIRCULATING_POWER" in c.circ_wd.reason
|
||||
and "W measured going round" in c.circ_wd.reason
|
||||
for c in (_cg, _cs)))
|
||||
print()
|
||||
print(" the operator's press is the only way out, and it clears BOTH halves")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user