from pathlib import Path from tempfile import TemporaryDirectory import unittest from netplan_v4.forecast_quality import assess_family from netplan_v4.service import ingest,run_once from netplan_v4.store import PlannerStore from test_v4 import inputs,AT,AID class ForecastQualityTest(unittest.TestCase): def test_zero_load_not_free_energy_assumption(self): f={'points':[{'loadW':0.,'pvW':1000.} for _ in range(3)]} self.assertFalse(assess_family(f)['valid']) def test_confirmed_pv_only_plant_is_supported(self): f={'points':[{'loadW':0.,'pvW':1000.} for _ in range(3)],'zeroLoadConfirmed':True} self.assertTrue(assess_family(f)['valid']) def test_boolean_and_nan_are_not_forecast_powers(self): for value in (float('nan'),True,-1.,None): f={'points':[{'loadW':value,'pvW':1000.} for _ in range(3)]} self.assertFalse(assess_family(f)['valid']) def test_selected_invalid_family_not_silently_replaced(self): with TemporaryDirectory() as d: s=PlannerStore(str(Path(d)/'p.sqlite'));op,fc,tar=inputs() for p in fc['families']['3']['points']:p['loadW']=0. for k,v in zip(('operation','forecast','tariffs'),(op,fc,tar)):ingest(s,AID,k,v,AT) plan=run_once(s,AT) self.assertEqual(plan['status'],'awaiting_inputs');self.assertIn('all-zero',plan['reason']);self.assertIsNone(s.current(AID));s.close() def test_nonzero_family_remains_usable(self): f={'points':[{'loadW':50.,'pvW':0.} for _ in range(3)]} self.assertTrue(assess_family(f)['valid']) if __name__=='__main__':unittest.main()