- 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>
TEST-23 showed 'No meter reading for 30 seconds, over the limit of 30
seconds': the age is 30.4 s, which rounds to the limit. The limit alone is
always true at the moment the line is logged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LyR88rXETvwhTgx6yHE39p
- Every WARNING/ERROR line that reported a safety reason (direction, delivery,
stuck meter, stale reading, peak guard, circulation, over-rating) now ends in
the reason's code (messages.reason_code()). The reason itself, figures and
limits included, is on a DEBUG line right after it and in the action log.
- The reasons and state.json are unchanged, so an old state file loads and
shows the same way: every saved reason opens with its code.
- test_messages part 6 checks every WARNING+ line at 25 words as logged; nine
non-safety families are listed with a reason and capped. The byte pin in
test_watchdog now pins the meaning, in order.
- The meter logs one WARNING per quiet episode, and INFO when back, so the red
row's "the add-on log shows why" holds. The Why line past the hold names
the missing reading. Action log: "25 engagements", "Shadow mode off: ...".
No trigger, latch, threshold, log level, notification id, cadence, row colour
or banner order changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LyR88rXETvwhTgx6yHE39p