Selbst-Update: Ladezustand und echter Neustart-Knopf
Der erste echte Live-Test des Selbst-Updates gegen das private Gitea-Repo lief erfolgreich (mehrfach im Test-Container bestätigt) - deckte aber zwei UX-Lücken auf, die der Owner direkt gemeldet hat: - Prüfen/Installieren gaben während der 15-25 Sekunden dauernden Netzwerkaktion keine sichtbare Rückmeldung - nicht von einem Hänger zu unterscheiden. Jetzt ein Ladeindikator (Panel: wiederverwendetes .lade-spinner; companion-app: neues .dm-spinner-Äquivalent, gab es dort noch gar nicht). - Nach erfolgreicher Installation stand nur ein Hinweistext da, kein Weg zum eigentlich nötigen nächsten Schritt. Der Knopf wechselt jetzt zu "Installation abschließen - Jetzt neu starten" und stößt homeassistant.restart direkt an. Das separat gemeldete "Lädt"-Hängenbleiben war kein Bug: reproduziert durch Live-Test des neuen Neustart-Knopfs - eine echte HA-Verbindungsunterbrechung während eines Neustarts zeigt exakt denselben, bereits bestehenden Bootstrap-Ladebildschirm. Vermutlich derselbe Effekt durch den Docker-Neustart früher in dieser Sitzung. Verifiziert im Test-Container per Browser-Automatisierung: Neustart-Knopf ausgelöst, Verbindungsabbruch beobachtet, per docker logs bestätigt, dass Home Assistant tatsächlich neu gestartet ist und die neue Version aktiv wurde. Details in AGENTS.md, Abschnitt L. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
{"version":"2026.8.24.5","sha256":"378a1cbc7f5daa3d8c5d74734a4c09f30557b243a8ce4d720240bf911fbeff76","bytes":232096,"gebaut":"2026-08-24T10:29:33Z"}
|
||||
{"version":"2026.8.24.6","sha256":"e0d8c7a6f4cc7fddc59b252e02e4ebf50002f3bd4e317ddb315670ef13299d75","bytes":232382,"gebaut":"2026-08-24T10:44:09Z"}
|
||||
Binary file not shown.
@@ -2426,16 +2426,32 @@ function vEinst() {
|
||||
<div class="tile"><span class="label">Integration-Update</span>
|
||||
${(() => {
|
||||
const u = INTEGRATION_UPDATE;
|
||||
const laeuft = INTEGRATION_UPDATE_LAEUFT;
|
||||
// Ersetzt install.ps1 als laufenden Update-Weg (Windows Smart App
|
||||
// Control blockiert dessen Ausführung zuverlässig) - install.ps1
|
||||
// bleibt nur noch für die Erstinstallation nötig, bevor die
|
||||
// Integration überhaupt läuft und sich selbst aktualisieren kann.
|
||||
//
|
||||
// HIG "Loading": Netzwerk zu Gitea plus Entpacken dauert unbestimmt
|
||||
// lang, ohne verlässliche Fortschrittsangabe - ein laufender
|
||||
// Indikator statt eines stumm daliegenden Knopfes verhindert, dass
|
||||
// das wie ein Hänger aussieht (derselbe Grund wie beim
|
||||
// Erstladen-Spinner, .lade-spinner). Nach Erfolg führt der Knopf
|
||||
// direkt zum nächsten nötigen Schritt (Neustart), statt den Nutzer
|
||||
// selbst suchen zu lassen.
|
||||
const spinner = (text) => `<div style="display:flex;align-items:center;gap:10px;margin-top:8px">
|
||||
<span class="lade-spinner" aria-hidden="true"></span>
|
||||
<span class="label" style="margin:0">${esc(text)}</span>
|
||||
</div>`;
|
||||
if (laeuft === "installieren") return spinner("Installiere …");
|
||||
if (laeuft === "neustart") return spinner("Home Assistant startet neu …");
|
||||
if (u && u.installiert) {
|
||||
return `<span style="display:block;margin-top:8px;color:var(--fg2);font-size:13.5px;line-height:1.6">
|
||||
Version ${esc(u.version)} installiert. Home Assistant neu starten, damit die neue
|
||||
Fassung geladen wird - Einstellungen -> System -> Neu starten.</span>
|
||||
<button class="aktion" style="margin-top:14px" data-update="pruefen">Erneut prüfen</button>`;
|
||||
Version ${esc(u.version)} installiert - die neue Fassung wird erst nach einem Neustart
|
||||
geladen.</span>
|
||||
<button class="aktion" style="margin-top:14px" data-update="neustart">Installation abschließen - Jetzt neu starten</button>`;
|
||||
}
|
||||
if (laeuft === "pruefen") return spinner("Prüfe …");
|
||||
if (u && u.verfuegbar) {
|
||||
return `<dl class="rows"><div class="row" style="border-bottom:0"><dt>Verfügbare Version</dt><dd>${esc(u.version)}</dd></div></dl>
|
||||
<span style="display:block;margin-top:8px;color:var(--fg2);font-size:13.5px;line-height:1.6">
|
||||
@@ -2448,7 +2464,7 @@ function vEinst() {
|
||||
${u ? `Integration ist aktuell${u.geprueft_am ? ` (geprüft ${dedat(new Date(u.geprueft_am))})` : ""}.` : "Noch nicht geprüft."}</span>
|
||||
<button class="aktion" style="margin-top:14px" data-update="pruefen">Auf Update prüfen</button>`;
|
||||
})()}
|
||||
${INTEGRATION_UPDATE && INTEGRATION_UPDATE.fehler
|
||||
${INTEGRATION_UPDATE && INTEGRATION_UPDATE.fehler && !INTEGRATION_UPDATE_LAEUFT
|
||||
? `<span class="label" style="margin-top:10px;color:var(--red)">${esc(INTEGRATION_UPDATE.fehler)}</span>`
|
||||
: ""}
|
||||
</div>`;
|
||||
@@ -3156,6 +3172,12 @@ let APP_VERSION = null;
|
||||
// geprüft wurde. Ersetzt install.ps1 als Update-Weg, das Windows Smart App
|
||||
// Control zuverlässig blockiert; siehe vVersion()/Einstellungen-Ansicht.
|
||||
let INTEGRATION_UPDATE = null;
|
||||
// "pruefen" | "installieren" | "neustart" | null - während einer dieser drei
|
||||
// Aktionen läuft, siehe vEinst()'s Integration-Update-Kachel. Eigens statt
|
||||
// über serviceRufen() (das feuert-und-vergisst), weil diese drei Aktionen
|
||||
// unbestimmt lange dauern (Netzwerk zu Gitea, Entpacken) und die Oberfläche
|
||||
// das sichtbar machen soll - siehe .lade-spinner's eigener Kommentar dazu.
|
||||
let INTEGRATION_UPDATE_LAEUFT = null;
|
||||
|
||||
/* Auswahl für "Modell" unter Einrichten - setzt nur CONFIG.fahrzeugtitel
|
||||
(Zeile "Modell" in der Identität, Kopfzeilen, Kalender-Einträge, und den
|
||||
@@ -4515,8 +4537,33 @@ function ereignisseVerdrahten() {
|
||||
return;
|
||||
}
|
||||
const upd = e.target.closest("[data-update]");
|
||||
if (upd && upd.dataset.update === "pruefen") { serviceRufen("update_pruefen", {}); return; }
|
||||
if (upd && upd.dataset.update === "installieren") { serviceRufen("update_installieren", {}); return; }
|
||||
if (upd) {
|
||||
const aktion = upd.dataset.update;
|
||||
// Eigene Promise-Kette statt serviceRufen() (das feuert-und-vergisst) -
|
||||
// diese drei Aktionen brauchen einen sichtbaren Ladezustand, siehe
|
||||
// INTEGRATION_UPDATE_LAEUFT's Kommentar an der Deklaration.
|
||||
if (aktion === "pruefen" || aktion === "installieren") {
|
||||
INTEGRATION_UPDATE_LAEUFT = aktion; render();
|
||||
HASS.callService(DOMAIN, `update_${aktion}`, {})
|
||||
.catch((err) => {
|
||||
hinweis(
|
||||
aktion === "pruefen" ? "Prüfung fehlgeschlagen" : "Installation fehlgeschlagen",
|
||||
err && err.message ? err.message : "Der Dienst konnte nicht ausgeführt werden.",
|
||||
);
|
||||
})
|
||||
.finally(() => { INTEGRATION_UPDATE_LAEUFT = null; render(); });
|
||||
} else if (aktion === "neustart") {
|
||||
INTEGRATION_UPDATE_LAEUFT = "neustart"; render();
|
||||
HASS.callService("homeassistant", "restart", {}).catch((err) => {
|
||||
// Bricht die Verbindung normalerweise durch den Neustart selbst ab,
|
||||
// bevor diese Zeile überhaupt liefe - nur ein echter Fehlschlag
|
||||
// (Dienst abgelehnt, o.ä.) kommt hier tatsächlich an.
|
||||
hinweis("Neustart fehlgeschlagen", err && err.message ? err.message : "Home Assistant konnte nicht neu gestartet werden.");
|
||||
INTEGRATION_UPDATE_LAEUFT = null; render();
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
const cs = e.target.closest("[data-csv]");
|
||||
if (cs) {
|
||||
const w = cs.dataset.csv;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "audi_dashboard",
|
||||
"name": "Audi Dashboard",
|
||||
"version": "2026.8.24.5",
|
||||
"version": "2026.8.24.6",
|
||||
"documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md",
|
||||
"issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues",
|
||||
"codeowners": ["@paul"],
|
||||
|
||||
Reference in New Issue
Block a user