diff --git a/haos-addon/config.yaml b/haos-addon/config.yaml index 88ef316..1e68634 100644 --- a/haos-addon/config.yaml +++ b/haos-addon/config.yaml @@ -1,5 +1,5 @@ name: ShineBridge -version: "1.8.27" +version: "1.8.28" slug: shinebridge description: Growatt Wechselrichter lokal in Home Assistant — Modbus TCP via ShineLAN-X, MQTT Discovery, Web UI url: https://gitea.bitfire.work/retr0/shinebridge diff --git a/haos-addon/src/history.py b/haos-addon/src/history.py index d4d1b34..ad7af1e 100644 --- a/haos-addon/src/history.py +++ b/haos-addon/src/history.py @@ -7,7 +7,7 @@ from typing import Dict, List, Optional, Tuple log = logging.getLogger(__name__) DB_PATH = "/data/history.db" -RETENTION_DAYS = 7 +RETENTION_DAYS = 14 _lock = threading.Lock() _conn: sqlite3.Connection | None = None @@ -59,9 +59,19 @@ def init_db(): """) c.commit() cleanup_old() + _start_cleanup_scheduler() log.info("History DB initialisiert: %s", DB_PATH) +def _start_cleanup_scheduler(): + def _loop(): + while True: + time.sleep(86400) + cleanup_old() + t = threading.Thread(target=_loop, daemon=True, name="history-cleanup") + t.start() + + def period_key(period_type: str, billing_day: int = 1, billing_month: int = 1) -> str: import datetime today = datetime.date.today() @@ -117,21 +127,18 @@ def write_batch(inv_id: str, ts: float, values: Dict[str, float]): def load_recent(inv_id: str, limit: int = 300) -> Dict[str, List[Tuple[float, float]]]: """Letzte `limit` Messpunkte pro Sensor — zum Befüllen der In-Memory-Deque beim Start.""" with _lock: - rows = _get_conn().execute(""" - SELECT sensor_id, ts, value - FROM ( - SELECT sensor_id, ts, value, - ROW_NUMBER() OVER (PARTITION BY sensor_id ORDER BY ts DESC) AS rn - FROM measurements - WHERE inv_id = ? - ) - WHERE rn <= ? - ORDER BY ts ASC - """, (inv_id, limit)).fetchall() - - result: Dict[str, List[Tuple[float, float]]] = {} - for sensor_id, ts, value in rows: - result.setdefault(sensor_id, []).append((ts, value)) + c = _get_conn() + sensors = [r[0] for r in c.execute( + "SELECT DISTINCT sensor_id FROM measurements WHERE inv_id = ?", (inv_id,) + ).fetchall()] + result: Dict[str, List[Tuple[float, float]]] = {} + for sid in sensors: + rows = c.execute( + "SELECT ts, value FROM measurements " + "WHERE inv_id = ? AND sensor_id = ? ORDER BY ts DESC LIMIT ?", + (inv_id, sid, limit), + ).fetchall() + result[sid] = [(ts, val) for ts, val in reversed(rows)] return result