v1.8.16: Finanzen-Tab — Festpreis vs. Spot-Vergleich

Täglicher Tarif-Tracking: kWh + EPEX-Ø-Preis werden ab jetzt täglich
gespeichert. Neuer Finanzen-Tab zeigt Balkendiagramm (Festpreis vs.
Spot hypothetisch), Summen-Karten und Empfehlung ob flexibler Tarif
sich lohnen würde.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
retr0
2026-05-05 13:29:55 +02:00
parent dfb42e6902
commit 2456f356b4
4 changed files with 253 additions and 2 deletions
+55
View File
@@ -47,6 +47,16 @@ def init_db():
PRIMARY KEY (agg_id, period_type, period_key)
)
""")
# Tariftage: täglicher Verbrauch + Preisvergleich
c.execute("""
CREATE TABLE IF NOT EXISTS tariff_days (
date TEXT PRIMARY KEY,
kwh REAL NOT NULL,
spot_ct REAL,
fixed_ct REAL NOT NULL,
markup_ct REAL NOT NULL DEFAULT 0
)
""")
c.commit()
cleanup_old()
log.info("History DB initialisiert: %s", DB_PATH)
@@ -137,6 +147,51 @@ def query(inv_id: str, sensor_id: str,
return rows
def save_daily_tariff_snapshot(date_iso: str, prev_kwh: float, cur_kwh: float,
spot_ct: Optional[float], fixed_ct: float, markup_ct: float):
"""Speichert den Tagesverbrauch + Preisdaten für einen abgeschlossenen Tag."""
delta = max(0.0, cur_kwh - prev_kwh)
with _lock:
c = _get_conn()
c.execute("""
INSERT OR IGNORE INTO tariff_days(date, kwh, spot_ct, fixed_ct, markup_ct)
VALUES(?, ?, ?, ?, ?)
""", (date_iso, round(delta, 4), spot_ct, fixed_ct, markup_ct))
c.commit()
def get_tariff_days(from_date: str, to_date: str) -> List[Tuple]:
"""Gibt alle Tariftage im Bereich [from_date, to_date] zurück."""
with _lock:
return _get_conn().execute("""
SELECT date, kwh, spot_ct, fixed_ct, markup_ct
FROM tariff_days
WHERE date >= ? AND date <= ?
ORDER BY date ASC
""", (from_date, to_date)).fetchall()
def get_daily_kwh_start(date_iso: str) -> Optional[float]:
"""Gibt den gespeicherten kWh-Tagesstartwert zurück (aus period_starts)."""
with _lock:
row = _get_conn().execute("""
SELECT value FROM period_starts
WHERE agg_id='tariff' AND period_type='daily' AND period_key=?
""", (date_iso,)).fetchone()
return row[0] if row else None
def save_daily_kwh_start(date_iso: str, kwh: float):
"""Speichert den kWh-Stand als Tagesstartwert (einmalig, INSERT OR IGNORE)."""
with _lock:
c = _get_conn()
c.execute("""
INSERT OR IGNORE INTO period_starts(agg_id, period_type, period_key, value)
VALUES('tariff', 'daily', ?, ?)
""", (date_iso, kwh))
c.commit()
def cleanup_old(days: int = RETENTION_DAYS):
cutoff = time.time() - days * 86400
with _lock: