sample2, more improvements

This commit is contained in:
Chris Oloff 2025-11-20 08:46:20 +02:00
parent 15e99c9c4a
commit 42f9c4a284

View file

@ -11,13 +11,6 @@ attach_w42_state(rx_var=w42_state, system_id="79476e53-dea6-44fa-976c-eff6260bae
state_as_text = panel.bind(lambda s: f"W42 State:\n\n```\n{json.dumps(s, indent=2)}\n```\n\nReplace this with some awesome visuals", w42_state) state_as_text = panel.bind(lambda s: f"W42 State:\n\n```\n{json.dumps(s, indent=2)}\n```\n\nReplace this with some awesome visuals", w42_state)
class LoadForecast(BaseModel):
at: datetime = datetime.now()
slots: list[float] = []
async def update(self, now: datetime) -> None:
pass
class Output(BaseModel): class Output(BaseModel):
target_storage: float target_storage: float
target_geyser_temperature: float target_geyser_temperature: float
@ -25,12 +18,21 @@ class Output(BaseModel):
grid_sell: list[float] grid_sell: list[float]
grid_buy: list[float] grid_buy: list[float]
class PvForecast(BaseModel):
at: datetime = datetime.now()
slots: list[float] = []
class LoadForecast(BaseModel):
at: datetime = datetime.now()
slots: list[float] = []
class SystemState(BaseModel): class SystemState(BaseModel):
load_forecast: LoadForecast = LoadForecast() load_forecast: LoadForecast = LoadForecast()
pv_forecast: PvForecast = PvForecast()
now: datetime = datetime.now() now: datetime = datetime.now()
output: Output | None = None output: Output | None = None
state: SystemState = panel.rx(lambda s: SystemState.model_validate(s) if s else SystemState())(w42_state) state: SystemState = panel.rx(lambda s: SystemState.model_validate(s) if s else SystemState())(w42_state)
state_pane = panel.pane.Markdown(state_as_text, sizing_mode='stretch_width') state_pane = panel.pane.Markdown(state_as_text, sizing_mode='stretch_width')
@ -49,12 +51,13 @@ def load_fc_chart(state: SystemState) -> dict:
at = state.load_forecast.at at = state.load_forecast.at
storage = state.output.storage if state.output else [0] * len(slots) storage = state.output.storage if state.output else [0] * len(slots)
battery = [storage[ix] - storage[ix-1] if ix > 0 else 0 for ix in range(len(slots))] if state.output else [0] * len(slots) battery = [storage[ix] - storage[ix-1] if ix > 0 else 0 for ix in range(len(slots))] if state.output else [0] * len(slots)
grid = [state.output.grid_buy[ix] - state.output.grid_sell[ix] if state.output else 0 for ix in range(len(slots))]
return { return {
'title': { 'title': {
'text': '24hr Forecast' 'text': '24hr Forecast'
}, },
'legend': { 'legend': {
'data': ['Load Forecast', 'Battery Storage', 'Battery in/out'] 'data': ['Load Forecast', 'Battery Storage', 'Battery in/out', 'PV Forecast', 'Grid in/out']
}, },
'tooltip': { 'tooltip': {
'trigger': 'axis' 'trigger': 'axis'
@ -81,6 +84,16 @@ def load_fc_chart(state: SystemState) -> dict:
'data': battery, 'data': battery,
'type': 'line', 'type': 'line',
'color': 'lightblue' 'color': 'lightblue'
}, {
'name': 'PV Forecast',
'data': state.pv_forecast.slots,
'type': 'line',
'color': 'green'
}, {
'name': 'Grid in/out',
'data': grid,
'type': 'line',
'color': 'red'
} }
] ]
} }