Initialer Import: HA-Panel, Design-System, Companion-App
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>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
"""Reifenzähler ohne utility_meter (§7.5, §10 Punkt 6).
|
||||
|
||||
ABWEICHUNG VOM URSPRÜNGLICHEN LASTENHEFT (Frontend-Anpassung, nach dem
|
||||
ursprünglichen Bau nachträglich verlangt): früher war der Zähler = aktueller
|
||||
Kilometerstand - fester Startwert je Satz (reifen.saetze.<satz>.
|
||||
start_odo_km). Das war falsch, sobald einmal zwischen Sommer und Winter
|
||||
umgeschaltet wurde: die Differenz zum Startwert zählt dann alle seither
|
||||
gefahrenen Kilometer mit, auch die auf dem jeweils anderen Satz. Jetzt gilt
|
||||
stattdessen: jeder gefahrene Kilometer wird dem Satz zugerechnet, der zum
|
||||
Zeitpunkt der Fahrt aktiv war. Dafür führt reifen.saetze.<satz>.km selbst den
|
||||
fortlaufenden Gesamtstand (statt eines Startwerts), und reifen.
|
||||
referenz_odo_km hält den zuletzt verarbeiteten Kilometerstand fest, gegen den
|
||||
die nächste Änderung als Delta gemessen wird. start_odo_km/§13 entfällt
|
||||
damit vollständig.
|
||||
|
||||
Ergebnis wird zusätzlich als eigene pyscript-Zustandsvariable bereitgestellt
|
||||
(nur zur Kontrolle in Entwicklerwerkzeuge → Zustände, das Frontend liest die
|
||||
Werte direkt aus dem veröffentlichten Profil):
|
||||
pyscript.reifen_sommer_km, pyscript.reifen_winter_km,
|
||||
pyscript.reifen_aktiver_satz
|
||||
|
||||
Kein Abhängigkeit von total_increasing oder utility_meter-internem Zustand -
|
||||
die Fortschreibung braucht nur den zuletzt bekannten Absolutwert des
|
||||
Kilometerstand-Sensors. Ein zeitweise `unavailable` Quellsensor (§4.1)
|
||||
verliert dadurch nichts: referenz_odo_km bleibt einfach stehen, bis wieder
|
||||
ein gültiger Wert kommt, und das nächste Delta wird dann gegen diesen alten
|
||||
Stand berechnet - auch km, die während eines HA-Neustarts/Ausfalls gefahren
|
||||
wurden, werden so noch dem damals aktiven Satz zugerechnet.
|
||||
|
||||
Entity-IDs stehen zentral in pyscript/modules/einstellungen.py.
|
||||
"""
|
||||
|
||||
import einstellungen
|
||||
import frontend_veroeffentlichung
|
||||
import profil
|
||||
|
||||
|
||||
def _aktueller_km():
|
||||
try:
|
||||
return float(frontend_veroeffentlichung.zustand_oder_none(einstellungen.KM_SENSOR))
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
def _zustaende_veroeffentlichen(p):
|
||||
reifen = p.get("reifen", {})
|
||||
saetze = reifen.get("saetze", {})
|
||||
for satz_name in ("sommer", "winter"):
|
||||
km = saetze.get(satz_name, {}).get("km")
|
||||
if km is None:
|
||||
state.set(f"pyscript.reifen_{satz_name}_km", "unbekannt")
|
||||
else:
|
||||
state.set(f"pyscript.reifen_{satz_name}_km", km, new_attributes={"unit_of_measurement": "km"})
|
||||
state.set("pyscript.reifen_aktiver_satz", reifen.get("aktiv", "unbekannt"))
|
||||
|
||||
|
||||
def _fortschreiben_und_veroeffentlichen(neuer_km, neuer_aktiv=None):
|
||||
"""Rechnet zuerst mit dem bisher aktiven Satz ab (Delta seit
|
||||
referenz_odo_km), trägt danach optional einen Satzwechsel ein - in dieser
|
||||
Reihenfolge, damit beim Wechseln selbst keine km dem neuen Satz
|
||||
zugerechnet werden, die eigentlich noch auf dem alten gefahren wurden."""
|
||||
p = profil.profil_lesen()
|
||||
reifen = p.setdefault("reifen", {})
|
||||
saetze = reifen.setdefault("saetze", {})
|
||||
aktiv = reifen.get("aktiv", "sommer")
|
||||
referenz = reifen.get("referenz_odo_km")
|
||||
|
||||
if referenz is not None and neuer_km is not None:
|
||||
delta = round(neuer_km - referenz, 1)
|
||||
if delta > 0:
|
||||
satz = saetze.setdefault(aktiv, {})
|
||||
satz["km"] = round((satz.get("km") or 0) + delta, 1)
|
||||
if neuer_km is not None:
|
||||
reifen["referenz_odo_km"] = neuer_km
|
||||
if neuer_aktiv is not None:
|
||||
reifen["aktiv"] = neuer_aktiv
|
||||
|
||||
profil.profil_schreiben(p)
|
||||
frontend_veroeffentlichung.profil_veroeffentlichen()
|
||||
_zustaende_veroeffentlichen(p)
|
||||
|
||||
|
||||
@time_trigger("startup")
|
||||
def beim_start():
|
||||
_fortschreiben_und_veroeffentlichen(_aktueller_km())
|
||||
|
||||
|
||||
@state_trigger(f"{einstellungen.KM_SENSOR}")
|
||||
def kilometerstand_geaendert(value=None):
|
||||
_fortschreiben_und_veroeffentlichen(_aktueller_km())
|
||||
|
||||
|
||||
@service
|
||||
def audi_dashboard_reifen_wechseln(satz=None):
|
||||
"""Umschalten des aktiven Reifensatzes (§5.2). Aufruf als
|
||||
pyscript.audi_dashboard_reifen_wechseln mit satz="sommer"|"winter"."""
|
||||
if satz not in ("sommer", "winter"):
|
||||
log.warning(f"audi_dashboard: ungültiger Reifensatz '{satz}'")
|
||||
return
|
||||
_fortschreiben_und_veroeffentlichen(_aktueller_km(), neuer_aktiv=satz)
|
||||
log.info(f"audi_dashboard: aktiver Reifensatz auf '{satz}' umgeschaltet")
|
||||
Reference in New Issue
Block a user