Bridge für Steinel L 625 CAM SC auf ONVIF, 2-Way Audio & Home Assistant

Die Anwendung ist als hochperformanter, 100 % autarker Go-Daemon.
Es soll die Steinel L 625 CAM SC Außenleuchte (und ggf. baugleiche Modelle) in eine standardkonforme ONVIF Profile S/T Kamera mit RTSP-Streaming, 2-Wege-Audio (Gegensprechen) und vollständiger MQTT Home Assistant Auto-Discovery verwandelt – zur nahtlosen Integration in Home Assistant, Scrypted / Apple HomeKit Secure Video (HKSV) und weitere.
Das Schwestermodell XLED CAM2 SC konnte nicht verprobt werden, könnte aber ebenfalls funktionieren. Über Rückmeldungen würde ich mich freuen.
[!WARNING]
Trotz sorgfältiger Entwicklung und Verwendung der Schnittstellen des 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 MQTT Auto-Discovery:
- Hauptlicht (
number): Maximale Helligkeit des Hauptlichts (10–100 %).
- Betriebsmodus (
select): Umschalten zwischen Sensor (Automatik), Dauerlicht und Aus.
- Helligkeitssensor (
sensor): Live-Dämmerungswert in Lux (lx).
- Bewegungsmelder (
binary_sensor): Hardware-PIR Bewegungserkennung (motion).
- PIR-Status (
binary_sensor): Zeigt an, ob der PIR-Sensor aktiv/scharf ist.
- Schieberegler (
number):
- PIR-Empfindlichkeit (
0–100 %)
- Dämmerungsschwelle (
2–1000 lx)
- Nachlaufzeit des Hauptlichts (
5–900 s)
- Grundlicht Helligkeit (
0–50 %)
- Alarmsirene (
siren): Akustischer Alarm der Außenleuchte.
- Videoauflösung (
select): Live-Umschaltung (1080p, 720p, 360p).
- Standardisierter ONVIF Profile S & Profile T Server:
- 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 extra Konfiguration für transcoding des Audiosignals. Wahlweise umschaltbar:
AUDIO_CODEC="aac" (Standard) oder AUDIO_CODEC="pcmu" (Raw Passthrough).
- RTSP Audio Backchannel: Durchleitung von HomeKit/Scrypted-Sprachdaten direkt an den Lautsprecher der Steinel-Leuchte (PCMU / G.711u 8000 Hz).
- Bewegungserkennung & Apple HomeKit Secure Video (HKSV):
- Hersteller-Architektur: Die Steinel-Kamera übermittelt Bewegungsevents ab Werk ausschließlich an das Cloud-Push-Gateway des Herstellers (für Push-Nachrichten der Steinel App) und stellt lokal im P2P-Modus den reinen Live-Stream bereit.
- Lokale HKSV-Aufnahme: In Scrypted wird über das offizielle Plugin
OpenCV Motion Detector (@scrypted/opencv) eine latenzfreie Pixelanalyse des 1080p-RTSP-Streams durchgeführt. Bewegungen von Personen, Fahrzeugen oder Tieren lösen entsprechende Events aus.
- 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="192.168.1.100" \
-e QR_CODE="did=de-xxxxxxx,pid=pr-xxxxx,sct=xxxx,pairPwd=xxxx" \
-e AUDIO_CODEC="aac" \
-e MQTT_BROKER="tcp://192.168.1.50: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 Brokerhttps://github.com/home-assistant/addons/tree/master/mosquitto 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/{timestamp}/snapshot.jpg |
GET |
Liefert das JPEG-Vorschaubild der Aufnahme direkt aus dem Kameraspeicher |
/api/sdcard/events/{timestamp}/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 |
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.