Bridge für Steinel CAM Leuchten auf ONVIF (RTSP), 2-Way Audio & Home Assistant

Die Bridge ist eine hochperformanter, 100 % autarker Go-Daemon der in Docker (Compose) oder als HomeAssistant App betrieben
werden kann.
Sie verwandelt Steinel CAM Außenleuchten (L 625 CAM SC, L 620 CAM, XLED CAM 1/2, Spot CAM) in standardkonforme
ONVIF Profile S/T/G Kamera mit RTSP-Streaming, 2-Wege-Audio (Gegensprechen), lokalem MicroSD-Speicherabruf und
vollständiger MQTT Home Assistant Auto-Discovery.
Damit ist eine nahtlosen Integration in Home Assistant, Synology Surveillance Station, Scrypted, Frigate und weitere
möglich.
Mit Hilfe von Scrypted ist dann z.B. eine Integration in Apple HomeKit Secure Video (HKSV) möglich.
Da ich nicht alle Modelle selbst besitze kann ich nicht alles selbst direkt vertesten. Über Rückmeldungen würde ich mich freuen.
[!WARNING]
Trotz sorgfältiger Entwicklung und Verwendung der Schnittstellen der offiziellen (Nabto) SDKs und APIs die von der Kamera
bereitgestellt werden kann nicht garantiert werden das es zu keinen Komplikationen mit der Hardware der Kamera/Leuchte kommt.
Das Projekt oder meine Personen übernehmen keine Gewährleistung oder Sachmängelhaftung für eventuell eintretende Schäden
an der Hardware.
✨ Features & Home Assistant Integration
-
Standardisierter ONVIF Profile S, T & G Server:
- Profile G (Edge Storage): Bereitstellung standardisierter Search-, Replay- und Recording-Dienste zur Wiedergabe und
Synchronisation von MicroSD-Aufnahmen in NVRs (z. B. Synology Surveillance Station).
- WS-Discovery (UDP 3702): Automatische Erkennung im lokalen Netzwerk.
- Native Live-Snapshots: NVRs und Clients (z. B. Scrypted Prebuffer, Home Assistant) generieren hochauflösende
Live-Standbilder direkt aus dem H.264-Videostream ohne Dummy-Platzhalter.
-
🔊 Volles 2-Way Audio (Gegensprechen) & Natives AAC-Audio:
- Natives AAC-Audio (Standard): Automatisches Realtime-Transcoding des Kamera-Mikrofons (G.711u 8 kHz $\rightarrow$ AAC-LC 16 kHz).
Keine extra Konfiguration für Transcoding des Audiosignals erforderlich.
- RTSP Audio Backchannel: Durchleitung von HomeKit/Scrypted-Sprachdaten direkt an den Lautsprecher der Steinel-Leuchte
(PCMU / G.711u 8000 Hz).
-
🏠 Home Assistant MQTT Auto-Discovery (Strukturierte Gerätesteuerung):
- 🎮 Steuerung:
- Betriebsmodus (
select.mode): Umschalten zwischen Sensor (Automatik), Dauerlicht und Aus.
- Alarmsirene (
siren.siren): Sofortiges Auslösen und Stoppen des akustischen Alarms der Außenleuchte mit
Live-Zustandsrückmeldung (ON / OFF).
- 🎬 Ereignisse & Aufnahmen:
- Letzte SD-Aufnahme (
event.letzte_sd_aufnahme): Übermittlung des neuesten MicroSD-Aufnahmeereignisses mit
Metadaten (Zeitstempel, Dauer, Dateigröße) und direkten URLs für Vorschaubild (thumbnail_url) und MP4-Video (video_url).
- ⚙️ Konfiguration (Einstellungsbereich):
- Dämmerungsschwelle (
number.lux_threshold): Schaltschwelle in Lux (2–1000 lx), ab welcher Umgebungsdunkelheit das Licht bei Bewegung schaltet.
- Hauptlicht Helligkeit (
number.highlight): Maximale Leuchtstärke des Flutlichts (10–100 %).
- Grundlicht Helligkeit (
number.lowlight): Dauerhafte Nachtlicht-Helligkeit (0–50 %).
- Nachlaufzeit (
number.duration): Einschaltdauer des Hauptlichts nach Bewegung (5–900 s).
- PIR-Empfindlichkeit (
number.pir_sensitivity): Reichweite / Sensitivität des Bewegungsmelders (0–100 %).
- Videoauflösung (
select.resolution): Live-Umschaltung der Kameraauflösung (1080p, 720p, 360p).
- 🩺 Diagnose:
- PIR-Status (
binary_sensor.pir_status): Zeigt den Betriebszustand des PIR-Sensors an (running).
-
💡 Hinweise zu Hardware-Grenzen & Bewegungserkennung:
- Kein kontinuierlicher Luxmeter-Sensor (
sensor.lux): Die Steinel-Kamera besitzt keinen digitalen Helligkeitsmesser
(wie eine Wetterstation), sondern einen analogen Photowiderstand (LDR), der lediglich mit der eingestellten Dämmerungsschwelle
abgeglichen wird.
- Kein lokaler Hardware-PIR-Push (
binary_sensor.motion): Die Kamera-Firmware meldet Bewegungsevents ab Werk
ausschließlich über das Cloud-Gateway des Herstellers an die Steinel-Smartphone-App. Auf der lokalen Schnittstelle wird der
1080p-Live-Stream bereitgestellt.
- Bewegungserkennung & Apple HomeKit Secure Video (HKSV): Die Bewegungserkennung wird in Smart-Home-Umgebungen
standardmäßig per Video-Bildanalyse realisiert:
- In Home Assistant: Über Frigate oder MotionEye für präzise KI-Objekterkennung (Personen, Fahrzeuge, Tiere).
- In Scrypted: Über das offizielle Plugin
OpenCV Motion Detector (@scrypted/opencv) für latenzfreie
HomeKit-Mitteilungen und HKSV-Cloud-Aufzeichnungen.
-
Autarkes Single-Binary: Kein Python, kein Node.js und kein separater MediaMTX-Server erforderlich.
- Im Betrieb als HomeAssistant AddOn Image mit minimalsten Abhängigkeiten.
-
24/7 Resilienz & Watchdog: RTP-Silence Watchdog, 30s Cooldown, mDNS-Wakeup.
🐳 Bereitstellung (Home Assistant Add-on & Docker)
Option A: Home Assistant Add-on (Empfohlen für Home Assistant Nutzer)

- Klicken Sie auf das "Open in Home Assistant" Badge oben oder fügen Sie in Home Assistant unter Einstellungen ➔ Add-ons ➔ Add-on Store ➔ Repositories (Drei-Punkte-Menü) folgende URL hinzu:
https://github.com/Afrouper/steinel-cam-bridge
- Wählen Sie "Steinel CAM Bridge" aus und klicken Sie auf Installieren.
- Tragen Sie im Reiter Konfiguration Ihre
camera_ip und den qr_code ein und klicken Sie auf Starten!
Option B: Standalone Docker Compose (Empfohlen für Server / NAS mit Security Hardening)
Eine fertige Vorlage finden Sie unter examples/docker-compose.yml.
Starten mit:
docker compose up -d
Option C: Standalone Docker Run (Gehärtet)
docker run -d \
--name steinel-cam-bridge \
--restart unless-stopped \
--net=host \
--user "1000:1000" \
--security-opt no-new-privileges:true \
--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=64M \
--memory=256m \
--cpus=0.5 \
--pids-limit=100 \
-e CAMERA_IP="IP-ADDESS" \
-e QR_CODE="did=de-xxxxxxx,pid=pr-xxxxx,sct=xxxx,pairPwd=xxxx" \
-e AUDIO_CODEC="aac" \
-e MQTT_BROKER="tcp://<IP-ADDESS>:1883" \
-e MQTT_USER="homeassistant" \
-e MQTT_PASSWORD="secretpassword" \
-v ./data:/data \
ghcr.io/afrouper/steinel-cam-bridge:latest
📱 Einbindung in Home Assistant & Scrypted
1. Home Assistant (MQTT)
Wird kein separater MQTT Broker konfiguriert wird automatisch der in HomeAssistant integrierte
Standard Broker verwendet. In Home Assistant unter
Einstellungen ➔ Geräte & Dienste ➔ MQTT erscheint automatisch das Gerät "Steinel L 625 CAM SC" mit allen Licht-,
Sensor- und Steuerungsentitäten:
2. Scrypted (Home Assistant Add-on oder Standalone)
Egal ob Scrypted als Home Assistant Add-on oder als eigenständige Instanz läuft:
- Im Scrypted ONVIF Plugin auf Add Camera klicken (IP-Adresse des Bridge-Servers, Port
8000).
- Scrypted erkennt automatisch 1080p Video, natives AAC-Mikrofon und Gegensprechanlage.
- Natives Audio: Die Bridge liefert standardmäßig natives AAC-Audio (16 kHz). In Scrypted ist kein manuelles Audio-Transcoding im HomeKit-DEBUG-Reiter erforderlich.
- Bewegungserkennung für HKSV aktivieren:
- In Scrypted unter Plugins das Plugin
OpenCV Motion Detector (@scrypted/opencv) installieren.
- Auf der Steinel-Kamera im Reiter Extensions das Plugin OpenCV Motion Detector aktivieren.
- Im HomeKit Plugin die Kamera aktivieren ➔ Live-Streaming & HKSV-Aufnahmen in Apple Home laufen vollautomatisch!
🗄️ SD-Karten REST API (Ereignisse, Snapshots & Video-Download)
Die Bridge stellt auf Port 8000 eine direkte 1:1 REST-API bereit, um Aufnahmen der internen SD-Karte abzufragen und ohne Umwege per HTTP-Stream herunterzuladen (Zero-Disk I/O).
| Endpunkt |
Methode |
Beschreibung |
/api/sdcard/events |
GET |
Liefert die JSON-Liste aller Video-Ereignisse (Query-Parameter: start, end, page, limit) |
/api/sdcard/events/{id}/thumbnail.jpg |
GET |
Liefert das JPEG-Vorschaubild der Aufnahme direkt aus dem Kameraspeicher |
/api/sdcard/events/{id}/video.mp4 |
GET |
Streamt die vollständige MP4-Aufnahme als Binärstream (inkl. Hardware-Überlastungsschutz) |
[!TIP]
Eingebauter Hardware-Schutz (Concurrency = 1): Um die kleine Embedded-CPU der Steinel-Kamera vor Überlastung zu schützen, erlaubt die Bridge immer nur genau einen aktiven Download gleichzeitig. Parallele Abfragen werden mit HTTP 429 Too Many Requests beantwortet. Bricht ein Client den Download vorzeitig ab, stoppt die Bridge den Kamera-Transfer sofort.
💻 Lokale Entwicklung (macOS & Linux)
Die Bridge kann vollständig nativ auf einem Entwickler-Rechner (macOS / Linux) ohne Docker gebaut, getestet und ausgeführt werden:
1. Nabto SDK vorbereiten
Laden Sie die passende native Nabto Client SDK-Bibliothek (libnabto_client.dylib bzw. .so) einmalig in das lokale .sdk/-Verzeichnis herunter:
./scripts/setup-sdk.sh
2. Lokale Tests ausführen
# macOS:
DYLD_LIBRARY_PATH="$(pwd)/.sdk/lib" go test -v ./...
# Linux:
LD_LIBRARY_PATH="$(pwd)/.sdk/lib" go test -v ./...
3. Natives Binary kompilieren
# macOS:
CGO_LDFLAGS="-L$(pwd)/.sdk/lib -lnabto_client" CGO_CFLAGS="-I$(pwd)/.sdk/include" go build -o steinel-bridge ./cmd/steinel-bridge
# Linux:
CGO_LDFLAGS="-L$(pwd)/.sdk/lib -lnabto_client" CGO_CFLAGS="-I$(pwd)/.sdk/include" go build -o steinel-bridge ./cmd/steinel-bridge
4. Bridge lokal starten
# macOS:
DYLD_LIBRARY_PATH="$(pwd)/.sdk/lib" ./steinel-bridge \
-ip 192.168.1.100 \
-qr "did=de-xxxxxxx,pid=pr-xxxxx,sct=xxxx,pairPwd=xxxx" \
-key ./data/local_client.key \
-debug
# Linux:
LD_LIBRARY_PATH="$(pwd)/.sdk/lib" ./steinel-bridge \
-ip 192.168.1.100 \
-qr "did=de-xxxxxxx,pid=pr-xxxxx,sct=xxxx,pairPwd=xxxx" \
-key ./data/local_client.key \
-debug
⚙️ Konfiguration & Umgebungsvariablen
| Variable / Flag |
CLI-Flag |
Standard |
Beschreibung |
CAMERA_IP |
-ip |
192.168.1.2 |
Lokale IP-Adresse der Steinel-Kamera |
QR_CODE |
-qr |
"" |
QR-Code Payload aus der Steinel App für automatisches Pairing |
KEY_PATH |
-key |
data/client.key |
Speicherpfad für den persistenten ECC-Schlüssel |
RESOLUTION |
-res |
1080p |
Videoauflösung (1080p, 720p, 360p) |
AUDIO_CODEC |
-audio-codec |
aac |
Audio-Codec des RTSP/ONVIF Streams: aac (nativ transkodiert) oder pcmu (Raw Passthrough) |
RTSP_PORT |
-port |
8554 |
Port des integrierten RTSP-Servers |
ONVIF_PORT |
-onvif |
8000 |
Port des integrierten ONVIF HTTP-Servers |
SDCARD_SYNC_INTERVAL |
-sync-interval |
30 |
Intervall in Sekunden für die Hintergrundabfrage neuer MicroSD-Aufnahmen |
MQTT_BROKER |
-mqtt-broker |
"" |
MQTT Broker URL (z. B. tcp://192.168.1.100:1883) |
MQTT_USER |
-mqtt-user |
"" |
MQTT Benutzername |
MQTT_PASSWORD |
-mqtt-pass |
"" |
MQTT Passwort |
MQTT_TOPIC_PREFIX |
-mqtt-topic |
steinel |
MQTT Basis-Topic (Geräte-ID wird automatisch angehängt) |
MQTT_DISCOVERY_PREFIX |
-mqtt-disc |
homeassistant |
Home Assistant MQTT Auto-Discovery Prefix |
DEBUG |
-debug |
false |
Ausführliches Debug-Logging für RTSP, WebRTC, Signaling & MCU |
RESET_PAIRING |
-reset-pairing |
false |
Löscht den gespeicherten Private Key und erzwingt ein erneutes Pairing mit dem angegebenen QR-Code |
📄 Lizenz & Disclaimer
- Projektlizenz: Dieses Projekt ist unter der MIT License lizenziert.
- Third-Party Lizenzen: Siehe THIRD_PARTY_LICENSES.md für Hinweise zum Nabto Edge Client SDK und zu den Go-Bibliotheken.
[!NOTE]
Das bereitgestellte Docker-Image enthält keinerlei proprietäre Fremdbibliotheken. Da die Nabto Lizenz keine Distribution zulässt, wird beim allerersten Start
des Containers die benötigte libnabto_client.so vollautomatisch direkt von Nabtos offiziellem GitHub-Repository auf das System des Nutzers geladen
und persistent im Cache (/data/lib/) gespeichert.
[!NOTE]
Dies ist ein unabhängiges Open-Source-Community-Projekt. Es steht in keiner geschäftlichen Verbindung zur STEINEL GmbH, Nabto ApS oder Apple Inc. Alle Markennamen sind Eigentum der jeweiligen Rechteinhaber.