SAFETY-118: read the peak forecast in its own unit
peak_forecast_entity is read through pv.watts() by its unit_of_measurement; the abs(raw) < 50 size rule is gone. No unit or a non-power unit means the forecast is not used, with one warning per cause. The validator no longer claims a kW sensor is taken as watts for this entity. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
780c1f67bb
commit
f0b4e68e49
@@ -93,12 +93,12 @@ def watts(state: dict | None) -> tuple:
|
||||
unknown" are different claims and the page has to be able to make the first.
|
||||
|
||||
⚠️ THE UNIT IS READ OFF THE ENTITY AND NOT ASSUMED, AND THERE IS NO
|
||||
MAGNITUDE HEURISTIC. `read_inputs()` guesses kW-or-W for
|
||||
`peak_forecast_entity` with `abs(raw) < 50`, which is safe there because
|
||||
nobody's quarter-hour demand forecast is 50 W. It is NOT safe here: 30 W of
|
||||
real production at dusk is an ordinary reading, and that heuristic would
|
||||
publish it as 30 kW - a fabricated number, in the channel whose entire
|
||||
purpose is to be believed a week later. A sensor whose unit this cannot read
|
||||
MAGNITUDE HEURISTIC. 30 W of real production at dusk is an ordinary reading,
|
||||
and a "small number means kW" rule would publish it as 30 kW - a fabricated
|
||||
number, in the channel whose entire purpose is to be believed a week later.
|
||||
SAFETY-118 removed the last such rule, on `peak_forecast_entity`, for the
|
||||
same reason (DECISIONS/SAFETY-118-peak-forecast-unit.md): the peak forecast
|
||||
now reads through this function too. A sensor whose unit this cannot read
|
||||
is REFUSED rather than guessed at.
|
||||
"""
|
||||
if state is None:
|
||||
@@ -126,6 +126,24 @@ 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`.
|
||||
"""
|
||||
if state is None:
|
||||
return None
|
||||
raw = str(state.get("state", "")).strip()
|
||||
if raw.lower() in BAD_STATES:
|
||||
return None
|
||||
try:
|
||||
float(raw)
|
||||
except ValueError:
|
||||
return None
|
||||
unit = str((state.get("attributes") or {}).get(UNIT_KEY) or "").strip()
|
||||
return None if unit in WATTS_PER else unit
|
||||
|
||||
|
||||
# --- TEL-12: the ROSTER, and the SITE figure over it --------------------------
|
||||
|
||||
def entities(opts: dict) -> tuple:
|
||||
|
||||
Reference in New Issue
Block a user