UX-11 review: restored stops log their figures to events, the quiet-meter WARNING is rate-limited
- After a restart, each restored stop (direction per inverter and site, delivery, circulation) also writes its saved reason to the action log. log_level defaults to info and events starts empty, so the DEBUG evidence alone left the figures only in state.json. - A flapping meter (ha_signed under a flat load, 42-97 s between changes) logs at most one WARNING/INFO pair per 10 minutes, with the episodes in between at DEBUG. - LONG_LINE_OK refuses any key whose text is a safety reason. - test_watchdog keeps the byte pin beside the meaning pin, since the text did not change. - DOCS says the DEBUG line needs log_level debug. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1227,7 +1227,9 @@ check(f"UX-11: no WARNING+ line runs over {LINE_WORDS} words as logged, except "
|
||||
f"the {len(LONG_LINE_OK)} listed families, and none of them is a safety "
|
||||
f"reason (cap {LONG_LINE_CAP})",
|
||||
len(LONG_LINE_OK) <= LONG_LINE_CAP
|
||||
and not any("reason_code" in k for k in LONG_LINE_OK))
|
||||
and not any("reason_code" in k
|
||||
or TEXT.get(k) in SAFETY_REASONS.values()
|
||||
for k in LONG_LINE_OK))
|
||||
check(f"...and every listed family still runs long, so the list only shrinks "
|
||||
f"(no longer long: {sorted(set(LONG_LINE_OK) - _long_seen)})",
|
||||
set(LONG_LINE_OK) <= _long_seen)
|
||||
@@ -1397,6 +1399,7 @@ import logging # noqa: E402
|
||||
from app import hass as _hass, p1 as _p1, validate as _validate, web as _web # noqa: E402
|
||||
from app.arbiter import Claim # noqa: E402
|
||||
from app.main import Controller, why_key # noqa: E402
|
||||
from app import main as _main # noqa: E402
|
||||
|
||||
|
||||
class _Rec(logging.Handler):
|
||||
@@ -1695,7 +1698,12 @@ def _meter_at(age_s):
|
||||
|
||||
|
||||
def _quiet_episodes():
|
||||
for age in (1, 40, 45, 50, 1, 2, 60, 65):
|
||||
# Two quiet episodes close together, then a third 10 minutes on.
|
||||
for age in (1, 40, 45, 50, 1, 2, 60, 65, 1):
|
||||
_meter_at(age)
|
||||
asyncio.run(_c.read_inputs())
|
||||
_c._meter_quiet_warned -= _main.METER_QUIET_REPEAT_S
|
||||
for age in (40, 45, 1):
|
||||
_meter_at(age)
|
||||
asyncio.run(_c.read_inputs())
|
||||
|
||||
@@ -1704,9 +1712,13 @@ _mq = [r for r in _captured("goodwe", _quiet_episodes)
|
||||
if "meter" in r.getMessage().lower()]
|
||||
_mq_warn = [r.getMessage() for r in _mq if r.levelno == logging.WARNING]
|
||||
_mq_info = [r.getMessage() for r in _mq if r.levelno == logging.INFO]
|
||||
_mq_dbg = [r.getMessage() for r in _mq if r.levelno == logging.DEBUG]
|
||||
check(f"a meter that goes quiet logs one WARNING per episode, not per cycle, "
|
||||
f"and one INFO when readings return ({_mq_warn}, {_mq_info})",
|
||||
len(_mq_warn) == 2 and _mq_info == ["Meter readings are back."]
|
||||
f"and one INFO when readings return, and a flapping meter at most one "
|
||||
f"pair per {_main.METER_QUIET_REPEAT_S:.0f} s ({_mq_warn}, {_mq_info}, "
|
||||
f"{_mq_dbg})",
|
||||
len(_mq_warn) == 2 and _mq_info == ["Meter readings are back."] * 2
|
||||
and len(_mq_dbg) == 2
|
||||
and _mq_warn[0] == "No meter reading for over 30 seconds, so control "
|
||||
"waits and then sets the battery to 0 W."
|
||||
and len(words(_mq_warn[0])) <= LINE_WORDS)
|
||||
@@ -1763,6 +1775,13 @@ check("...each ERROR line at start is one plain sentence with the code, at "
|
||||
and any(m.endswith(f": {messages.NO_REASON_SAVED}.") for m in _rs_err))
|
||||
check("...and the saved text, figures and all, is on a DEBUG line beside it",
|
||||
all(any(t in m for m in _rs_dbg) for t in _OLD.values()))
|
||||
# UX-11 review: `log_level` defaults to info and `events` starts empty, so the
|
||||
# saved figures also go on the action log, where `status` shows them.
|
||||
_rs_ev = _restart[0].events if _restart else []
|
||||
check(f"...and in the action log, which an installer reads at the default "
|
||||
f"log level ({len(_rs_ev)} events)",
|
||||
all(any(t in e for e in _rs_ev) for t in _OLD.values())
|
||||
and any(e.endswith(messages.NO_REASON_SAVED) for e in _rs_ev))
|
||||
|
||||
# UX-11 item 4: the action log's clamp count and the shadow-off entry.
|
||||
_main_src = (APP / "main.py").read_text(encoding="utf-8")
|
||||
|
||||
Reference in New Issue
Block a user