OTA-Updates für die iOS-App; HACS-Fehlannahme korrigiert
HACS kann laut eigener Dokumentation grundsätzlich nicht mit privaten GitHub-Repositories arbeiten (hacs.xyz/docs/faq/private_repositories) - keine Ausnahme für Tokens oder verbundene Konten. Meine frühere Annahme, HACS käme damit zurecht, wenn es unter dem richtigen Konto angemeldet ist, war falsch. Da das Repository aus Lizenzgründen privat bleiben muss (Audi-Hausschrift, Typenschilder), ist install.ps1 damit nicht die Rückfallebene, sondern der einzige Installationsweg - README, INSTALL.md, ANLEITUNG.md, install.ps1 und VERSIONIERUNG.md korrigiert. Oberflächen-Updates für die iOS-App laufen jetzt ohne Xcode: @capgo/capacitor-updater eingebaut, ein Update-Abschnitt in den Einstellungen lädt ein neues Bündel und tauscht die Oberfläche aus. Kein Selbstlauf (autoUpdate: false) - nur auf Tastendruck, nie während der Benutzung. Das Bündel liegt in der Integration selbst (custom_components/audi_dashboard/frontend/app/), nicht unter /local/: so reist es bei jeder Installation automatisch mit, ohne zweiten Auslieferungsweg. Gebaut von companion-app/scripts/ota-paket.ps1 (neuer Befehl: npm run ota), gemeldet über sensor.audi_dashboard_app_version (neues Feld daten.buendel). Ein echter Bug beim Bauen gefunden: [IO.Compression.ZipFile]::CreateFrom- Directory schreibt unter Windows PowerShell 5.1 Backslashes in die Zip-Einträge - iOS hätte das Archiv falsch entpackt. Behoben, indem die Einträge von Hand mit "/" geschrieben werden. Rückfallebene: notifyAppReady() läuft erst, wenn React nachweislich gerendert hat (App.tsx). Kommt diese Meldung nicht, rollt das Plugin nach 20 Sekunden von selbst auf das vorherige Bündel zurück. Am laufenden Testcontainer verifiziert: die ausgelieferte Zip hasht exakt auf den in bundle.json hinterlegten Wert, 13 Einträge, index.html in der Wurzel, keine Backslashes, keine Beschädigung. tsc sauber, 117/117 Tests (5 davon neu für buendelPasst() - dabei eine echte Lücke gefunden: die Funktion hätte bei unbekannter eigener Version fälschlich ein Update angeboten, jetzt genauso vorsichtig wie versionVergleichen). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,14 @@ export * from "./warteschlange.ts";
|
||||
export * from "./ablageNativ.ts";
|
||||
|
||||
import { DIENST_DOMAIN, ENTITAETEN } from "./types.ts";
|
||||
import type { Fahrt, Fahrzeugstatus, ImportErgebnis, Profil, Tankvorgang } from "./types.ts";
|
||||
import type {
|
||||
AppVersionAngabe,
|
||||
Fahrt,
|
||||
Fahrzeugstatus,
|
||||
ImportErgebnis,
|
||||
Profil,
|
||||
Tankvorgang,
|
||||
} from "./types.ts";
|
||||
import { HassRest } from "./rest.ts";
|
||||
import { HassLive } from "./live.ts";
|
||||
import { Warteschlange } from "./warteschlange.ts";
|
||||
@@ -172,16 +179,19 @@ export class DataMetricApi {
|
||||
return this.rest.dienstAufrufen(DIENST_DOMAIN, "jetzt_aktualisieren");
|
||||
}
|
||||
|
||||
/** Welchen Oberflächen-Stand das Backend ausliefert (Version der Integration, siehe
|
||||
VERSIONIERUNG.md). `null`, wenn die Entität fehlt — etwa weil das Backend
|
||||
älter ist als diese Funktion; dann wird nichts verglichen und nichts
|
||||
/** Nutzlast von sensor.audi_dashboard_app_version: welchen Stand das
|
||||
Backend ausliefert (`app`, siehe VERSIONIERUNG.md) und ob ein
|
||||
OTA-Bündel bereitliegt (`buendel`, siehe daten/ota.ts). Beides kommt
|
||||
aus derselben Entität und wird deshalb in einem Aufruf gelesen statt in
|
||||
zweien. `null` bei jedem Fehler — fehlende Entität (älteres Backend),
|
||||
Netzproblem, was auch immer; dann wird nichts verglichen und nichts
|
||||
gemeldet, statt einen Fehlalarm auszulösen. */
|
||||
async appVersionLesen(): Promise<string | null> {
|
||||
async appVersionAngabeLesen(): Promise<AppVersionAngabe | null> {
|
||||
try {
|
||||
const zustand = await this.rest.zustandLesen<{ daten?: { app?: string | null } }>(
|
||||
const zustand = await this.rest.zustandLesen<{ daten?: AppVersionAngabe }>(
|
||||
ENTITAETEN.appVersion,
|
||||
);
|
||||
return zustand.attributes?.daten?.app ?? null;
|
||||
return zustand.attributes?.daten ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -156,6 +156,28 @@ export interface ImportErgebnis {
|
||||
meldung?: string;
|
||||
}
|
||||
|
||||
/** Das OTA-Bündel, das die Integration mit ausliefert (siehe
|
||||
custom_components/audi_dashboard/koordinator.py `_buendel_lesen()` und
|
||||
companion-app/scripts/ota-paket.ps1). `null`, solange keine
|
||||
bundle.json neben der Integration liegt — ein völlig normaler Zustand,
|
||||
kein Fehler: wer nur das Panel nutzt, braucht kein App-Bündel. */
|
||||
export interface Buendelangabe {
|
||||
version: string;
|
||||
sha256: string;
|
||||
bytes: number;
|
||||
gebaut: string;
|
||||
/** Pfad relativ zur Home-Assistant-Basis-URL, z. B.
|
||||
"/audi_dashboard_static/app/bundle.zip". Von der Integration
|
||||
angehängt, steht nicht in bundle.json selbst. */
|
||||
url: string;
|
||||
}
|
||||
|
||||
/** Nutzlast von sensor.audi_dashboard_app_version. */
|
||||
export interface AppVersionAngabe {
|
||||
app: string | null;
|
||||
buendel: Buendelangabe | null;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------- Entitäts-Verzeichnis */
|
||||
|
||||
/** Alle vom Backend veröffentlichten Entitäten an einer Stelle.
|
||||
|
||||
Reference in New Issue
Block a user