steinel-cam-bridge

module
v1.3.6-0...-6bfb4b3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: MIT

README

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

Latest Release CodeQL Analysis golangci-lint Go Reference Home Assistant Add-on Docker Image Go Version

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 – standardmäßig 30 s, Dateigröße) und direkter URL für das MP4-Video (video_url). Sofern vom Kameramodell unterstützt, wird zusätzlich thumbnail_url bereitgestellt (Kameras wie die L 625 CAM SC speichern reine MP4-Videodateien ohne separate Standbilder).
    • ⚙️ Konfiguration (Einstellungsbereich):
      • Dämmerungsschwelle (number.lux_threshold): Schaltschwelle in Lux (21000 lx), ab welcher Umgebungsdunkelheit das Licht bei Bewegung schaltet.
      • Hauptlicht Helligkeit (number.highlight): Maximale Leuchtstärke des Flutlichts (10100 %).
      • Grundlicht Helligkeit (number.lowlight): Dauerhafte Nachtlicht-Helligkeit (050 %).
      • Nachlaufzeit (number.duration): Einschaltdauer des Hauptlichts nach Bewegung (5900 s).
      • PIR-Empfindlichkeit (number.pir_sensitivity): Reichweite / Sensitivität des Bewegungsmelders (0100 %).
      • 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)

Open your Home Assistant instance and show the add-on store with a specific repository enabled.

  1. 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
    
  2. Wählen Sie "Steinel CAM Bridge" aus und klicken Sie auf Installieren.
  3. 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:

Home Assistant Steuerung und Sensoren

2. Scrypted (Home Assistant Add-on oder Standalone)

Egal ob Scrypted als Home Assistant Add-on oder als eigenständige Instanz läuft:

  1. Im Scrypted ONVIF Plugin auf Add Camera klicken (IP-Adresse des Bridge-Servers, Port 8000).
  2. Scrypted erkennt automatisch 1080p Video, natives AAC-Mikrofon und Gegensprechanlage.
  3. Natives Audio: Die Bridge liefert standardmäßig natives AAC-Audio (16 kHz). In Scrypted ist kein manuelles Audio-Transcoding im HomeKit-DEBUG-Reiter erforderlich.
  4. 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.
  5. Im HomeKit Plugin die Kamera aktivieren ➔ Live-Streaming & HKSV-Aufnahmen in Apple Home laufen vollautomatisch!

Scrypted ONVIF Kamera Integration


🗄️ 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 (sofern vom Modell unterstützt, sonst HTTP 501 Not Implemented)
/api/sdcard/events/{id}/video.mp4 GET Streamt die vollständige MP4-Aufnahme (2560x1440 HEVC / AAC) als Binärstream (inkl. Hardware-Überlastungsschutz)

[!NOTE] SD-Karten Snapshots vs. Video-Downloads: Manche Kameramodelle (u. a. Steinel L 625 CAM SC) legen auf der internen MicroSD-Karte ausschließlich vollständige Video-Clips (event_<timestamp>.mp4) und keine separaten JPEG-Dateien ab. Um Wartezeiten und Schnittstellen-Blockaden zu vermeiden, quittiert /api/sdcard/events/{id}/thumbnail.jpg bei solchen Modellen Anfragen sofort mit HTTP 501 Not Implemented. Das MP4-Video steht unter /api/sdcard/events/{id}/video.mp4 uneingeschränkt zum Download und zur Wiedergabe bereit.

[!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 (Steinel L 625 CAM SC via Nabto Edge CGo):
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 (Steinel L 625 CAM SC via Nabto Edge CGo):
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

# Steinel L 620 CAM / XLED CAM 1 (kein CGo / Nabto SDK erforderlich):
./steinel-bridge \
  -ip 192.168.1.100 \
  -type l620 \
  -user admin \
  -pass "meinpasswort" \
  -debug

⚙️ Konfiguration & Umgebungsvariablen

Die Konfiguration erfolgt nach den Grundsätzen einer 12-Factor App in folgender Prioritätsreihenfolge:

  1. Explizite CLI-Flags (höchste Priorität)
  2. Umgebungsvariablen
  3. Konfigurationsdatei (/data/options.json im Home Assistant Add-on)
  4. Interne Defaults
Kameraverbindung & Authentifizierung
Umgebungsvariable CLI-Flag Standard Beschreibung
CAMERA_IP -ip "" Lokale IP-Adresse der Steinel-Kamera im Heimnetz (Pflicht)
CAMERA_TYPE -type auto Kameramodell: auto (automatische Erkennung), l625 (L 625 CAM SC), l620 (L 620 CAM / XLED CAM 1)
CAMERA_USER -user admin Benutzername für L 620 CAM (Standard: admin)
CAMERA_PASSWORD / CAMERA_PASS -pass (oder -password) "" Geräte-Passwort für L 620 CAM (in der Steinel-App vergeben)
QR_CODE -qr "" QR-Code Payload aus der Steinel App ("Kamera teilen") für automatisches Pairing der L 625 CAM SC
KEY_PATH -key data/client.key Speicherpfad für den persistenten ECC-Schlüssel (L 625 CAM SC)
RESET_PAIRING -reset-pairing false Löscht den gespeicherten Private Key und erzwingt ein erneutes Pairing mit dem angegebenen QR-Code
Streaming & Server-Ports
Umgebungsvariable CLI-Flag Standard Beschreibung
RESOLUTION -res 1080p Videoauflösung: 1080p, 720p, 360p
AUDIO_CODEC -audio-codec aac Audio-Codec des RTSP/ONVIF Streams: aac (nativ transkodiert, empfohlen) oder pcmu (Raw Passthrough)
RTSP_PORT -port 8554 Port des integrierten RTSP-Servers
RTSP_PATH -path steinel Stream-Pfad des RTSP-Servers (rtsp://<host>:<port>/<path>)
ONVIF_PORT -onvif 8000 Port des integrierten ONVIF HTTP- und SD-Karten REST API-Servers
SDCARD_SYNC_INTERVAL / SYNC_INTERVAL -sync-interval (oder -sdcard-sync-interval) 60 Intervall in Sekunden für die Hintergrundabfrage neuer MicroSD-Aufnahmen (5–300 s)
Nabto Edge Treiber & Diagnose (L 625 CAM SC)
Umgebungsvariable CLI-Flag Standard Beschreibung
NABTO_DRIVER -nabto-driver cgo Nabto-Treiber-Engine: cgo (offizielles C-SDK, empfohlen & Standard) oder pure (nativer Go-Stack, experimentell)
USE_CGO_NABTO -use-cgo true Boolean-Schalter für CGo-Treiber (true = cgo, false = pure)
DEBUG -debug false Ausführliches Debug-Logging für RTSP, WebRTC, Signaling & MCU
IS_BETA / BETA -beta false Kennzeichnet die Instanz bei der IAM-Registrierung auf der Kamera als Beta (steinel-bridge-beta-...)
MQTT & Home Assistant Integration
Umgebungsvariable CLI-Flag Standard Beschreibung
MQTT_BROKER -mqtt-broker "" MQTT Broker URL (z. B. tcp://192.168.1.100:1883). Leer lassen für automatische Supervisor-Erkennung im Home Assistant Add-on
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: <prefix>/<did>/...)
MQTT_DISCOVERY_PREFIX -mqtt-disc homeassistant Home Assistant MQTT Auto-Discovery Prefix

📄 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.

Directories

Path Synopsis
cmd
launcher command
steinel-bridge command
pkg
mcu
tools
mock-camera command
test-pure-nabto command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL