e1d570992e
Drei zusammengehörige Teile in einem Repository: - homeassistant/ Das fertige, im Einsatz befindliche Home-Assistant-Panel (panel_custom Custom Element + pyscript-Backend). Echte Fahrzeug- und Personendaten (fahrzeugprofil.json, fahrten.jsonl, tankvorgaenge.jsonl, Tankbelege) bleiben per .gitignore außen vor; die anonymisierte Vorlage fahrzeugprofil.example.json ist mit dabei. - design-system/ Eigenständige React-Komponentenbibliothek (@audi-dash/ui), die die visuelle Sprache des Panels nachbildet - ohne Audi-Markenzeichen und ohne die lizenzierte Hausschrift. Dient als Grundlage für Claude Design. War bis hierher ein eigenes Repository und ist in dieses eingeschmolzen worden. - companion-app/ Datenschicht der neuen App DataMetric360 (iOS/Android via Capacitor, zusätzlich als Iframe im HA-Dashboard). Noch ohne Oberfläche: REST- und WebSocket-Zugriff auf Home Assistant plus Warteschlange für Änderungen ohne Netz. Ersetzt das eingespritzte hass-Objekt, das nur innerhalb des HA-Frontends existiert. Dazu die Projektdokumentation: SPECIFICATION.md (Ist-Stand des Panels), COMPANION_APP_ARCHITECTURE.md (Architekturentscheidungen der neuen App), AUDIT_2026-08-10.md, DESIGN_BRIEF_DATAMETRIC360.md und der ursprüngliche Bauauftrag. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
63 lines
2.9 KiB
Python
63 lines
2.9 KiB
Python
"""Langfristige Aufzeichnung der 12V-Batteriespannung (Mein Audi -> Zustand
|
|
-> Batteriespannung antippen). Eine über die Jahre absinkende Spannung
|
|
deutet auf eine alternde Batterie hin - dafür braucht es einen Verlauf,
|
|
nicht nur den aktuellen Wert.
|
|
|
|
Ein Eintrag pro Tag ({datum, min, min_ts, max, max_ts}) reicht für diesen
|
|
Zweck aus und hält batteriespannung.jsonl auch über viele Jahre klein - auch
|
|
wenn der Sensor selbst künftig mehrfach pro Stunde meldet (aktive Fahrt:
|
|
Motor an/aus, Ladezustand des Alternators wechselt laufend).
|
|
batterie_verlauf_pruefen() läuft deshalb häufig (alle 5 Minuten) und trägt
|
|
jede Messung in den Tageseintrag ein, statt wie zuvor nur einmal täglich
|
|
einen Einzelwert zu speichern - profil.batterieverlauf_tageswert_aktualisieren()
|
|
erweitert dabei nur min/max samt dem genauen Zeitstempel der jeweiligen
|
|
Extremmessung, robust gegen Neustarts und schwankende Erreichbarkeit.
|
|
|
|
Der Tagesminimalwert ist die für die Entladung aussagekräftige Größe: er
|
|
fällt typischerweise auf den Moment kurz nach dem Start, bevor der
|
|
Alternator die Ladespannung hochfährt - also am nächsten an die "echte"
|
|
Ruhespannung heran, ohne 2+ Stunden Standzeit abwarten zu müssen. Deshalb
|
|
verwendet auch die Ladezustands-/Gesundheitsauswertung im Frontend
|
|
(audi-dashboard-app.js, AGM_RUHE_MAX_V) den Tagesminimalwert als
|
|
repräsentativen Wert des Tages, nicht den Maximalwert.
|
|
|
|
Anders als in der ersten Fassung wird hier NICHT mehr gefiltert, welche
|
|
Messwerte gespeichert werden - min UND max jedes Tages werden roh
|
|
aufgezeichnet (der Maximalwert ist z. B. informativ beim Antippen eines
|
|
Punkts im Diagramm sichtbar). Die AGM-Ruhespannungs-Grenze wird stattdessen
|
|
erst beim Anzeigen angewendet (siehe AGM_RUHE_MAX_V im Frontend): Tage, an
|
|
denen selbst der Minimalwert über der Grenze liegt (Fahrzeug nie im
|
|
Ruhezustand beobachtet, z. B. bei einer sehr langen Fahrt), tauchen dort
|
|
nicht in der Ladezustands-Statistik auf.
|
|
|
|
Ohne eingetragenen einstellungen.BATTERIE_SENSOR (aktuell der Fall - die
|
|
genutzte Integration liefert dafür keinen Sensor, siehe dortiger Kommentar)
|
|
passiert hier bewusst nichts, statt Platzhalter-Nullwerte aufzuzeichnen.
|
|
"""
|
|
|
|
import datetime
|
|
|
|
import einstellungen
|
|
import frontend_veroeffentlichung
|
|
import profil
|
|
|
|
|
|
@time_trigger("startup")
|
|
@time_trigger("period(now, 5 minutes)")
|
|
def batterie_verlauf_pruefen():
|
|
if not einstellungen.BATTERIE_SENSOR:
|
|
return
|
|
wert = frontend_veroeffentlichung.zustand_oder_none(einstellungen.BATTERIE_SENSOR)
|
|
if wert is None:
|
|
return
|
|
try:
|
|
spannung = float(wert)
|
|
except (TypeError, ValueError):
|
|
return
|
|
|
|
heute = datetime.date.today().isoformat()
|
|
ts = datetime.datetime.now(datetime.timezone.utc).isoformat()
|
|
profil.batterieverlauf_tageswert_aktualisieren(heute, ts, spannung)
|
|
frontend_veroeffentlichung.batterieverlauf_veroeffentlichen()
|
|
log.info(f"audi_dashboard: Batteriespannung erfasst ({heute}: {spannung} V)")
|