SAFETY-128 round 2: find late readings from the batteries, not the meter alone
checks / unit (pull_request) Successful in 26m50s
infra-pin / fresh (pull_request) Successful in 2s

Review B1: the meter fit took repeating house loads (ovens, a heat pump)
for late readings on healthy 1-2 s sites, about 9 % of the recorded
house. B2: at a 5 s meter it never ran. M1: no hysteresis. M2: an
unbounded check.

lateness.Delay now fits how long each battery's reading takes to show
its own request, which the house does not move, from the 1 s reads
(read_inputs -> Answer.watch). The meter fit stays for speed at 1-3 s
meters, but counts only when an ask was slow to start and no battery
fit said on time. Late from 9.5 s after 2 fits, on time under 6.5 s,
dropped after 120 s without a fit. Fits are bounded (a few ms).

Readings on time: no verdict in any reviewer scenario (22 shapes at
1/2/5 s meters, 7 harm runs) nor in 2 days of the recorded house at
1, 2 and 5 s ticks; digests equal to 77fe31b. Late: found 36-68 s after
the start at 1-2 s, about 3 min at 5 s. The row gives the batteries'
delay, or no figure while only the meter has shown it.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
This commit is contained in:
glenn schrooyen
2026-11-02 04:32:04 +01:00
co-authored by Claude
parent 09e1fbb898
commit d3f4f9f48b
5 changed files with 462 additions and 196 deletions
+8 -4
View File
@@ -3137,11 +3137,11 @@ class Controller:
if a.late_seen != self._late_logged:
self._late_logged = a.late_seen
if a.late_seen:
self.log_event(f"readings late ({a.delay_s:.0f} s) - holding",
self.log_event("readings late - holding",
hint=messages.hint("readings_late"))
_LOG.warning("Home Assistant readings arrive late, so control "
"holds the battery: READINGS_LATE.")
_LOG.debug("READINGS_LATE: the meter shows a power request "
"holds the batteries: READINGS_LATE.")
_LOG.debug("READINGS_LATE: the readings show a power request "
"%.0f s after it is sent.", a.delay_s)
else:
self.log_event("readings on time", hint=messages.hint(
@@ -3760,6 +3760,10 @@ class Controller:
else:
_LOG.debug("Meter readings are back.")
self.answer.watch(now_mono, [(inv.name, inv.standing_w(), inv.batt)
for inv in self.inverters], # SAFETY-128
sum(inv.standing_w() for inv in self.inverters),
self.grid)
if self.inputs_ok:
if self.inputs_bad_since is not None:
self.log_event("inputs recovered",
@@ -7384,7 +7388,7 @@ class Controller:
if self.answer.late_seen: # SAFETY-128
out.append({"ok": False, "warn": True, "id": "late",
"text": messages.row_readings_late(
self.answer.delay_s, self._late_zero)})
self.answer.shown_s, self._late_zero)})
# SAFETY-03. Red while an over-rating clamp is engaged (amber for the
# integrator bound, SAFETY-40), and the engagement COUNT is shown even