feat(application): integrate measured-load ingestion training and planner source
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
"""Minimal validity gates, not a claim of forecast accuracy or model ranking."""
|
||||
from math import isfinite
|
||||
|
||||
|
||||
def assess_family(family, *, minimum_steps=3):
|
||||
points=family.get('points',[])
|
||||
if len(points)<minimum_steps:
|
||||
return {'valid':False,'reason':'Forecast has too few intervals'}
|
||||
loads=[]
|
||||
for point in points:
|
||||
for key in ('loadW','pvW'):
|
||||
value=point.get(key)
|
||||
if isinstance(value,bool) or not isinstance(value,(int,float)) or not isfinite(value) or value<0:
|
||||
return {'valid':False,'reason':'Forecast contains missing or invalid power'}
|
||||
loads.append(point['loadW'])
|
||||
# A PV-only plant or confirmed shutdown may legitimately forecast zero load.
|
||||
# It must be explicit; missing observations filled with zero are not savings.
|
||||
if max(loads)==0 and family.get('zeroLoadConfirmed') is not True:
|
||||
return {'valid':False,'reason':'Unconfirmed all-zero load forecast; likely missing data, not zero electricity costs'}
|
||||
return {'valid':True,'reason':None,'loadMaximumW':max(loads),
|
||||
'loadZeroFraction':sum(v==0 for v in loads)/len(loads)}
|
||||
Reference in New Issue
Block a user