No description
  • Java 36.8%
  • TypeScript 30.9%
  • C++ 11.1%
  • Python 8.9%
  • SCSS 6.4%
  • Other 5.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-31 18:17:23 +01:00
.cursor/skills/deploy-personalization-pi full rweork of nfc rallye code 2026-10-05 12:54:41 +02:00
backend feat: Ziehung 2026-10-31 18:17:23 +01:00
config feat: robustness improved, usability, beeper 2026-10-19 21:35:58 +02:00
deploy feat: ux improvements 2026-10-28 10:42:20 +01:00
docs ziehung nur mit mail, email vebresserungen 2026-10-31 12:22:25 +01:00
esp-code feat: sounds, personalisation 2026-10-28 00:38:13 +01:00
frontend feat: Ziehung 2026-10-31 18:17:23 +01:00
personalisierungsterminal feat: sounds, personalisation 2026-10-28 00:38:13 +01:00
preview feat: robustness improved, usability, beeper 2026-10-19 21:35:58 +02:00
.dockerignore full rweork of nfc rallye code 2026-10-05 12:54:41 +02:00
.env.example visualization improvements 2026-10-20 16:40:54 +02:00
.gitignore full rweork of nfc rallye code 2026-10-05 12:54:41 +02:00
README.md feat: ux improvements 2026-10-28 10:42:20 +01:00

NFC Scan Rallye LinuxTag Villach 2026

Lokale NFC-Scan-Rallye von node-K: Hackspace Klagenfurt für den LinuxTag Villach 2026. Besucher tragen NFC-Anhänger, scannen an 10–15 Ständen (ESP32 + HW-147C Si512), die Stationen mesh’en per painlessMesh, ein Gateway-ESP am Personalisierungsterminal reicht Events per Serial an den Pi, der per REST an ein Spring-Boot-Backend mit PostgreSQL spricht. Live-Visualisierung (Three.js) auf dem 34"-Widescreen, Personalisierung am 15"-Touch.

Das System ist lokal-first: kein Internet nötig. Node→Stand-Zuordnung liegt im Backend, nicht in der Firmware.

Schnellstart (dieser Rechner)

cd deploy/backend
docker compose up --build

Unter Windows legt Docker Desktop network_mode: host nicht auf die Ports dieses PCs. Dort die zweite Datei mitgeben:

cd deploy/backend
docker compose -f docker-compose.yml -f docker-compose.windows.yml up -d --build

Danach im Browser http://localhost:43145/. Postgres 5432, Backend 43145.

Danach:

Oberfläche URL
Live-Visualisierung http://127.0.0.1:43145/
Stände (Name & Ort) http://127.0.0.1:43145/admin/stations
Scanner-Geräte (Node → Stand) http://127.0.0.1:43145/admin/nodes
Admin / Leitstand http://127.0.0.1:43145/admin/
Demo (Neustart) http://127.0.0.1:43145/admin/#demo
Personalisierungs-Kiosk http://127.0.0.1:43145/kiosk/
API-Health http://127.0.0.1:43145/actuator/health

Standard-Tokens (nur LAN, vor dem Event ändern):

  • Admin: linuxtag-admin (Header X-Admin-Token oder Feld im Admin-UI)
  • Terminal: linuxtag-terminal (Header X-Terminal-Token)

Scans kommen von den Stationen und vom Personalisierungsterminal. In der Visualisierung: Taste D (Demo-Overlay), R (Demo neu starten, nur bei RALLYE_DEMO_MODE=true). Leitstand: Button Demo neu starten. Ohne Flag werden keine Produktivdaten gelöscht.

Zusammenfassung per Mail

Am Eventende im Leitstand http://127.0.0.1:43145/admin/mail. Empfänger sind personalisierte Tags mit E-Mail und Zustimmung zur Zusammenfassung, eine Mail pro Anhänger: Anzahl Stände, Verlauf, längster Aufenthalt (Zeit bis zum nächsten gezählten Stand), Link auf node-k.at. Schon versendete Adressen bleiben aus, außer „erneut senden“.

Vorlage backend/src/main/resources/mail/summary.html im Browser öffnen und bearbeiten. Die Beispieltexte (Alex, Lötecke) ersetzt der Versand. Eine Datei mail/summary.html im Overlay gewinnt ohne Neubau.

SMTP steht in .env.example. Nach .env im Repo-Root kopieren. Der Prozess liest sie beim Start, Compose lädt sie in den Container. MAIL_ENABLED=true erst mit Host und Absender.

Hardware / Verdrahtung

Reader überall: HW-147C Si512 (kein PN532) per I2C am ESP32. Am Kiosk: ein ESP env:gateway (Mesh-Root); der Pi spricht REST und lädt /kiosk/ live.

Gerät PlatformIO-Env Anbindung Doku
Stand-Scanner (viele) station I2C + Mesh esp-code/WIRING.md
Personalisierungsterminal (= Gateway, genau eins) gateway I2C + Mesh-Root; Pi REST/nfc-bridge personalisierungsterminal/WIRING.md · personalisierungsterminal/FULLPAGEOS.md · esp-code/platformio.ini

Produktion braucht nur station + gateway. Env terminal ist optionaler Reader-Bring-up ohne Mesh. Flash Gateway: pio run -e gateway (node_id fest node-terminal). Details: personalisierungsterminal/WIRING.md. Überblick: docs/01-wiring.md.

Wo die Zuordnung liegt (verbindlich)

Es gibt zwei Mappings, beide nur im Backend (Postgres), nicht in der Firmware:

Was Tabelle Oberfläche
Station-ID → Name, Website, Farbe, Beschreibung, mapX/Y/Z station http://127.0.0.1:43145/admin/stations
ESP node_id (Station: Chip-MAC, Gateway: node-terminal) → Stand node_status.station_id http://127.0.0.1:43145/admin/nodes

Seed-Daten stehen in Flyway V2__seed.sql und config/stations.json. Nach dem Start gewinnt die Datenbank. Die 3D-Viz liest Namen und Positionen aus GET /api/v1/config/stations und /api/v1/state/snapshot.

Mapping-Workflow

Stände (Name & Ort) – zuerst, oft schon vor dem Event:

  1. http://127.0.0.1:43145/admin/stations öffnen (Token linuxtag-admin).
  2. Stand anlegen: ID (z.B. stand-loetecke), Anzeigename, Website-URL (Newsletter-CTA), Farbe, Beschreibung.
  3. Lage setzen: Zahlen mapX / mapY / mapZ oder Marker auf dem 2D-Lageplan klicken/ziehen. Speichern schreibt in station.
  4. Unnötige Stände deaktivieren (bleiben in der DB) oder löschen.

Scanner-Geräte (Node → Stand) – am Eventmorgen, wenn die Terminals stehen:

  1. Firmware überall gleich flashen. Stationen melden sich mit ihrer Chip-MAC, das Gateway als node-terminal. station_id in der Firmware ist optional und nur ein Hinweis.
  2. http://127.0.0.1:43145/admin/nodes öffnen.
  3. Node wählen, Stand wählen, Zuordnung speichern. identify lässt die LED blinken, damit du das Gerät in der Halle findest.
  4. Ab jetzt zählen Scans dieses Nodes für diesen Stand (Cooldown/Duplicate entscheidet das Backend).

set_station per Mesh bleibt als Override in der Firmware, die Backend-Tabelle gewinnt bei der Zählung.

Der Leitstand http://127.0.0.1:43145/admin/ verlinkt nur noch diese zwei Oberflächen (keine alten „(alt)“-Registerkarten). Der Hallengrundriss kommt aus config/map.json (extrudierte Polygone). Optional STL: Admin → Halle / 3D-Modell oder Datei config/venue.stl. Details: docs/06-visualization.md.

Ohne Docker (Dev)

PostgreSQL 16 lokal, dann:

cd frontend && npm install && npm run build
cd ../backend && ./mvnw -DskipTests package
SERVER_PORT=43145 java -jar target/rallye-1.0.0.jar

SPA lokal ohne Docker: cd frontend && npm start (Proxy → :43145). / = Live-Szene, /admin = Leitstand, /kiosk = Personalisierung.

Tests (Testcontainers PostgreSQL, Docker nötig):

cd backend && ./mvnw test

Monorepo

esp-code/                  PlatformIO ESP32 (station + gateway); Verdrahtung: esp-code/WIRING.md
backend/                   Spring Boot 4.1 / Java 25 / Maven / Flyway / Postgres
frontend/                  Angular 22: Live-Szene `/`, Leitstand `/admin`, Kiosk `/kiosk`
personalisierungsterminal/ nfc-bridge (REST-Ingest + Serial + Setup :8083)
config/                    stations.json, map.json, game.json (optional venue.stl)
deploy/backend/            docker-compose, Dockerfile, rallye-stack.service
deploy/frontend/           Kiosk-Skript der 34"-Visualisierung
deploy/personalisierungsterminal/  systemd, udev, polkit, Kiosk-Skript
docs/                      Verdrahtung, Protokoll, API, Setup, Scanner-Howto, Visualisierung

Lücken gegenüber der PDF-Spezifikation

  • OTA-over-Mesh-Empfang ist in station/gateway aktiv (Firmware 1.1.0+); Push noch nicht verdrahtet, vor Event nur nach Feldtest.
  • WS2812/OLED-Feedback ist dokumentiert, Referenzfirmware nutzt die Onboard-LED.
  • painlessMesh-Feldtest und 8-h-Dauerlauf müssen vor Ort nachgeholt werden.
  • Der öffentliche Mirror linuxtag26.node-k.at ist bewusst out of scope; Export aggregate.json ist anonym-aggregiert vorbereitet.
  • Pi-REST-Ingest + Kiosk Serial/MESH-Pfad End-to-End mit Hardware vor Ort verifizieren.

Ausführliche Hardware- und Protokolldokumente: docs/ (Index: docs/01-wiring.md). Stationen: esp-code/WIRING.md. Personalisierungs-Terminal: personalisierungsterminal/WIRING.md / personalisierungsterminal/README.md.