strompreis/dashboard/app.py

73 lines
2.2 KiB
Python

import sys
from pathlib import Path
import duckdb
import polars as pl
import streamlit as st
project_root = str(Path(__file__).parent.parent)
if project_root not in sys.path:
sys.path.append(project_root)
from utils.config_loader import settings
st.set_page_config(page_title="Strompreis & Netz Dashboard", layout="wide")
st.title("⚡ Strompreis, Netz & Wetter Dashboard")
@st.cache_data(ttl=300)
def load_data():
try:
con = duckdb.connect(settings.database.path)
df = con.execute("SELECT * FROM combined ORDER BY timestamp DESC").pl()
con.close()
return df.fill_null(0)
except Exception as e:
st.error(f"Fehler beim Laden der Daten: {e}")
return pl.DataFrame()
df = load_data()
if df.is_empty():
st.warning("Keine Daten gefunden. Bitte Pipeline starten.")
else:
latest = df.head(1).to_dicts()[0]
m1, m2, m3, m4 = st.columns(4)
m1.metric("Preis", f"{latest['price']:.2f} €/MWh")
m2.metric("Netzlast", f"{latest['load_forecast'] / 1000:.1f} GW")
m3.metric("Erneuerbare", f"{(latest['wind_total'] + latest['pv']) / 1000:.1f} GW")
m4.metric("Außentemp.", f"{latest['temperature']:.1f} °C")
tab1, tab2, tab3 = st.tabs(["Markt & Netz", "Wetter-Details", "Rohdaten"])
with tab1:
st.subheader("Strompreis vs. Netzlast")
pdf = df.to_pandas()
st.line_chart(pdf.set_index("timestamp")[["price", "load_forecast"]])
st.subheader("Erzeugung Mix (Wind & Solar)")
st.area_chart(pdf.set_index("timestamp")[["wind_total", "pv"]])
with tab2:
st.subheader("Detaillierte Wetterdaten")
w_col1, w_col2 = st.columns(2)
with w_col1:
st.info("Temperaturverlauf")
st.line_chart(pdf.set_index("timestamp")["temperature"])
with w_col2:
st.info("Windgeschwindigkeit")
st.line_chart(pdf.set_index("timestamp")["wind_speed"])
st.info("Weitere Wetterfaktoren")
available_weather = [
c
for c in ["solar", "sunshine", "cloud_cover", "precipitation"]
if c in df.columns
]
if available_weather:
st.line_chart(pdf.set_index("timestamp")[available_weather])
with tab3:
st.dataframe(df)