Nice Work
This commit is contained in:
+5
-7
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user