Nice Work

This commit is contained in:
2026-01-13 19:44:02 +00:00
parent b503b372b4
commit 0718377b27
144 changed files with 15587 additions and 2132 deletions
+5 -7
View File
@@ -21,22 +21,20 @@ Quickstart (3-5 Minuten):
http://127.0.0.1:9000/setup
```
3) WLAN-Profil eintragen und speichern.
4) Status pruefen:
4) Backend pruefen:
```
curl http://127.0.0.1:8000/status
curl http://127.0.0.1:5001/api/boxes
```
5) Playback starten:
5) Frontend oeffnen und Box pairen:
```
curl -X POST http://127.0.0.1:8000/command \
-H "Content-Type: application/json" \
-d '{"command":"nfc_on","payload":{"uid":"UID_1"}}'
http://127.0.0.1:5174
```
## Troubleshooting
- Box startet nicht:
- Pruefe Abhaengigkeiten und ob Ports 8000/9000 frei sind.
- GUI erreicht API nicht:
- Pruefe `VITE_BOX_API_URL` und Box-Logs.
- Pruefe `VITE_BACKEND_URL` und Backend-Logs.
## Was ist Mock vs. real
- Mock: WLAN, IP, Spotify, Audio, Hardware. Diese Backends sind logische Simulationen.
+39 -33
View File
@@ -186,7 +186,7 @@ curl -X POST http://127.0.0.1:8000/command \
- `/status` aendert sich nach Commands.
6) Abweichungen / Fehlersuche
- GUI "Failed to fetch": `VITE_BOX_API_URL` pruefen.
- GUI "Failed to fetch": `VITE_BACKEND_URL` pruefen.
---
@@ -197,7 +197,7 @@ curl -X POST http://127.0.0.1:8000/command \
2) Voraussetzungen
- Tags in `box/data/box.json`.
- Medien in `box/data/media`.
- Medien im Backend unter `gui/backend/media`.
3) Durchfuehrung Simulation / Emulation
```
@@ -245,7 +245,7 @@ curl -X POST http://127.0.0.1:8000/command \
- Rekursive Reihenfolge (DFS) ist korrekt.
2) Voraussetzungen
- Verschachtelte Ordner in `box/data/media`.
- Verschachtelte Ordner im Backend unter `gui/backend/media`.
3) Durchfuehrung Simulation / Emulation
- Tag auf `media/book_6` setzen, `nfc_on`.
@@ -310,7 +310,7 @@ curl -X POST http://127.0.0.1:8000/command \
---
# Server/Pairing-Tests (A-J)
# Backend/Pairing-Tests (A-J)
## Test A: Box-Erststart & Identitaet
@@ -334,15 +334,21 @@ curl -X POST http://127.0.0.1:8000/command \
---
## Test B: Announce -> neue Box erscheint im Server
## Test B: Announce -> neue Box erscheint im Backend
1) Ziel
- Box meldet sich beim Server und erscheint als UNPAIRED.
- Box meldet sich beim Backend und erscheint als UNPAIRED.
2) Voraussetzungen
- Server laeuft:
- Backend laeuft:
```
python3 server/main.py
cd gui/backend
npm run dev
```
- Frontend laeuft:
```
cd gui/frontend
npm run dev -- --host 0.0.0.0 --port 5174 --strictPort
```
3) Durchfuehrung Simulation / Emulation
@@ -351,26 +357,26 @@ python3 server/main.py
python3 box/main.py run
```
- 30-60s warten (Announce-Intervall).
- Server-GUI oeffnen:
- Frontend-GUI oeffnen:
```
http://127.0.0.1:7000/ui
http://127.0.0.1:5174
```
- Optional: Server-Storage pruefen:
- Optional: Backend-Storage pruefen:
```
cat server/data/boxes.json
sqlite3 gui/backend/db/klangkiste.sqlite "SELECT box_id, state, last_seen FROM boxes;"
```
4) Durchfuehrung Reale Box (Hardware)
- Box einschalten.
- Server-GUI oeffnen, Box sollte erscheinen.
- Frontend-GUI oeffnen, Box sollte erscheinen.
5) Erwartetes Ergebnis
- Box erscheint als UNPAIRED in der Server-GUI.
- `server/data/boxes.json` enthaelt `box_id` und `fingerprint`.
- Box erscheint als UNPAIRED in der Frontend-GUI.
- `gui/backend/db/klangkiste.sqlite` enthaelt `box_id` und `fingerprint`.
6) Abweichungen / Fehlersuche
- Keine Box sichtbar: Server-URL in `box/data/box.json` pruefen.
- Server nicht erreichbar: Server-Prozess/Port 7000 pruefen.
- Keine Box sichtbar: Backend-URL in `box/data/box.json` pruefen.
- Backend nicht erreichbar: Backend-Prozess/Port 5001 pruefen.
---
@@ -387,7 +393,7 @@ cat server/data/boxes.json
4) Durchfuehrung Reale Box (Hardware)
- Zwei physische Boxen einschalten.
- Server-GUI zeigt beide UNPAIRED an.
- Frontend-GUI zeigt beide UNPAIRED an.
5) Erwartetes Ergebnis
- Zwei Eintraege mit unterschiedlichen `box_id`.
@@ -397,34 +403,34 @@ cat server/data/boxes.json
---
## Test D: Pairing-Freigabe ueber Server-GUI
## Test D: Pairing-Freigabe ueber Frontend-GUI
1) Ziel
- Pairing liefert API-Token und Box wird PAIRED.
2) Voraussetzungen
- Box erscheint als UNPAIRED in `/ui`.
- Box erscheint als UNPAIRED in der Frontend-GUI.
3) Durchfuehrung Simulation / Emulation
- Server-GUI oeffnen:
- Frontend-GUI oeffnen:
```
http://127.0.0.1:7000/ui
http://127.0.0.1:5174
```
- Button "Box hinzufuegen" klicken.
- API-Token via Server-API abrufen:
- Button "Pairen" klicken.
- API-Token via Backend-API abrufen:
```
curl -X POST http://127.0.0.1:7000/api/boxes/pair -H "Content-Type: application/json" -d '{"box_id":"<box_id>"}'
curl -X POST http://127.0.0.1:5001/api/boxes/pair -H "Content-Type: application/json" -d '{"box_id":"<box_id>"}'
```
4) Durchfuehrung Reale Box (Hardware)
- Gleiches Vorgehen ueber Server-GUI.
- Gleiches Vorgehen ueber Frontend-GUI.
5) Erwartetes Ergebnis
- Box erscheint in der gepaarten Liste.
- `api_token` wird an die Box ausgeliefert.
6) Abweichungen / Fehlersuche
- Pairing bleibt aus: `server/data/boxes.json` pruefen.
- Pairing bleibt aus: `gui/backend/db/klangkiste.sqlite` pruefen.
---
@@ -526,24 +532,24 @@ rm -f box/data/box.json box/data/state.json box/data/secrets.enc
---
## Test I: Offline / Server nicht erreichbar
## Test I: Offline / Backend nicht erreichbar
1) Ziel
- Box laeuft weiter ohne Server.
- Box laeuft weiter ohne Backend.
2) Voraussetzungen
- Box laeuft, Server gestoppt.
- Box laeuft, Backend gestoppt.
3) Durchfuehrung Simulation / Emulation
- Server stoppen.
- Backend stoppen.
- Playback starten (mit Token falls gepairt).
4) Durchfuehrung Reale Box (Hardware)
- Server vom Netz trennen.
- Backend vom Netz trennen.
5) Erwartetes Ergebnis
- Lokale Playback-Logik laeuft weiter.
- Server-GUI zeigt Box ggf. als OFFLINE nach Timeout.
- Nicht testbar mit aktuellem Code: Backend markiert OFFLINE nicht.
6) Abweichungen / Fehlersuche
- Box stoppt: lokale Logs pruefen.
+11 -1
View File
@@ -29,6 +29,9 @@ Felder:
- `connected_ssid`: verbundene SSID oder `null`
- `wifi_profiles_count`: Anzahl gespeicherter Profile
- `spotify_status`: `NOT_CONFIGURED | READY`
- `last_nfc`:
- `uid`: letzte erkannte UID oder `null`
- `known`: `true` wenn Tag in der Box zugeordnet ist
- `playback_state`:
- `state`: `IDLE | PLAYING | PAUSED`
- `active_uid`
@@ -54,7 +57,7 @@ Beispielantwort:
"state": "PLAYING",
"active_uid": "UID_1",
"playback_root": "media/book_1",
"current_file": "/root/klangkiste/box/data/media/book_1/01.mp3",
"current_file": "/root/klangkiste/box/data/media/stories/dragons/album_1/track_01.mp3",
"file_index": 0,
"position": 42,
"duration": 180,
@@ -89,6 +92,13 @@ Unterstuetzte Commands:
- `wifi_reset`
- `spotify_set_tokens` `{ access_token, refresh_token, expires_at, account_id? }`
- `spotify_clear`
- `unpair`
- `tag_assign` `{ uid, media_path }`
- `tag_remove` `{ uid }`
## Tag-Commands
- `tag_assign` `{ uid, media_path }` weist ein Tag einem Medienordner zu.
- `tag_remove` `{ uid }` entfernt die Zuordnung fuer ein Tag.
## Auth fuer Commands
- Vor Pairing sind nur diese Commands erlaubt:
+1 -1
View File
@@ -52,4 +52,4 @@ exit | quit
- Commands nicht gefunden:
- Aus Repo-Root ausfuehren oder `box/main.py` voll referenzieren.
- Kein Playback:
- Tags in `box/data/box.json` und Medien in `box/data/media` pruefen.
- Tags in `box/data/box.json` und Medien im Backend unter `gui/backend/media` pruefen.
+9 -9
View File
@@ -14,19 +14,19 @@ Nutze die Sektionen nach Symptomen.
### GUI zeigt "Failed to fetch"
- API pruefen:
```
curl http://127.0.0.1:8000/status
curl http://127.0.0.1:5001/api/boxes
```
- GUI API-Base pruefen:
- `VITE_BOX_API_URL` oder Default `http://localhost:8000`
- `VITE_BACKEND_URL` oder Default `http://127.0.0.1:5001`
### Playback startet nicht
- Tags pruefen:
```
cat box/data/box.json
```
- Medien pruefen:
- Medienkatalog pruefen:
```
ls -la box/data/media
ls -la gui/backend/media
```
- Status pruefen:
```
@@ -44,10 +44,10 @@ cat box/data/state.json
- Port 9000 frei?
- Box laeuft?
### Box wird nicht erkannt (Server)
### Box wird nicht erkannt (Backend)
- Server-URL in `box/data/box.json` pruefen (`server_url`).
- Server laeuft auf Port 7000?
- `server/data/boxes.json` pruefen.
- Backend laeuft auf Port 5001?
- `gui/backend/db/klangkiste.sqlite` pruefen.
### Box erscheint mehrfach
- `box_id` in `box/data/box.json` pruefen.
@@ -58,7 +58,7 @@ cat box/data/state.json
- `box/data/box.json` darf nicht geloescht werden.
### Pairing haengt
- `server/data/boxes.json` pruefen: state, api_token.
- `gui/backend/db/klangkiste.sqlite` pruefen: state, api_token.
- Box-Status: `pairing_state` in `/status` pruefen.
## Reale Box (Hardware)
@@ -76,7 +76,7 @@ cat box/data/state.json
- Nicht testbar mit aktuellem Code.
### Box wird nicht erkannt / erscheint mehrfach / Fingerprint wechselt / Pairing haengt
- Server-GUI (`/ui`) pruefen.
- Frontend-GUI (`http://127.0.0.1:5174`) pruefen.
- Box-IP/Server-IP/VLAN pruefen.
- Box-Logs pruefen.
+17 -10
View File
@@ -13,34 +13,41 @@ Start/Stop der virtuellen Box, Logs, und GUI-API-Konfiguration.
```
./dev.sh
```
- GUI laeuft im Hintergrund.
- Box laeuft im Vordergrund und akzeptiert CLI-Kommandos.
- Frontend, Backend und Box laufen im Hintergrund.
- CLI-Kommandos fuer die Box bitte in einem separaten Terminal absetzen.
### Komponenten separat starten
Box only:
```
python3 box/main.py run
```
GUI only:
Frontend only:
```
cd gui
cd gui/frontend
npm run dev -- --host 0.0.0.0 --port 5174 --strictPort
```
Backend only:
```
cd gui/backend
npm run dev
```
## Ports / Hosts
- Server API + GUI: `http://127.0.0.1:7000` (GUI unter `/ui`)
- Backend API: `http://127.0.0.1:5001`
- Frontend GUI: `http://127.0.0.1:5174`
- Box API: `http://127.0.0.1:8000`
- Setup UI: `http://127.0.0.1:9000/setup`
- GUI: `http://127.0.0.1:5174`
## API-URL fuer die GUI
Default ist `http://localhost:8000`. Override:
Default ist `http://<HOST-IP>:5001` (aus `hostname -I`). Override:
```
VITE_BOX_API_URL=http://127.0.0.1:8000 npm run dev
KLANGKISTE_BACKEND_URL=http://<server-ip>:5001 ./dev.sh
VITE_BACKEND_URL=http://<server-ip>:5001 npm run dev
```
## Logs ansehen
- Server-Logs: Terminal mit `python3 server/main.py`
- Backend-Logs: Terminal mit `cd gui/backend && npm run dev`
- Box-Logs: Terminal mit `python3 box/main.py run`
- GUI-Logs: Browser-Konsole
@@ -52,7 +59,7 @@ VITE_BOX_API_URL=http://127.0.0.1:8000 npm run dev
-`./dev.sh` gestartet
- ✅ Box-CLI Prompt sichtbar
- ✅ GUI im Browser erreichbar
-`curl http://127.0.0.1:8000/status` liefert JSON
-`curl http://127.0.0.1:5001/api/boxes` liefert JSON
## Troubleshooting
- Port belegt:
@@ -60,4 +67,4 @@ VITE_BOX_API_URL=http://127.0.0.1:8000 npm run dev
- CORS-Fehler:
- API muss laufen und erreichbar sein.
- GUI zeigt "Failed to fetch":
- `VITE_BOX_API_URL` pruefen.
- `VITE_BACKEND_URL` pruefen.
+27 -26
View File
@@ -1,56 +1,57 @@
# GUI Control Panel
## Zweck
Nutzung des GUI Control Panels zur Steuerung und Beobachtung der virtuellen Box.
Nutzung des Frontend Control Panels zur Steuerung und Beobachtung der Boxen ueber das Backend.
## Voraussetzungen
- Box laeuft auf `http://127.0.0.1:8000`
- GUI gestartet (`npm run dev` oder `./dev.sh`)
- Bei gepaarter Box: `VITE_BOX_API_TOKEN` gesetzt
- Backend laeuft auf `http://127.0.0.1:5001`
- Frontend gestartet (`cd gui/frontend && npm run dev` oder `./dev.sh`)
- Box laeuft und meldet sich per Announce beim Backend
## Schritt-fuer-Schritt
1) GUI oeffnen:
```
http://127.0.0.1:5174
```
2) Buttons klicken, Status beobachten.
2) In "Neue Boxen" die Box auswaehlen und "Pairen" klicken.
3) In "Gepairte Boxen" eine Box anklicken.
4) Status und Commands nutzen.
## Controls (im GUI vorhanden)
- Play / Pause
- Next
- Prev
- Vol +
- Vol -
- NFC UID_1 ON
- NFC UID_1 OFF
- Refresh Status
- Pairen (Button in "Neue Boxen")
- Statusanzeige (automatisch)
- Play/Pause, Next, Prev, Vol +/-, Stop
- NFC on/off (UID eingeben)
- Unpair (Button in "Gepairte Boxen")
- Medienkatalog (Explorer-Ansicht, nur Lesen)
- Neuer Tag erkannt (Panel) mit ID-Zuweisung und Zuordnung
- Tags werden nur nach NFC-Erkennung erstellt und zugeordnet.
## Controls (nur API)
## Controls (nur Backend/API)
- WiFi add/reset
- Spotify set/clear
Beispiel via API:
Beispiel via Backend-API (weitergeleitet an die Box):
```
## Auth-Token fuer GUI
- Nach Pairing: Token ueber Server-API oder Server-GUI ermitteln.\n- GUI mit Token starten:\n```\nVITE_BOX_API_TOKEN=<api_token> npm run dev\n```
curl -X POST http://127.0.0.1:8000/command \
curl -X POST http://127.0.0.1:5001/api/boxes/<box_id>/command \
-H "Content-Type: application/json" \
-d '{"command":"wifi_add_profile","payload":{"ssid":"HomeWiFi","password":"secret","priority":10}}'
```
## Erwartete Ergebnisse
- Nach jedem Klick wird der Status innerhalb von 1s aktualisiert.
- `last_error` wird angezeigt, wenn gesetzt.
- Fehler werden im GUI angezeigt.
## Checkliste
- ✅ GUI laedt und zeigt API-URL
-Status aktualisiert sich automatisch
-Buttons aendern `/status`
- ✅ GUI laedt und zeigt Backend-URL
-Neue Boxen erscheinen unter "Neue Boxen"
-Pairing verschiebt die Box in die gepaarte Liste
- ✅ Buttons aendern den `/status`
## Troubleshooting
- GUI zeigt "Failed to fetch":
- `VITE_BOX_API_URL` pruefen.
- Box API muss laufen.
- Backend erreichbar? `http://127.0.0.1:5001/api/boxes`
- Browser-Konsole pruefen.
- Buttons ohne Wirkung:
- API-Command-Namen in `docs/api.md` pruefen.
- Box gepairt?
- Backend-Logs pruefen.
+3 -2
View File
@@ -5,7 +5,8 @@ Tests fuer NFC-Playback, Rekursion, Resume und Buttons.
## Voraussetzungen
- Box laeuft: `python3 box/main.py run`
- Medien unter `box/data/media/`
- Medienkatalog unter `gui/backend/media/`
- Box spielt nur Medien, die ueber Tags zugeordnet wurden.
## Schritt-fuer-Schritt
### NFC-Simulation
@@ -57,6 +58,6 @@ Erwartung: UID_1 resumed.
## Troubleshooting
- Kein Playback:
- Tags in `box/data/box.json` pruefen.
- Dateien in `box/data/media` pruefen.
- Medienordner im Backend pruefen (`gui/backend/media`).
- Duration = 0:
- Unbekannte Dateinamen -> Hash-Dauer, nicht 0.