Batteriespannungs-Messwertliste, Wisch-Löschen, Reifensatz-Archiv, CI-Icons
Fünf vom Nutzer angeforderte Erweiterungen in einer Runde:
- Batteriespannungs-Kachel bekommt eine Messwertliste (Datum, Uhrzeit,
Spannung, optional Außentemperatur über den neuen AUSSENTEMP_SENSOR),
erreichbar über ein neues list-s-Symbol in der Diagramm-Kachel. Werte
über AGM_RUHE_MAX_V (12,8 V) sind keine Ruhespannung, sondern
Lichtmaschinenspannung - die Zeile markiert das jetzt mit
"Generatorspannung" statt es unkommentiert als Messwert auszugeben.
- Jede Zeile der neuen Liste wischbar zum Löschen (neuer Dienst
batterieverlauf_loeschen), über dieselbe Wisch-Mechanik wie Fahrten/
Tankvorgänge in beiden Oberflächen.
- Batteriespannungs-Diagramm im Panel war auf großen Bildschirmen (≥860px,
Spaltenlayout) stark in die Breite gezogen (preserveAspectRatio="none"
bei fester Höhe) - gedeckelt wie die dort bereits vorhandenen Popups.
- Statistik-Tab-Symbol in beiden Oberflächen durch das Audi-CI-Symbol
polls-s ersetzt.
- Neue Möglichkeit, einen Reifensatz zu archivieren ("Neue Räder
anlegen"): der aktuelle Stand (km, Marke, Modell, DOT, Maße, Solldruck,
Kommentar) wandert in ein Archiv, der laufende Satz beginnt bei 0 km neu.
Archiv als aufklappbare Übersicht mit voller Bearbeitungsmöglichkeit,
über drei neue, bewusst nicht über profilSchreiben laufende Dienste
(reifen_archivieren/-aktualisieren/-loeschen) - aus demselben Grund wie
reifen_wechseln: kein im Browser gehaltener Stand darf einen
zwischenzeitlich fortgeschriebenen km-Wert überschreiben.
Live im Testcontainer geprüft (erstmals über :18123 statt :8123 erreichbar)
und dabei zwei echte Layout-Fehler gefunden, die kein Compile-/Testlauf
sehen konnte: die Archiv-Eingabefelder waren durch ein fälschlich
verwendetes .mitEinheit (feste 96px-Breite, eigentlich für Zahl+Einheit
gedacht) abgeschnitten ("Continenta" statt "Continental"), und die
Kilometerzahl in der eingeklappten Archiv-Zeile war klein an das Datum
gequetscht statt wie der Satzname lesbar. Beides behoben, live erneut
bestätigt.
Backend: py_compile clean, services.yaml ergänzt. Panel: node --check
clean. companion-app: tsc/Testsuite (146/146)/Build/OTA-Bündel alle grün.
Manifest 2026.8.25.2 → .8, jeder Neustart im Testcontainer sauber.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -20,9 +20,11 @@ Satz zugerechnet.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .ablage import neue_id
|
||||
from .veroeffentlichung import zustand_oder_none
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -32,6 +34,11 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SAETZE = ("sommer", "winter")
|
||||
|
||||
# Felder, die bei "Neue Räder anlegen" mit auf den frischen Satz übernommen
|
||||
# werden - Größe und Solldruck ändern sich bei einem gleich montierten Ersatz
|
||||
# typischerweise nicht, anders als Marke/Modell/DOT (siehe archivieren()).
|
||||
_UEBERNOMMENE_FELDER = ("bild", "mass", "druck_vorne", "druck_hinten")
|
||||
|
||||
|
||||
def aktueller_km(k: Koordinator) -> float | None:
|
||||
try:
|
||||
@@ -106,6 +113,95 @@ async def km_setzen(k: Koordinator, satz: str | None, km: object) -> None:
|
||||
_LOGGER.info("km-Stand '%s' manuell auf %s gesetzt", satz, wert)
|
||||
|
||||
|
||||
async def archivieren(k: Koordinator, satz: str | None) -> None:
|
||||
""""Neue Räder anlegen": legt den aktuellen Stand von `satz` (km, Marke,
|
||||
Modell, DOT, Kommentar) als Übersichtszeile ins Archiv und setzt den
|
||||
laufenden Satz auf einen frischen Stand zurück - km auf 0, Marke/Modell/
|
||||
DOT/Kommentar leer (galten für den alten, jetzt ersetzten Reifen), Größe
|
||||
und Solldruck unverändert übernommen (siehe _UEBERNOMMENE_FELDER)."""
|
||||
if satz not in SAETZE:
|
||||
_LOGGER.warning("Ungültiger Reifensatz '%s'", satz)
|
||||
return
|
||||
|
||||
profil = await k.ablage.profil_lesen()
|
||||
if profil is None:
|
||||
return
|
||||
reifen = profil.setdefault("reifen", {})
|
||||
saetze = reifen.setdefault("saetze", {})
|
||||
alt = dict(saetze.get(satz, {}))
|
||||
|
||||
archiv = reifen.setdefault("archiv", [])
|
||||
archiv.insert(0, {
|
||||
"id": neue_id("r"),
|
||||
"satz": satz,
|
||||
"ersetzt_am": datetime.date.today().isoformat(),
|
||||
"km": alt.get("km") or 0,
|
||||
"marke": alt.get("marke") or "",
|
||||
"modell": alt.get("modell") or "",
|
||||
"dot": alt.get("dot") or "",
|
||||
"mass": alt.get("mass") or "",
|
||||
"druck_vorne": alt.get("druck_vorne") or "",
|
||||
"druck_hinten": alt.get("druck_hinten") or "",
|
||||
"kommentar": alt.get("kommentar") or "",
|
||||
})
|
||||
|
||||
saetze[satz] = {
|
||||
"km": 0, "marke": "", "modell": "", "dot": "", "kommentar": "",
|
||||
**{feld: alt.get(feld) or "" for feld in _UEBERNOMMENE_FELDER},
|
||||
}
|
||||
|
||||
await k.ablage.profil_schreiben(profil)
|
||||
await k.profil_veroeffentlichen(profil)
|
||||
_LOGGER.info("Reifensatz '%s' archiviert (%s km), neuer Satz angelegt", satz, archiv[0]["km"])
|
||||
|
||||
|
||||
async def archiv_aktualisieren(k: Koordinator, id_: str | None, daten: dict) -> None:
|
||||
"""Bearbeitet einen archivierten Reifensatz-Eintrag (Übersichtszeile auf
|
||||
der Reifen-Seite, aufgeklappt -> "Bearbeiten")."""
|
||||
if not id_:
|
||||
_LOGGER.warning("reifen_archiv_aktualisieren ohne id aufgerufen")
|
||||
return
|
||||
profil = await k.ablage.profil_lesen()
|
||||
if profil is None:
|
||||
return
|
||||
archiv = profil.setdefault("reifen", {}).setdefault("archiv", [])
|
||||
eintrag = next((e for e in archiv if e.get("id") == id_), None)
|
||||
if eintrag is None:
|
||||
_LOGGER.warning("Archivierter Reifensatz '%s' nicht gefunden", id_)
|
||||
return
|
||||
|
||||
erlaubte_felder = (
|
||||
"ersetzt_am", "km", "marke", "modell", "dot", "mass",
|
||||
"druck_vorne", "druck_hinten", "kommentar",
|
||||
)
|
||||
for feld in erlaubte_felder:
|
||||
if feld in daten and daten[feld] is not None:
|
||||
eintrag[feld] = daten[feld]
|
||||
|
||||
await k.ablage.profil_schreiben(profil)
|
||||
await k.profil_veroeffentlichen(profil)
|
||||
_LOGGER.info("Archivierter Reifensatz '%s' aktualisiert", id_)
|
||||
|
||||
|
||||
async def archiv_loeschen(k: Koordinator, id_: str | None) -> None:
|
||||
if not id_:
|
||||
_LOGGER.warning("reifen_archiv_loeschen ohne id aufgerufen")
|
||||
return
|
||||
profil = await k.ablage.profil_lesen()
|
||||
if profil is None:
|
||||
return
|
||||
reifen = profil.setdefault("reifen", {})
|
||||
archiv = reifen.get("archiv", [])
|
||||
uebrig = [e for e in archiv if e.get("id") != id_]
|
||||
if len(uebrig) == len(archiv):
|
||||
_LOGGER.warning("Archivierter Reifensatz '%s' nicht gefunden", id_)
|
||||
return
|
||||
reifen["archiv"] = uebrig
|
||||
await k.ablage.profil_schreiben(profil)
|
||||
await k.profil_veroeffentlichen(profil)
|
||||
_LOGGER.info("Archivierter Reifensatz '%s' gelöscht", id_)
|
||||
|
||||
|
||||
def zustaende(profil: dict | None) -> dict[str, object]:
|
||||
"""Die drei Kontrollwerte für die eigenen Reifen-Entitäten.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user