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 <noreply@anthropic.com>
This commit is contained in:
@@ -11797,3 +11797,60 @@ Die Gestaltung des zweiten Abschnitts gegengeprueft, indem einer eingesetzt
|
||||
wurde: Haarlinie 0.8px, 16px Abstand und 16px Polster darueber, Abschnittskopf
|
||||
14px ueber seinem Inhalt. Der Abschnitt selbst ist nur in der nativen Huelle zu
|
||||
sehen - im Browser ist `otaMoeglich()` falsch.
|
||||
|
||||
## CX. Die Integration bot Rueckschritte als Update an (2026.9.5.19)
|
||||
|
||||
Gemeldet: *"Warum wird eine aeltere Version angeboten? .16 ist aelter als
|
||||
.18"*. In `aktualisierung.py` stand:
|
||||
|
||||
"verfuegbar": remote_version != eigene_version
|
||||
|
||||
Reine Ungleichheit, ohne Richtung. Lief die Instanz einer Veroeffentlichung
|
||||
voraus - waehrend der Entwicklung der Normalfall -, bot die Integration an,
|
||||
sich auf die AELTERE Fassung zu "aktualisieren".
|
||||
|
||||
Es ist derselbe Fehler, der am 04.09.2026 fuer die App behoben wurde
|
||||
(`appVersion.ts`: *"erkannt werden soll eine NEUERE Fassung und keine
|
||||
andere"*), nur auf der anderen Seite - und er blieb dort stehen, weil damals
|
||||
nur die App angesehen wurde.
|
||||
|
||||
`ist_neuer()` ist jetzt das Gegenstueck zu `versionOrdnung()`, mit denselben
|
||||
drei Eigenschaften:
|
||||
|
||||
* Fehlende Stellen zaehlen als 0, `2026.9.4` und `2026.9.4.0` sind derselbe
|
||||
Stand.
|
||||
* Kein `int()` mit Vorabschnitt - "4b" darf nicht klaglos als 4 gelesen werden,
|
||||
sonst entsteht genau die scheingenaue Reihenfolge, die vermieden werden soll.
|
||||
* Laesst sich keine Reihenfolge bilden (Formatwechsel), gilt die Fassung als
|
||||
verfuegbar: die Oberflaeche sagt dann, dass etwas abweicht, aber nicht in
|
||||
welche Richtung - besser als eine Aenderung zu verschweigen.
|
||||
|
||||
Sechs neue Faelle in `tests/aktualisierung/test_aktualisierung.py`, 79 Tests
|
||||
gruen. Live gegengeprueft: Gitea auf .18, Instanz auf .19 - gemeldet wird
|
||||
"aktuell" statt eines Rueckschritts.
|
||||
|
||||
### Die Kachel wurde dabei schlanker
|
||||
|
||||
Vorgabe des Eigentuemers: *"Statt Installiert 'Home-Assistant-Integration' zu
|
||||
schreiben. Dann haette der User die Sicht: Was ist in welcher Version vorhanden
|
||||
auf seinem Geraet."* Die Zeile benennt jetzt selbst, was sie zeigt:
|
||||
|
||||
Home-Assistant-Integration 2026.9.5.19
|
||||
aktuell geprueft 05.09.2026, 11:32 Uhr
|
||||
|
||||
Damit entfallen auch die Abschnitts-Ueberschriften "Integration"/"App" aus
|
||||
CW - sie sagten dasselbe ein zweites Mal. Die beiden Bloecke trennt weiterhin
|
||||
eine Haarlinie, und benannt sind sie durch ihre eigene Zeile.
|
||||
|
||||
**"aktuell" erscheint nur nach einer Pruefung.** Vorher steht dort gar nichts:
|
||||
gruen "aktuell" ohne Pruefung waere eine Behauptung ohne Grundlage, und der
|
||||
Knopf "Auf Update pruefen" sagt den Zustand ohnehin. Es gibt keinen
|
||||
automatischen Takt - geprueft wird nur auf Knopfdruck (nachgesehen, kein
|
||||
`async_track_time_interval` dafuer).
|
||||
|
||||
Gemessen in beiden: Farbe `rgb(52,199,89)` bzw. `rgb(48,209,88)` - das ist
|
||||
`--ok` im jeweiligen Thema.
|
||||
|
||||
**Offen, zur Entscheidung:** "Home-Assistant-Integration" bricht als Beschriftung
|
||||
auf Telefonbreite in zwei Zeilen um. Lesbar, aber unruhig. "Integration" allein
|
||||
wuerde einzeilig passen.
|
||||
|
||||
@@ -748,21 +748,15 @@ export function Einstellungen({
|
||||
<Tile>
|
||||
<span className="ads-eyebrow">Version</span>
|
||||
|
||||
{/* Die Zeile benennt selbst, WAS in welcher Fassung auf dem Geraet
|
||||
liegt - vorher hiess das Label "Installiert" und der Gegenstand
|
||||
stand klein darunter. Damit braucht der Abschnitt auch keine
|
||||
Ueberschrift mehr: sie saegte dasselbe ein zweites Mal (Vorgabe
|
||||
des Eigentuemers, 05.09.2026: "damit wird es nochmal schlanker"). */}
|
||||
<div className="dm-kachelabschnitt">
|
||||
{/* Nur wenn darunter wirklich ein zweiter Abschnitt folgt. Ohne den
|
||||
staende "Integration" allein unter "Version" - eine Unterteilung
|
||||
ohne zweiten Teil, genau wie im Panel, das den App-Abschnitt gar
|
||||
nicht kennt. */}
|
||||
{otaMoeglich() && <span className="ads-eyebrow">Integration</span>}
|
||||
<Werteliste
|
||||
kinder={
|
||||
<Wertzeile
|
||||
label="Installiert"
|
||||
wert={serverVersion ?? "unbekannt"}
|
||||
zusatz="Home-Assistant-Integration"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Werteliste
|
||||
kinder={<Wertzeile label="Home-Assistant-Integration" wert={serverVersion ?? "unbekannt"} />}
|
||||
/>
|
||||
{/* HIG "Loading": Netzwerk zu Gitea plus Entpacken dauert unbestimmt
|
||||
lang, ohne verlässliche Fortschrittsangabe - ein laufender
|
||||
Indikator statt eines nur deaktivierten Knopfes verhindert, dass
|
||||
@@ -865,12 +859,7 @@ export function Einstellungen({
|
||||
|
||||
{otaMoeglich() && (
|
||||
<div className="dm-kachelabschnitt">
|
||||
<span className="ads-eyebrow">App</span>
|
||||
<Werteliste
|
||||
kinder={
|
||||
<Wertzeile label="Installiert" wert={eigeneVersion() ?? "unbekannt"} zusatz="Diese App" />
|
||||
}
|
||||
/>
|
||||
<Werteliste kinder={<Wertzeile label="App" wert={eigeneVersion() ?? "unbekannt"} />} />
|
||||
{otaUpdateVerfuegbar && otaBuendel ? (
|
||||
<>
|
||||
<Werteliste
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":"2026.9.5.18","sha256":"8b03fe0a871e5fc88b421146910832fbd73999ee9844000efbaf1b41a52ab603","bytes":324620,"gebaut":"2026-09-05T09:27:15Z"}
|
||||
{"version":"2026.9.5.19","sha256":"5490ca4a341da15dd210a13f84fb6941620d2974683b3c4280ea31ed87f0fb7c","bytes":324597,"gebaut":"2026-09-05T09:31:37Z"}
|
||||
Binary file not shown.
@@ -3719,7 +3719,7 @@ function vEinst() {
|
||||
(Vorgabe des Eigentuemers, 04.09.2026). -->
|
||||
<div class="tile"><span class="label">Version</span>
|
||||
<dl class="rows">
|
||||
<div class="row" style="border-bottom:0"><dt>Installiert</dt><dd>${esc(APP_VERSION || "unbekannt")}<small>Home-Assistant-Integration</small></dd></div>
|
||||
<div class="row" style="border-bottom:0"><dt>Home-Assistant-Integration</dt><dd>${esc(APP_VERSION || "unbekannt")}</dd></div>
|
||||
</dl>
|
||||
${(() => {
|
||||
const u = INTEGRATION_UPDATE;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "audi_dashboard",
|
||||
"name": "Audi Dashboard",
|
||||
"version": "2026.9.5.18",
|
||||
"version": "2026.9.5.19",
|
||||
"documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md",
|
||||
"issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues",
|
||||
"codeowners": [
|
||||
|
||||
@@ -188,5 +188,41 @@ class AbgelehnteFaelle(unittest.TestCase):
|
||||
self._unangetastet()
|
||||
|
||||
|
||||
class VersionsOrdnung(unittest.TestCase):
|
||||
"""Nur eine NACHWEISLICH neuere Fassung ist ein Update.
|
||||
|
||||
Bis zum 05.09.2026 stand in version_pruefen() `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: .16 wurde angeboten,
|
||||
waehrend .18 lief)."""
|
||||
|
||||
def test_neuere_fassung_ist_ein_update(self):
|
||||
self.assertIs(a.ist_neuer("2026.9.5.18", "2026.9.5.16"), True)
|
||||
self.assertIs(a.ist_neuer("2026.10.1.1", "2026.9.5.99"), True)
|
||||
self.assertIs(a.ist_neuer("2027.1.1.1", "2026.12.31.9"), True)
|
||||
|
||||
def test_aeltere_fassung_ist_keins(self):
|
||||
self.assertIs(a.ist_neuer("2026.9.5.16", "2026.9.5.18"), False)
|
||||
self.assertIs(a.ist_neuer("2026.9.4.26", "2026.9.5.1"), False)
|
||||
|
||||
def test_gleichstand_ist_keins(self):
|
||||
self.assertIs(a.ist_neuer("2026.9.5.18", "2026.9.5.18"), False)
|
||||
|
||||
def test_fehlende_stellen_zaehlen_als_null(self):
|
||||
self.assertIs(a.ist_neuer("2026.9.4", "2026.9.4.0"), False)
|
||||
self.assertIs(a.ist_neuer("2026.9.4.1", "2026.9.4"), True)
|
||||
|
||||
def test_nicht_sortierbar_bleibt_offen(self):
|
||||
# Formatwechsel: lieber "nicht entscheidbar" als eine erfundene
|
||||
# Reihenfolge. "4b" darf nicht klaglos als 4 gelesen werden.
|
||||
self.assertIsNone(a.ist_neuer("2026.9.4b", "2026.9.4.1"))
|
||||
self.assertIsNone(a.ist_neuer("v2", "2026.9.5.1"))
|
||||
self.assertIsNone(a.ist_neuer("", "2026.9.5.1"))
|
||||
|
||||
def test_zeichengleich_ist_gleich_auch_bei_fremdem_format(self):
|
||||
self.assertIs(a.ist_neuer("beliebig", "beliebig"), False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user