Feature: Börsenstrompreis-Chart (EPEX SPOT via aWATTar) im Energie-Dashboard (v1.8.0)

- /api/spot-price: Proxy zu api.awattar.de/v1/marketdata, 15-min Cache
- EUR/MWh → ct/kWh Konvertierung
- SVG-Balkenchart 24h-Prognose, gleiche Breite wie Flussdiagramm (viewBox 520)
- Farbe nach Preistertil: grün/gelb/rot; aktuelle Stunde hervorgehoben
- Aktuellen Preis als ct/kWh-Label in der Kopfzeile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
retr0
2026-04-29 08:15:52 +02:00
parent f96d798274
commit 526e802c74
3 changed files with 80 additions and 4 deletions
+23
View File
@@ -545,6 +545,29 @@ def api_import_config():
threading.Thread(target=_restart_all, daemon=True).start()
return jsonify({"ok": True, "inverters": len(inverters)})
_spot_cache: Dict[str, Any] = {"ts": 0.0, "data": []}
_SPOT_TTL = 900 # 15 Minuten
@app.get("/api/spot-price")
def api_spot_price():
import urllib.request as _ur
global _spot_cache
now = time.time()
if now - _spot_cache["ts"] < _SPOT_TTL and _spot_cache["data"]:
return jsonify({"ok": True, "data": _spot_cache["data"]})
try:
with _ur.urlopen("https://api.awattar.de/v1/marketdata", timeout=8) as r:
raw = json.loads(r.read())
entries = [
{"ts": int(d["start_timestamp"] // 1000), "price": round(d["marketprice"] / 10, 2)}
for d in raw.get("data", [])
]
_spot_cache = {"ts": now, "data": entries}
return jsonify({"ok": True, "data": entries})
except Exception as e:
log.warning("Spot-Price API Fehler: %s", e)
return jsonify({"ok": False, "data": _spot_cache.get("data", [])})
@app.get("/")
def index():
return send_from_directory(WEB_DIR, "index.html")