# Erste Pi-Softwareversion Diese Version implementiert ein Livebild des vorhandenen Camera Module 3 NoIR über Picamera2, eine lokale WebUI, Moduswahl mit Speicherung und eine **Simulation** des Effektablaufs. Sie steuert noch keine GPIOs, Motoren, Servos, Lampen oder Lautsprecher. Eine lokale SQLite-Datenbank speichert Testereignisse und Profilkennungen. Lokale Personenerkennung mit Linienauslösung ist implementiert, muss aber am Pi installiert und kalibriert werden. Bei automatischer Auslösung wird ein Bild des grünen Bereichs lokal gespeichert. Profilzuordnung per Kamera, Clips und zusätzliche frei zeichnbare Masken sind noch nicht umgesetzt. Die 30-Tage-Löschung ist für künftige Auto-Profile vorbereitet. Daher vorerst nur im privaten Testbereich verwenden; die Kamera nicht auf öffentliche Flächen richten. ## Auf dem Raspberry Pi 5 vorbereiten Die Kamera mit passendem Kabel anschließen und mit `rpicam-hello --list-cameras` prüfen. Danach im Projektordner: ```bash sudo apt update sudo apt install python3-picamera2 python3-venv python3 -m venv --system-site-packages .venv .venv/bin/python -m pip install -r requirements.txt ``` Picamera2 wird über die Raspberry-Pi-Pakete installiert; die virtuelle Umgebung kann dieses Systempaket durch `--system-site-packages` verwenden. Der Server bindet nur an `127.0.0.1` auf dem Pi. So ist das Livebild nicht direkt im WLAN sichtbar. ### WebUI beim Hochfahren starten Das versionierte Uploadskript richtet den systemd-Autostart jetzt bei jedem Update mit `--apply` ein und prüft den gestarteten Webdienst. Anleitung, Rückfall und Datensicherung stehen in [UPLOAD.md](UPLOAD.md). Der Updateablauf verwendet einen einzigen sudo-Aufruf für Umschaltung und möglichen Rückfall; das Passwort wird nicht gespeichert. Python-Prüfungen laufen als Pi-Benutzer. Der Dienst nutzt `current/.venv`, startet die WebUI beim Hochfahren und verweist für alle Laufzeitdaten auf den gemeinsamen Basisordner `data/`. Mit `--web-host 0.0.0.0` beim Upload wird direkter Heimnetzzugriff aktiviert; ohne Angabe gilt die gespeicherte Wahl, anfänglich Loopback. Auf dem Pi prüfen: ```bash systemctl status halloween-grab.service systemctl is-enabled halloween-grab.service ``` Der einzelne Installer bleibt für manuelle Einrichtung verfügbar: `bash tools/install_pi_service.sh --project-dir /home/BENUTZER/halloween --apply`. Er prüft keinen vollständigen Versionsrückfall; Updates deshalb vom Laptop über das Uploadskript durchführen. Autostart ist am echten Pi noch zu prüfen. Zum Deaktivieren: `sudo systemctl disable --now halloween-grab.service`. Bei Startproblemen: `sudo journalctl -u halloween-grab.service -n 80 --no-pager`. Ein Browserfenster auf dem Laptop öffnet sich dadurch nicht automatisch. ## Vom Laptop aus ansehen Mit dem geprüften Pi-Benutzer und Hostnamen ein SSH-Terminal offen lassen: ```bash ssh -L 8000:127.0.0.1:8000 BENUTZER@HOST ``` Dann auf dem Laptop `http://127.0.0.1:8000` öffnen. Ein SSH-Passwort reicht; ein Schlüssel ist nicht nötig. Ist Port 8000 auf dem Laptop belegt, links vom ersten Doppelpunkt einen anderen freien Port wählen; rechts bleibt der Pi-Port 8000, solange `run.py` dort mit dem Standardport läuft. ### Direkt im Heimnetz ansehen Auf Nutzerwunsch ist für den aktuellen Test auch direkter Zugriff im Heimnetz vorgesehen. Dafür auf dem Pi den laufenden Server mit `Strg+C` beenden und im Ordner `~/halloween` starten: ```bash .venv/bin/python -m uvicorn halloween.web:create_app --factory --host 0.0.0.0 --port 8000 ``` Auf dem Laptop anschließend `http://raspi5wlan.local:8000` öffnen; kein SSH-Tunnel nötig. `0.0.0.0` ist die Bind-Adresse, keine Browseradresse. Die WebUI hat noch keinen Login: Geräte im erreichbaren Heimnetz können Kamera und Bedienoberfläche nutzen. Eine öffentliche Internetfreigabe ist damit nicht beauftragt. Direkter Browserzugriff im Heimnetz ist noch nicht bestätigt. `run.py` bleibt bei Loopback; der neue systemd-Dienst unterstützt die beim Upload gewählte Bind-Adresse. ## Ohne Kamera testen Auf einem Rechner mit den Paketen aus `requirements.txt`: ```bash python3 run.py --demo ``` Die Bildfläche trägt deutlich „DEMO – KEINE ECHTE KAMERA“. Über „Bereich frei (Test)“ und danach „Testauslösung“ lässt sich die Zustandsfolge ohne Aktoren durchspielen. „Stopp“ sperrt weitere Auslösungen bis „Zurücksetzen“ und erneuter Freigabe des Bereichs. Der Modus „voller Schreck“ ist nur bei noch nicht vorhandenen Einstellungen der Standard. Ein WebUI-Wechsel wird unter `data/settings.json` gespeichert und bleibt bei normalem Neustart erhalten. Das Uploadskript überträgt diesen Laufzeitordner nicht. ## Ereignisdatenbank und Profile Beim Start wird `data/events.sqlite3` angelegt. Erfolgreiche manuelle Testauslösungen werden mit Zeitpunkt und Modus gespeichert und in der WebUI aufgelistet. Profilkennungen lassen sich anlegen, Ereignissen zum Testen zuordnen und wieder löschen. Beim Löschen eines Profils bleibt das Ereignis ohne Zuordnung erhalten. Die Daten bleiben bei einem Neustart und bei weiteren Uploads bestehen, weil das Uploadskript `data/` auslässt. Der Nutzer wünscht später automatische Wiedererkennung per Kamera. Diese Version erstellt noch keine Profile aus Kamerabildern. Gesichtsmerkmale und Clips werden nicht aufgenommen; Auslösebilder liegen als separate lokale JPEGs mit einem Verweis in der Ereignisdatenbank. Für künftig automatisch erstellte Profile sind Merkmalsvektoren und eine 30-Tage-Frist ab letzter Sichtung vorbereitet. Beim Start, stündlich und beim Lesen der Ereignisse/Profile werden abgelaufene Auto-Profile mitsamt Merkmalsvektoren entfernt. Manuelle Profile bleiben bis zur manuellen Löschung bestehen; Ereignisse bleiben ohne Profilzuordnung erhalten. Eine echte Zuordnung braucht noch Kameratests und eine Prüfung von Fehlzuordnungen. ## Lokal prüfen Für die Webtests zusätzlich `httpx` installieren: ```bash .venv/bin/python -m pip install -r requirements-dev.txt .venv/bin/python -m unittest discover -s tests -v ``` Der Host-Test prüft Demo-Bild und Webendpunkte. Kamera, Nachtbild, WLAN, SSH-Tunnel und GPIOs müssen am echten Pi bzw. Aufstellort geprüft werden. Technische Grundlagen: [Picamera2-Handbuch](https://datasheets.raspberrypi.com/camera/picamera2-manual.pdf), [FastAPI-StreamingResponse](https://fastapi.tiangolo.com/advanced/stream-data/). ## Bilder zu automatischen Auslösungen Bei jeder akzeptierten automatischen Auslösung (Linienüberquerung oder Bewegungs-Test) wird der **grüne Auslösebereich** des tatsächlich ausgewerteten Kamerabildes als JPEG unter `data/event-images/` gespeichert. Außerhalb des gewählten Rechtecks wird nichts gespeichert. Der Bereich muss vor Aktivierung auf den vorgesehenen privaten Testbereich beschränkt sein. Keine zusätzliche Ton-/Clipaufnahme, keine Gesichtsmerkmale und keine Profilautomatik. In **Gespeicherte Ereignisse** erscheinen eine kleine Vorschau und **„Bild ansehen“** (öffnet das Bild in einem eigenen Tab). Die Liste aktualisiert sich alle 15 Sekunden; **„Ereignisse aktualisieren“** lädt sie sofort neu. Bisherige Ereignisse und manuelle Testauslösungen haben kein gespeichertes Bild. Auf ausdrückliche Nutzerwahl bleiben Bilder **bis zur manuellen Löschung** erhalten. **„Bild löschen“** verlangt eine Bestätigung und entfernt das JPEG im aktiven Datenbestand. Ereignis, Zeitpunkt und Profilzuordnung bleiben erhalten. Es gibt keine automatische Alterslöschung dieser Bilder. Speicherbelegung am Pi beobachten; die vorhandenen Upload-Sicherungen können ältere Bilder enthalten und werden durch diesen Knopf nicht verändert. JPEGs haben Dateirechte 0600, der Bildordner 0700. Abruf nur über die Ereignis-ID, keine statische Freigabe des gesamten `data/`-Ordners. `GET /api/events` liefert `image_url` oder `null`; `GET /api/events/{id}/image` liefert JPEG mit `no-store`, `DELETE` benötigt den vorhandenen UI-Header. Diese Schranke ersetzt keinen Login: Wie das Livebild sind Bilder im erreichbaren Heimnetz zugänglich. Keine öffentliche Freigabe. Upload und Versionswechsel bewahren `data/` einschließlich Bilder. Schreib-/Datenbankfehler werden angezeigt und sperren die Automatik bis zum bewussten Rücksetzen. Teilweise fehlgeschlagene Speichervorgänge räumen temporäre Bilder auf. Lokale Tests prüfen beschnittene Bilder, Trigger-Frame, Neustart, Alt-Datenbankmigration, Abruf/Löschen und Fehlerfälle mit synthetischen Bildern. Das Speichern und Anzeigen nach echter Pi-Auslösung ist noch zu prüfen. ## Personenerkennung und Linienauslösung Nach einem versionierten Update im aktiven Versionsordner auf dem Pi installieren: ```bash cd ~/halloween/current sudo apt update sudo apt install python3-opencv python3-numpy .venv/bin/python -c "import cv2, numpy; print(cv2.__version__, cv2.__file__); print(numpy.__version__)" HALLOWEEN_STATE_DIR=/home/marcinator_2/halloween/data \ .venv/bin/python tools/install_detection_model.py ``` Das Skript lädt ausschließlich das unquantisierte Modell `object_detection_nanodet_2022nov.onnx` des offiziellen OpenCV Zoo. Version, URL, Größe und SHA-256 stehen in `halloween/nanodet-model.json`. Das Modell liegt unter `data/models/`; ein bestehendes korrektes Modell wird nicht erneut geladen. Download erfolgt nur auf diesen ausdrücklichen Aufruf, HTTPS-Zertifikatsprüfung bleibt aktiv. Der Server lädt nichts aus dem Internet. Bei abweichendem `HALLOWEEN_STATE_DIR` diesen beim Installer ebenfalls setzen oder `--state-dir` angeben. Modellgewichte bleiben unversioniert und werden nicht vom Upload überschrieben. Auf dem Pi das fertige Systempaket verwenden; Picamera2 bleibt ebenfalls das Raspberry-Pi-Systempaket. OpenCV muss mindestens 4.10 sein; die tatsächliche installierte Version und Inferenz am Pi prüfen. Für andere Entwicklungsrechner kann `requirements-detection.txt` genutzt werden: Es erlaubt ausschließlich fertige Wheels und bricht ohne passende Pakete ab. Ein vorheriger pip-Installationsversuch kann lokale Pakete hinterlassen, die Systempakete überdecken; bei Importfehlern die ausgegebenen Pfade prüfen. Server anschließend wie oben starten. In der Liveansicht: 1. Orange Linienendpunkte und die zwei grünen Bereichsecken ziehen. Die Linie muss vollständig innerhalb des Rechtecks liegen. Außerhalb des privaten Testbereichs darf die Auslösung nicht eingerichtet werden. 2. Mit „Richtung umkehren“ den Pfeil zum Grab ausrichten. 3. „Automatisch auslösen“ auswählen und „Linie und Bereich speichern“ drücken. 4. Mindestens zwei Sekunden den gesamten Bereich freihalten. Danach auf der Ankunftsseite beginnen und über die Linie zum Grab gehen. Zunächst bleibt die automatische Auslösung aus. Gespeicherte Konfiguration und Aktivierung bleiben nach normalem Neustart erhalten, aber die Bereichsfreigabe und Tracking-IDs werden immer neu aufgebaut. Bei ungültiger Konfiguration bleibt die Automatik aus; der Fehler wird angezeigt. Es werden nur Personen ausgewertet (Startschwelle 0,6). Mindestens drei aufeinanderfolgende Erkennungen bestätigen einen Track. Der Fußpunkt ist die Mitte der unteren Rahmenkante. Er muss von der Ankunftsseite über das endliche Liniensegment auf die Grabseite wechseln, jeweils mindestens 3 % der Bildhöhe von der Linie entfernt. Kurz auftauchende Personen hinter der Linie, Rückwege, Bewegung entlang der Linie und Überquerungen außerhalb des Segments lösen nichts aus. Verdeckung oder zu schnelles Überqueren kann zur Nichterkennung führen; die Startwerte sind praktisch zu kalibrieren. Eine Gruppe erhält einen Effekt: Nach Auslösung sind zehn Sekunden Sperrzeit und mindestens zwei Sekunden freier Auslösebereich nötig. Auch unbestätigte Personenrahmen im Rechteck verhindern die Freigabe. Überquerungen während Sperre werden verworfen. Start, Moduswechsel, Rücksetzen und Änderungen der Konfiguration verlangen erneut einen freien Bereich. Stopp bleibt wirksam; ein manueller Testbutton umgeht keine Fehlersperre. Kamera-/Modellfehler und mehr als zwei Sekunden ohne gültige Auswertung sperren die aktivierte Automatik und stoppen den simulierten Ablauf. Nach Beheben des Fehlers „Nach Stopp zurücksetzen“ verwenden und Bereich freihalten. Modellprobleme bei deaktivierter Automatik verhindern keine manuellen Tests. Der Demo-Livefeed und manuelle Tests brauchen weder OpenCV noch Modell; der Bewegungs-Test benötigt auch im Demo-Modus OpenCV. Synthetische Bilder sind kein Test der echten Personenerkennung. Die Auswertung arbeitet im Hintergrund mit dem jeweils neuesten Bild, Ziel fünf Auswertungen/s. Die UI zeigt die gemessene Verarbeitungsrate. Bei Erkennungsergebnissen zeigt sie das zugehörige Bild statt des unabhängigen MJPEG-Bildes, damit Rahmen und Bild zusammenpassen. Nach zwei Sekunden sind Ergebnisse veraltet und die Rahmen verschwinden. Ohne Erkennungsbild bleibt der normale MJPEG-Stream verfügbar. `/api/detection` liefert Frame-Nummer, JPEG als Base64, normierte Personenrahmen, flüchtige Tracking-IDs und Status; `GET/POST /api/detection/config` liest/speichert Aktivierung, Linie, Richtung und Rechteck. `POST` benötigt wie andere Schreibaufrufe `X-Halloween-UI: 1`. `/api/status` enthält zusätzlich `detection`. Der Header ersetzt keinen Login. Automatische Auslösungen werden als `person_line_crossing` ohne Profil in der bestehenden Datenbank gespeichert, mit lokalem Bild des grünen Bereichs aus dem auslösenden Frame. Tracking-IDs werden nicht gespeichert; Profil-Wiedererkennung und Altersentscheidung fehlen. Aktoren bleiben ausschließlich simuliert. ### Nahbereich testen: Bewegung in Pfeilrichtung In der WebUI unter **Automatische Auslösung → Erkennung wählen** den Modus **„Test: Bewegung in Pfeilrichtung“** auswählen, „Automatisch auslösen“ anhaken und „Linie und Bereich speichern“ drücken. Der Modus wird lokal in `data/detection.json` gespeichert. Bisherige Einstellungen ohne Methodenfeld werden als Personenerkennung übernommen; diese bleibt der Standard. Dieser Test benötigt OpenCV und NumPy aus den oben beschriebenen Pi-Systempaketen, aber kein NanoDet-Modell. Wenn OpenCV fehlt, auf dem Pi ausführen: ```bash sudo apt install python3-opencv python3-numpy sudo systemctl restart halloween-grab.service ``` Zuerst die Kamera fest abstellen und das Bild im grünen Bereich mindestens zwei Sekunden ruhig halten. Dann eine Hand, den Kopf oder einen Gegenstand sichtbar in Pfeilrichtung bewegen. Eine Person muss weder vollständig sichtbar sein noch wird eine Linienüberquerung verlangt: Die Linie legt in diesem Modus nur den Pfeil fest. Für Bewegung nach links/rechts die Linie entsprechend senkrecht stellen; mit „Richtung umkehren“ die Pfeilrichtung wechseln. Es müssen zwei aufeinanderfolgende Auswertungen gerichtete Bildbewegung im gewählten Bereich bestätigen. Der Test wertet auch kleine, langsame Änderungen im Nahbereich aus. Unter der Statuszeile stehen der geänderte Bildanteil, die Richtungsbewertung und „Bestätigung 0/2“, „1/2“ oder „2/2“. So lassen sich zu kleine Änderungen von fehlender Richtung unterscheiden. Eine Auslösung setzt außerdem die vorherige automatische Freigabe voraus. Die Betriebsanzeige nutzt bei eingeschalteter Automatik deren Freigabe („Bereit (Automatik)“ oder „Ruhiges Bild abwarten (Automatik)“). Der Knopf „Bereich frei (manueller Test)“ ist dafür nicht erforderlich und hebt die automatische Freigabeprüfung nicht auf. Die manuellen Testknöpfe bleiben für separate Versuche verfügbar. Sehr langsame, zu schnelle, winzige oder strukturarme Bewegung kann übersehen werden. Nach Auslösung gelten zehn Sekunden Sperrzeit und erneut mindestens zwei Sekunden ruhiges Bild. Ein ruhiges Bild beweist **keinen menschenfreien Bereich**. Stopp, Fehler-Watchdog, bewusstes Rücksetzen und erneute Freigabe nach Start/Konfigurationswechsel bleiben wirksam. Bei bereits gesetzter Fehlersperre nach Auswahl und Speichern bewusst „Nach Stopp zurücksetzen“ drücken. Dies ist ein **Bewegungs-Test für die Simulation**, keine Personenerkennung für den späteren Gartenbetrieb. Auch Kamera-/Hintergrundbewegung kann auslösen. Lichtwechsel werden nicht als Richtung behandelt, können aber die Ruhefreigabe verzögern. Bei akzeptiertem Trigger wird ein Bild des grünen Bereichs gespeichert; Besuchermerkmale werden nicht gespeichert. Testereignisse erscheinen separat als „Bewegungs-Test“ (`motion_direction_test`). `/api/detection` liefert zusätzlich flüchtige Bewegungswerte unter `motion`; Config/Status enthalten `method` (`person_line` oder `motion_test`). Lokal mit synthetischen Bildern getestet: Richtung/Umkehr/gedrehte Linie, Gegenrichtung, seitliche Bewegung, Helligkeitswechsel, Bereichsgrenzen, Bestätigung, Bildlücken, Sperrzeit und Stopp. Browser-Demo bestätigt Auswahl, Speichern und Wiederherstellung nach Neuladen über die sichtbare UI-Struktur. Echte Pi-Kamera und Nahbereich noch nicht geprüft. ### Abnahme am echten Pi (noch offen) - Angezeigte Rate und Reaktionsverzögerung prüfen; Livebild und Stopp müssen bedienbar bleiben. Zehn Annäherungen und zehn Rückwege ausprobieren. - Gruppe, Verdeckung, Stehenbleiben, Linie entlanggehen, Neustart mit Person im Bereich sowie Kamera-/Erkennungsausfall und bewusstes Rücksetzen testen. - Danach Kostüme, tatsächliche Dunkelheit und IR-Beleuchtung am Aufstellort testen. Nachtbetrieb und Zuverlässigkeit sind noch nicht bestätigt. Modellgrundlage: [OpenCV Zoo NanoDet](https://github.com/opencv/opencv_zoo/tree/47534e27c9851bb1128ccc0102f1145e27f23f98/models/object_detection_nanodet). Optionaler echter Modell-Smoke-Test auf einem Rechner mit OpenCV und Modell: ```bash HALLOWEEN_TEST_MODEL="$PWD/data/models/object_detection_nanodet_2022nov.onnx" .venv/bin/python -m unittest discover -s tests -v ``` Ohne diese Variable wird nur der optionale Modell-Smoke-Test übersprungen; die Linien-/API-/Installer-Tests benötigen weder Modell noch OpenCV.