9794193803
Setup-Menü (Einstellungen -> Fahrzeug einrichten -> Setup): ordnet alle von der App genutzten Sensor-Rollen echten HA-Entitäten zu, statt sie in einstellungen.py von Hand einzutragen - durchsuchbares Dropdown je Feld, Vorauswahl aus vorhandenen Entitäten, Schalter für "nur passende Sensoren". Neues Modul entitaeten.py (Katalog + JSON-Override, zur Laufzeit über setattr() auf einstellungen angewendet, kein Neustart nötig außer für die drei trigger-gebundenen Felder). Zusätzlich: Fahrzeug-WLAN-Erkennung und alle Entity-IDs der nicht mehr genutzten TommiG1/HA_VAG-EU-Data-Act-Integration entfernt. Fahrterkennung läuft jetzt über den Zündungs-/ACC-Status des neu angebundenen Teltonika FMM003 (ersetzt die WLAN-Verbindungserkennung); Standort und 12V- Batteriespannung kommen ebenfalls vom FMM003. Kilometerstand, Tankfüllstand, Reichweite, Türen/Fenster/Schlösser sowie Ölwechsel-/Inspektionsdaten haben dadurch vorerst keine Quelle mehr und zeigen "unbekannt" - die Funktionen selbst bleiben erhalten und lassen sich über das neue Setup-Menü jederzeit neu zuordnen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
106 lines
4.4 KiB
Python
106 lines
4.4 KiB
Python
"""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())
|
|
|
|
|
|
# Ohne konfigurierten Kilometerstand-Sensor keinen Trigger registrieren -
|
|
# eine leere Entity-ID als @state_trigger-Ausdruck ist ungetestetes
|
|
# Verhalten, siehe gleiches Muster in fahrterkennung.py.
|
|
if einstellungen.KM_SENSOR:
|
|
@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")
|