SAFETY-118: a missing peak forecast reading keeps the unit-fault state
checks / unit (pull_request) Successful in 40m19s
infra-pin / fresh (pull_request) Successful in 1s

A missing reading (unavailable, unknown, failed read, non-numeric) no longer
clears the fault: no false 'used again' INFO, no repeated WARNING, the status
row stays. Adds pv.has_reading(). DECISIONS wording fixed; tests added.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
glenn schrooyen
2026-10-16 18:19:44 +02:00
co-authored by Claude
parent f0b4e68e49
commit 7d52dc1c0f
4 changed files with 97 additions and 16 deletions
+14 -7
View File
@@ -126,19 +126,26 @@ def watts(state: dict | None) -> tuple:
return value * WATTS_PER[unit], unit
def unit_fault(state: dict | None):
"""SAFETY-118. `None` unless `state` holds a number whose unit cannot be
read in watts, then that unit (`""` for none). A missing, unavailable or
non-numeric state is a missing reading, not a unit fault, so it is `None`.
"""
def has_reading(state: dict | None) -> bool:
"""SAFETY-118. True when `state` holds a number, so its unit can be judged.
A missing, unavailable, unknown or non-numeric state is a missing reading."""
if state is None:
return None
return False
raw = str(state.get("state", "")).strip()
if raw.lower() in BAD_STATES:
return None
return False
try:
float(raw)
except ValueError:
return False
return True
def unit_fault(state: dict | None):
"""SAFETY-118. `None` unless `state` holds a number whose unit cannot be
read in watts, then that unit (`""` for none). `None` also means a missing
reading: use `has_reading()` to tell it from a good unit."""
if not has_reading(state):
return None
unit = str((state.get("attributes") or {}).get(UNIT_KEY) or "").strip()
return None if unit in WATTS_PER else unit