mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-10-11 11:56:17 +00:00
218 lines
6.4 KiB
Python
218 lines
6.4 KiB
Python
![]() |
import json
|
||
|
from pathlib import Path
|
||
|
from typing import Union
|
||
|
|
||
|
import pandas as pd
|
||
|
import requests
|
||
|
from bokeh.models import ColumnDataSource, Range1d
|
||
|
from bokeh.plotting import figure
|
||
|
from monsterui.franken import FT, Grid, P
|
||
|
|
||
|
from akkudoktoreos.core.logging import get_logger
|
||
|
from akkudoktoreos.core.pydantic import PydanticDateTimeDataFrame
|
||
|
from akkudoktoreos.server.dash.bokeh import Bokeh
|
||
|
|
||
|
DIR_DEMODATA = Path(__file__).absolute().parent.joinpath("data")
|
||
|
FILE_DEMOCONFIG = DIR_DEMODATA.joinpath("democonfig.json")
|
||
|
if not FILE_DEMOCONFIG.exists():
|
||
|
raise ValueError(f"File does not exist: {FILE_DEMOCONFIG}")
|
||
|
|
||
|
logger = get_logger(__name__)
|
||
|
|
||
|
# bar width for 1 hour bars (time given in millseconds)
|
||
|
BAR_WIDTH_1HOUR = 1000 * 60 * 60
|
||
|
|
||
|
|
||
|
def DemoPVForecast(predictions: pd.DataFrame, config: dict) -> FT:
|
||
|
source = ColumnDataSource(predictions)
|
||
|
provider = config["pvforecast"]["provider"]
|
||
|
|
||
|
plot = figure(
|
||
|
x_axis_type="datetime",
|
||
|
title=f"PV Power Prediction ({provider})",
|
||
|
x_axis_label="Datetime",
|
||
|
y_axis_label="Power [W]",
|
||
|
sizing_mode="stretch_width",
|
||
|
height=400,
|
||
|
)
|
||
|
|
||
|
plot.vbar(
|
||
|
x="date_time",
|
||
|
top="pvforecast_ac_power",
|
||
|
source=source,
|
||
|
width=BAR_WIDTH_1HOUR * 0.8,
|
||
|
legend_label="AC Power",
|
||
|
color="lightblue",
|
||
|
)
|
||
|
|
||
|
return Bokeh(plot)
|
||
|
|
||
|
|
||
|
def DemoElectricityPriceForecast(predictions: pd.DataFrame, config: dict) -> FT:
|
||
|
source = ColumnDataSource(predictions)
|
||
|
provider = config["elecprice"]["provider"]
|
||
|
|
||
|
plot = figure(
|
||
|
x_axis_type="datetime",
|
||
|
y_range=Range1d(
|
||
|
predictions["elecprice_marketprice_kwh"].min() - 0.1,
|
||
|
predictions["elecprice_marketprice_kwh"].max() + 0.1,
|
||
|
),
|
||
|
title=f"Electricity Price Prediction ({provider})",
|
||
|
x_axis_label="Datetime",
|
||
|
y_axis_label="Price [€/kWh]",
|
||
|
sizing_mode="stretch_width",
|
||
|
height=400,
|
||
|
)
|
||
|
plot.vbar(
|
||
|
x="date_time",
|
||
|
top="elecprice_marketprice_kwh",
|
||
|
source=source,
|
||
|
width=BAR_WIDTH_1HOUR * 0.8,
|
||
|
legend_label="Market Price",
|
||
|
color="lightblue",
|
||
|
)
|
||
|
|
||
|
return Bokeh(plot)
|
||
|
|
||
|
|
||
|
def DemoWeatherTempAir(predictions: pd.DataFrame, config: dict) -> FT:
|
||
|
source = ColumnDataSource(predictions)
|
||
|
provider = config["weather"]["provider"]
|
||
|
|
||
|
plot = figure(
|
||
|
x_axis_type="datetime",
|
||
|
y_range=Range1d(
|
||
|
predictions["weather_temp_air"].min() - 1.0, predictions["weather_temp_air"].max() + 1.0
|
||
|
),
|
||
|
title=f"Air Temperature Prediction ({provider})",
|
||
|
x_axis_label="Datetime",
|
||
|
y_axis_label="Temperature [°C]",
|
||
|
sizing_mode="stretch_width",
|
||
|
height=400,
|
||
|
)
|
||
|
plot.line(
|
||
|
"date_time", "weather_temp_air", source=source, legend_label="Air Temperature", color="blue"
|
||
|
)
|
||
|
|
||
|
return Bokeh(plot)
|
||
|
|
||
|
|
||
|
def DemoWeatherIrradiance(predictions: pd.DataFrame, config: dict) -> FT:
|
||
|
source = ColumnDataSource(predictions)
|
||
|
provider = config["weather"]["provider"]
|
||
|
|
||
|
plot = figure(
|
||
|
x_axis_type="datetime",
|
||
|
title=f"Irradiance Prediction ({provider})",
|
||
|
x_axis_label="Datetime",
|
||
|
y_axis_label="Irradiance [W/m2]",
|
||
|
sizing_mode="stretch_width",
|
||
|
height=400,
|
||
|
)
|
||
|
plot.line(
|
||
|
"date_time",
|
||
|
"weather_ghi",
|
||
|
source=source,
|
||
|
legend_label="Global Horizontal Irradiance",
|
||
|
color="red",
|
||
|
)
|
||
|
plot.line(
|
||
|
"date_time",
|
||
|
"weather_dni",
|
||
|
source=source,
|
||
|
legend_label="Direct Normal Irradiance",
|
||
|
color="green",
|
||
|
)
|
||
|
plot.line(
|
||
|
"date_time",
|
||
|
"weather_dhi",
|
||
|
source=source,
|
||
|
legend_label="Diffuse Horizontal Irradiance",
|
||
|
color="blue",
|
||
|
)
|
||
|
|
||
|
return Bokeh(plot)
|
||
|
|
||
|
|
||
|
def Demo(eos_host: str, eos_port: Union[str, int]) -> str:
|
||
|
server = f"http://{eos_host}:{eos_port}"
|
||
|
|
||
|
# Get current configuration from server
|
||
|
try:
|
||
|
result = requests.get(f"{server}/v1/config")
|
||
|
result.raise_for_status()
|
||
|
except requests.exceptions.HTTPError as err:
|
||
|
detail = result.json()["detail"]
|
||
|
return P(
|
||
|
f"Can not retrieve configuration from {server}: {err}, {detail}",
|
||
|
cls="text-center",
|
||
|
)
|
||
|
config = result.json()
|
||
|
|
||
|
# Set demo configuration
|
||
|
with FILE_DEMOCONFIG.open("r", encoding="utf-8") as fd:
|
||
|
democonfig = json.load(fd)
|
||
|
try:
|
||
|
result = requests.put(f"{server}/v1/config", json=democonfig)
|
||
|
result.raise_for_status()
|
||
|
except requests.exceptions.HTTPError as err:
|
||
|
detail = result.json()["detail"]
|
||
|
# Try to reset to original config
|
||
|
requests.put(f"{server}/v1/config", json=config)
|
||
|
return P(
|
||
|
f"Can not set demo configuration on {server}: {err}, {detail}",
|
||
|
cls="text-center",
|
||
|
)
|
||
|
|
||
|
# Update all predictions
|
||
|
try:
|
||
|
result = requests.post(f"{server}/v1/prediction/update")
|
||
|
result.raise_for_status()
|
||
|
except requests.exceptions.HTTPError as err:
|
||
|
detail = result.json()["detail"]
|
||
|
# Try to reset to original config
|
||
|
requests.put(f"{server}/v1/config", json=config)
|
||
|
return P(
|
||
|
f"Can not update predictions on {server}: {err}, {detail}",
|
||
|
cls="text-center",
|
||
|
)
|
||
|
|
||
|
# Get Forecasts
|
||
|
try:
|
||
|
params = {
|
||
|
"keys": [
|
||
|
"pvforecast_ac_power",
|
||
|
"elecprice_marketprice_kwh",
|
||
|
"weather_temp_air",
|
||
|
"weather_ghi",
|
||
|
"weather_dni",
|
||
|
"weather_dhi",
|
||
|
],
|
||
|
}
|
||
|
result = requests.get(f"{server}/v1/prediction/dataframe", params=params)
|
||
|
result.raise_for_status()
|
||
|
predictions = PydanticDateTimeDataFrame(**result.json()).to_dataframe()
|
||
|
except requests.exceptions.HTTPError as err:
|
||
|
detail = result.json()["detail"]
|
||
|
return P(
|
||
|
f"Can not retrieve predictions from {server}: {err}, {detail}",
|
||
|
cls="text-center",
|
||
|
)
|
||
|
except Exception as err:
|
||
|
return P(
|
||
|
f"Can not retrieve predictions from {server}: {err}",
|
||
|
cls="text-center",
|
||
|
)
|
||
|
|
||
|
# Reset to original config
|
||
|
requests.put(f"{server}/v1/config", json=config)
|
||
|
|
||
|
return Grid(
|
||
|
DemoPVForecast(predictions, democonfig),
|
||
|
DemoElectricityPriceForecast(predictions, democonfig),
|
||
|
DemoWeatherTempAir(predictions, democonfig),
|
||
|
DemoWeatherIrradiance(predictions, democonfig),
|
||
|
cols_max=2,
|
||
|
)
|