feat(forecast): integrate full forecast charts and complete SDL visualization
Tests / test (push) Failing after 52s
Tests / test (push) Failing after 52s
This commit is contained in:
@@ -36,6 +36,16 @@ def inputs(at=AT):
|
||||
return op,forecast,tariff
|
||||
|
||||
class OptimizerTest(unittest.TestCase):
|
||||
def test_plan_preserves_exact_forecast_components(self):
|
||||
steps = [replace(s, external_w=725.) for s in seq([2100., 2200., 2300.], pv=[3100., 3200., 3300.])]
|
||||
plan = solve(steps)
|
||||
self.assertTrue(plan['executable'])
|
||||
for step, point in zip(steps, plan['points']):
|
||||
self.assertEqual(point['pvW'], step.pv_w)
|
||||
self.assertEqual(point['loadW'], step.base_load_w)
|
||||
self.assertEqual(point['externalW'], step.external_w)
|
||||
self.assertAlmostEqual(point['baselineGridW'], point['loadW'] + point['externalW'] - point['pvW'])
|
||||
|
||||
def test_grid_price_arbitrage(self):
|
||||
p=solve(seq([1000.]*6,buy=[.01]*3+[.7]*3),[batt()]);self.assertTrue(p['executable']);self.assertGreater(p['points'][0]['batteryTargetW'],0);self.assertLess(p['points'][-1]['batteryTargetW'],0)
|
||||
def test_no_future_energy(self):
|
||||
@@ -157,12 +167,21 @@ class ServiceIntegrationTest(unittest.TestCase):
|
||||
op,fc,tar=inputs();tar['import']={'mode':'dynamic','tariffId':'buy'};self.load((op,fc,tar))
|
||||
price={'version':1,'eventId':'price1','observedAt':AT.isoformat(),'periods':[{'tariffId':'buy','side':'import','start':AT.isoformat(),'end':(AT+timedelta(minutes=15)).isoformat(),'value':-2.,'unit':'Rp/kWh','observedAt':AT.isoformat(),'sourceKind':'published_interval'}]}
|
||||
ingest(self.store,AID,'prices',price,AT);p=run_once(self.store,AT);self.assertEqual(len(p['points']),3);self.assertEqual(p['points'][0]['importPriceChfKwh'],-.02)
|
||||
self.assertEqual(len(p['forecastPoints']), 6)
|
||||
self.assertEqual(p['forecastPoints'][-1]['validUntil'], p['forecastUntil'])
|
||||
self.assertGreater(p['forecastUntil'], p['pricesKnownUntil'])
|
||||
self.assertNotIn('gridTargetW', p['forecastPoints'][-1])
|
||||
self.assertNotIn('forecastPoints', p['inputQuality'])
|
||||
def test_carried_price_does_not_extend_horizon(self):
|
||||
op,fc,tar=inputs();tar['import']={'mode':'dynamic','tariffId':'buy'};self.load((op,fc,tar))
|
||||
price={'version':1,'eventId':'price1','observedAt':AT.isoformat(),'periods':[{'tariffId':'buy','side':'import','start':AT.isoformat(),'end':(AT+timedelta(hours=48)).isoformat(),'value':.1,'unit':'CHF/kWh','observedAt':AT.isoformat(),'sourceKind':'carried_forward'}]}
|
||||
ingest(self.store,AID,'prices',price,AT);self.assertEqual(run_once(self.store,AT)['status'],'awaiting_inputs')
|
||||
def test_aggregate_load_warning(self):
|
||||
op,fc,tar=inputs();fc['families']['3']['loadBasis']='house_total';self.load((op,fc,tar));self.assertTrue(run_once(self.store,AT)['warnings'])
|
||||
def test_aggregate_forecast_does_not_invent_separate_sdl(self):
|
||||
op,fc,tar=inputs();fc['families']['3']['loadBasis']='house_total'
|
||||
self.load((op,fc,tar));plan=run_once(self.store,AT)
|
||||
self.assertTrue(all(point['externalW'] is None for point in plan['forecastPoints']))
|
||||
def test_extra_credentials_not_stored(self):
|
||||
op,fc,tar=inputs();op['password']='do-not-store'
|
||||
with self.assertRaises(ValueError):ingest(self.store,AID,'operation',op,AT)
|
||||
|
||||
Reference in New Issue
Block a user