pyscript-Backend zur echten HA-Integration umgebaut (HACS-fähig)

Das Backend liegt jetzt als custom_components/audi_dashboard/ vor - eine
normale Home-Assistant-Integration mit Config-Flow, einer sensor-Plattform
und 18 Diensten. Damit ist die App über HACS installierbar; bis das Repo auf
GitHub gespiegelt ist (HACS spricht ausschließlich mit GitHub), installiert
homeassistant/installationspaket/install.ps1 denselben Ordner ohne HACS.

Fünf Installationsschritte entfallen ersatzlos: der pyscript:-Block, der
panel_custom:-Block, das Kopieren der Oberfläche nach www/, das langlebige
Zugriffstoken (der Verlauf wird direkt über die recorder-API gelesen) und
"pip install pypdf" (steht in manifest.json). Das Fahrzeugprofil legt die
Integration beim ersten Start aus ihrer Vorlage an.

Drei alte Schwächen sind dabei mit erledigt:
- Die Nutzlast landet nicht mehr in der Recorder-Datenbank
  (_unrecorded_attributes - das kann nur eine echte Entität).
- Eine laufende Fahrt überlebt einen Neustart (Store statt Arbeitsspeicher);
  fiel sie während eines Ausfalls ins Ende, schließt
  nach_neustart_fortsetzen() sie beim letzten aufgezeichneten Zeitpunkt.
- Sensor-Zuordnungen wirken sofort - die Zustandsbeobachter werden neu
  gebunden, der Neustart-Hinweis und der Neustart-Dienst sind weg.

Namensvertrag geändert, beide Oberflächen mitgezogen:
pyscript.audi_dashboard_x -> sensor.audi_dashboard_x,
pyscript.audi_dashboard_y -> audi_dashboard.y. Eine Companion-App vom alten
Stand findet nach dem Umstieg nichts mehr und muss neu gebaut werden; das
Panel liegt in der Integration und kann nicht driften.

Der selbstgebaute Updater entfällt - HACS ist die Update-Mechanik, die Home
Assistant kennt. Die Versionierung schrumpft auf eine Quelle: manifest.json.

Geprüft am laufenden Testcontainer (Container byteweise identisch mit dem
Repo): alle 18 Dienste, Panel, Config-Entry neu laden, Historienimport,
echter Shell-Beleg in-process, Neuinstallation im Wegwerf-Container blank mit
automatisch nachinstalliertem pypdf. Companion-App: tsc sauber, 112/112
Tests, beide Rauchtests gegen das laufende Backend grün. Belegparser 8/8.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-08-23 23:53:56 +02:00
co-authored by Claude Opus 5
parent 99cef7c393
commit d8b12da36d
136 changed files with 5289 additions and 17641 deletions
+13 -7
View File
@@ -1,7 +1,7 @@
# testumgebung/ — Wegwerf-Home-Assistant für Entwicklung und Tests
Setzt eine vollständige Home-Assistant-Instanz in Docker auf, in der das
pyscript-Backend dieses Projekts echt läuft: eigene Entitäten, echte Service-Aufrufe,
Setzt eine vollständige Home-Assistant-Instanz in Docker auf, in der die
Integration dieses Projekts echt läuft: eigene Entitäten, echte Dienstaufrufe,
nachgebildete Fahrzeugsensoren. Gedacht als Ziel für die Abnahmekriterien aus
`../UMSETZUNGSPLAN.md` (Phasen 1, 6, 9).
@@ -17,9 +17,15 @@ hier als ausführbares Skript statt als Anleitung.
Das Skript ist mehrfach ausführbar (löscht einen vorhandenen Container vorher).
Es lädt das offizielle Image, startet den Container auf **Port 18123**, legt per
API einen Testnutzer an, erzeugt ein langlebiges Zugriffstoken, installiert
pyscript als Custom Component, kopiert `../homeassistant/{pyscript,www,data}`
hinein und startet neu.
API einen Testnutzer an, erzeugt ein langlebiges Zugriffstoken, kopiert
`../custom_components/audi_dashboard` hinein, startet neu und legt den
Konfigurationseintrag über die API an.
Seit dem Umbau zur eigenen Integration (2026-08-23) fällt dabei einiges weg,
was vorher nötig war: pyscript herunterladen und einrichten, das Backend nach
`pyscript/` und die Oberfläche nach `www/` kopieren, ein Fahrzeugprofil aus der
Vorlage anlegen, den Belegleser ablegen und ein Zugriffstoken in eine Datei
schreiben. Alles davon macht die Integration jetzt selbst.
Am Ende schreibt es das Token nach `../companion-app/.env.local`
(Variable `VITE_TEST_TOKEN`, gitignored) — von dort holen es die
@@ -31,7 +37,7 @@ authentifizierten Tests.
`konfiguration.yaml` bildet zwei Datenquellen als Template-Sensoren nach, damit
das Backend echte Werte sieht. Steuerbar zur Laufzeit über Helfer — damit
lassen sich die `@state_trigger`-Abläufe wirklich auslösen:
lassen sich die Erkennungsabläufe (Fahrt, Tanken, Reifen) wirklich auslösen:
| Helfer | Steuert | Wofür |
|---|---|---|
@@ -44,7 +50,7 @@ lassen sich die `@state_trigger`-Abläufe wirklich auslösen:
Die Kilometerstand-/Tankfüllstand-/Reichweite- und Tür-/Fenster-Sensoren
bilden die Entitäten der abgelösten HACS-Integration `TommiG1/HA_VAG-EU-Data-Act`
nach (siehe `einstellungen.py`) — für den Standardbetrieb ohne Bedeutung, aber
nach (siehe `custom_components/audi_dashboard/einstellungen.py`) — für den Standardbetrieb ohne Bedeutung, aber
weiterhin nützlich, um die manuelle Zuordnung über das Setup-Menü zu testen.
(Türschloss- und Haubenschloss-Erkennung wurden 2026-08-16 ersatzlos aus der
App entfernt, siehe `AGENTS.md`.)
+31 -23
View File
@@ -39,34 +39,22 @@ if [ -z "$TOKEN" ]; then
exit 1
fi
echo "==> pyscript installieren"
VERSION="$(curl -s https://api.github.com/repos/custom-components/pyscript/releases/latest \
| grep -o '"tag_name": *"[^"]*"' | cut -d'"' -f4)"
TMPDL="$(mktemp -d)"
curl -sL -o "$TMPDL/pyscript.zip" \
"https://github.com/custom-components/pyscript/archive/refs/tags/${VERSION}.zip"
unzip -oq "$TMPDL/pyscript.zip" -d "$TMPDL"
mkdir -p "$ZIEL/custom_components"
cp -r "$TMPDL/pyscript-${VERSION}/custom_components/pyscript" "$ZIEL/custom_components/"
rm -rf "$TMPDL"
echo " pyscript $VERSION"
echo "==> Projektdateien einspielen"
# Seit dem Umbau zur eigenen Integration (2026-08-23) faellt hier einiges weg,
# was frueher noetig war: pyscript herunterladen und entpacken, das Backend
# nach pyscript/ kopieren, die Oberflaeche nach www/ kopieren, ein
# Fahrzeugprofil aus der Vorlage anlegen, den Belegleser ablegen und das
# Zugriffstoken in eine Datei schreiben. Alles davon macht die Integration
# jetzt selbst - hier bleibt ein einziger Kopiervorgang.
echo "==> Integration einspielen"
cp "$HIER/konfiguration.yaml" "$ZIEL/configuration.yaml"
cp -r "$PROJEKT/homeassistant/pyscript" "$ZIEL/pyscript"
mkdir -p "$ZIEL/www" "$ZIEL/audi_dashboard"
cp -r "$PROJEKT/homeassistant/www/." "$ZIEL/www/"
cp "$PROJEKT/homeassistant/data/fahrzeugprofil.example.json" \
"$ZIEL/audi_dashboard/fahrzeugprofil.json"
cp "$PROJEKT/homeassistant/data/shell_beleg_parser.py" "$ZIEL/audi_dashboard/"
: > "$ZIEL/audi_dashboard/fahrten.jsonl"
: > "$ZIEL/audi_dashboard/tankvorgaenge.jsonl"
printf '%s' "$TOKEN" > "$ZIEL/audi_dashboard/ha_token.txt"
mkdir -p "$ZIEL/custom_components"
cp -r "$PROJEKT/custom_components/audi_dashboard" "$ZIEL/custom_components/"
find "$ZIEL/custom_components/audi_dashboard" -name __pycache__ -type d -exec rm -rf {} + 2>/dev/null || true
echo "==> Neu starten"
docker restart "$NAME" >/dev/null
echo "==> Auf Backend warten"
echo "==> Auf Home Assistant warten"
for _ in $(seq 1 60); do
if [ "$(curl -s -o /dev/null -w '%{http_code}' --max-time 3 \
-H "Authorization: Bearer $TOKEN" "$BASIS/api/" || true)" = "200" ]; then
@@ -75,6 +63,25 @@ for _ in $(seq 1 60); do
sleep 5
done
# Der Konfigurationseintrag entsteht sonst nur ueber die Oberflaeche. Der
# Ablauf hat keine Eingabefelder, deshalb genuegen zwei Aufrufe: Ablauf
# starten, Ablauf mit leerem Formular bestaetigen.
echo "==> Integration hinzufuegen"
FLOW="$(curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"handler":"audi_dashboard","show_advanced_options":false}' \
"$BASIS/api/config/config_entries/flow" | sed 's/.*"flow_id":"\([^"]*\)".*/\1/')"
if [ -z "$FLOW" ]; then
echo "FEHLER: Konfigurationsablauf liess sich nicht starten" >&2
exit 1
fi
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{}' "$BASIS/api/config/config_entries/flow/$FLOW" >/dev/null
echo "==> Pruefen, ob die Entitaeten da sind"
ANZAHL="$(curl -s -H "Authorization: Bearer $TOKEN" "$BASIS/api/states" \
| tr ',' '\n' | grep -c '"entity_id":"sensor.audi_dashboard' || true)"
echo " $ANZAHL Entitaeten sensor.audi_dashboard_*"
echo "==> Token nach companion-app/.env.local schreiben"
printf 'VITE_TEST_URL=%s\nVITE_TEST_TOKEN=%s\n' "$BASIS" "$TOKEN" \
> "$PROJEKT/companion-app/.env.local"
@@ -82,3 +89,4 @@ printf 'VITE_TEST_URL=%s\nVITE_TEST_TOKEN=%s\n' "$BASIS" "$TOKEN" \
echo
echo "Fertig. $BASIS · Benutzer test · Passwort testtest123"
echo "Token liegt in companion-app/.env.local (gitignored)."
echo "Sensoren zuordnen: in der App unter Einstellungen -> Fahrzeug einrichten -> Setup."
+6 -13
View File
@@ -1,11 +1,11 @@
# Wegwerf-Testinstanz fuer DataMetric360.
# Bildet zwei Datenquellen nach: den FMM003-Zuendungssensor (Fahrterkennung,
# aktiv per Standard in einstellungen.py) sowie die Entitaeten der
# im Auslieferstand nicht zugeordnet) sowie die Entitaeten der
# abgeloesten HACS-Integration TommiG1/HA_VAG-EU-Data-Act (Kilometerstand,
# Tankfuellstand, Tueren/Fenster - in einstellungen.py per Default leer,
# Tankfuellstand, Tueren/Fenster - alle im Auslieferstand leer,
# aber ueber das Setup-Menue weiterhin manuell zuordenbar). Ueber die
# input_*-Helfer sind die Werte zur Laufzeit aenderbar (Fahrterkennung,
# Reifenzaehler, Tankerkennung haengen an @state_trigger).
# Reifenzaehler, Tankerkennung beobachten die zugeordneten Entitaeten).
default_config:
@@ -20,16 +20,9 @@ http:
- capacitor://localhost # native Huelle iOS
- ionic://localhost # native Huelle Android
pyscript:
allow_all_imports: true
panel_custom:
- name: audi-dashboard-panel
sidebar_title: Mein Audi
sidebar_icon: mdi:car-sports
module_url: /local/audi-dashboard-panel.js?v=1
embed_iframe: false
trust_external_script: false
# Frueher standen hier ein pyscript:- und ein panel_custom:-Block. Beide sind
# mit dem Umbau zur eigenen Integration entfallen: sie meldet ihr Panel selbst
# an und braucht dafuer kein YAML.
input_number:
test_kilometerstand: