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)