Kein Rueckschritt mehr als Update, Version-Kachel schlanker

aktualisierung.py pruefte mit `remote_version != eigene_version` - reine
Ungleichheit ohne Richtung. Lief die Instanz einer Veroeffentlichung voraus,
bot die Integration an, sich auf die aeltere Fassung zu aktualisieren. Vom
Eigentuemer gemeldet. ist_neuer() ist jetzt das Gegenstueck zu
versionOrdnung() in appVersion.ts, wo derselbe Fehler am 04.09. behoben wurde:
fehlende Stellen zaehlen als 0, kein int() mit Vorabschnitt, und was sich
nicht in eine Reihenfolge bringen laesst, gilt als verfuegbar statt
verschwiegen. Sechs neue Testfaelle, 79 Python-Tests gruen.

Dazu auf Vorgabe des Eigentuemers: die Zeile benennt jetzt selbst, was sie
zeigt - "Home-Assistant-Integration | 2026.9.5.19" statt "Installiert" mit dem
Gegenstand klein darunter. Damit entfallen die Abschnitts-Ueberschriften aus
dem vorigen Commit, sie sagten dasselbe doppelt.

Live in beiden Oberflaechen gegengeprueft: Gitea auf .18, Instanz auf .19 -
gemeldet wird gruenes "aktuell" (--ok) mit Pruefzeitpunkt statt eines
Rueckschritts. 0 Tracebacks.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-05 11:33:56 +02:00
co-authored by Claude Opus 5
parent f693a41692
commit 5a65ec9590
8 changed files with 158 additions and 24 deletions
@@ -84,6 +84,54 @@ def _header(token: str) -> dict[str, str]:
return {"Authorization": f"token {token}"}
def _versionsteile(version: str) -> list[int] | None:
"""Zerlegt `2026.9.4.17` in [2026, 9, 4, 17].
`None`, sobald ein Teil keine reine Ziffernfolge ist - dann wird nicht
sortiert. Bewusst kein `int()` mit Vorabschnitt: das läse "4b" klaglos als
4 und erzeugte genau die scheingenaue Reihenfolge, die hier vermieden
werden soll. Wortgleich mit `teile()` in
companion-app/src/daten/appVersion.ts."""
if not version:
return None
zahlen: list[int] = []
for stueck in version.split("."):
if not stueck.isdigit():
return None
zahlen.append(int(stueck))
return zahlen
def ist_neuer(kandidat: str, bisher: str) -> bool | None:
"""Ob `kandidat` nachweislich neuer ist als `bisher`.
`None` heißt "nicht zu entscheiden" - verschieden, aber nicht in eine
Reihenfolge zu bringen (Formatwechsel). Fehlende Stellen zählen als 0,
damit `2026.9.4` und `2026.9.4.0` denselben Stand bezeichnen.
Gegenstück zu `versionOrdnung()` in appVersion.ts. Der Grund ist derselbe
und dort ausführlich vermerkt: bis zum 05.09.2026 stand hier
`remote_version != eigene_version`, also reine Ungleichheit ohne Richtung.
Lief die Instanz einer Veröffentlichung voraus - während der Entwicklung
der Normalfall -, bot die Integration an, sich auf die ÄLTERE Fassung zu
"aktualisieren". Vom Eigentümer am 05.09.2026 gemeldet: „Warum wird eine
ältere Version angeboten? .16 ist älter als .18"."""
if not kandidat or not bisher:
return None
if kandidat == bisher:
return False
links = _versionsteile(kandidat)
rechts = _versionsteile(bisher)
if links is None or rechts is None:
return None
for i in range(max(len(links), len(rechts))):
l = links[i] if i < len(links) else 0
r = rechts[i] if i < len(rechts) else 0
if l != r:
return l > r
return False
async def version_pruefen(hass: HomeAssistant, token: str, eigene_version: str) -> dict[str, Any]:
"""Fragt nur die manifest.json von Gitea ab (ein kleiner Request, kein
Repo-Download) und vergleicht die Version gegen die installierte.
@@ -120,7 +168,11 @@ async def version_pruefen(hass: HomeAssistant, token: str, eigene_version: str)
raise AktualisierungsFehler(f"Antwort von Gitea nicht lesbar: {fehler}") from fehler
return {
"verfuegbar": remote_version != eigene_version,
# Nur eine NACHWEISLICH neuere Fassung ist ein Update. Ist sie nicht
# in eine Reihenfolge zu bringen (None), gilt sie als verfuegbar -
# dann sagt die Oberflaeche, dass etwas abweicht, aber nicht in
# welche Richtung, statt eine Aenderung zu verschweigen.
"verfuegbar": ist_neuer(remote_version, eigene_version) is not False,
"version": remote_version,
"geprueft_am": datetime.datetime.now(datetime.timezone.utc).isoformat(),
}