Moin,
Auf den ersten Blick sieht der API Key sehr kurz aus? Sicher das der richtig ist?
Steht irgendwas im Debug vom Gateway?
Moin,
Auf den ersten Blick sieht der API Key sehr kurz aus? Sicher das der richtig ist?
Steht irgendwas im Debug vom Gateway?
Moin, der ist API Key war definitiv korrekt. Ich habe den per copy paste rüber kopiert und auch nochmal geprüft auf dem NVR Gen 2. Ich habe jetzt aber nochmal einen neuen generiert und schwups, jetzt tuts und ich kann die Kameras hinzufügen. Allerdings kommt dann gleich das nächste Problem: Die Zwei hinzugefügten Kameras melden “Instanz ist inaktiv”. Der Debug meldet keinen Fehler…
Aber wenn ich schon mal dabei bin, noch ein zwei Fragen:
1.) Der RTSP Stream funktioniert scheint’s nur mit dem Standard Encoding. Enhanced und Advanced funktionieren nicht. Weiß jemand, welche Codecs hier verwendet werden? Ich habe hier ehrlich gesagt auch erstmal gebraucht, um zu verstehen, dass auch RTSP unterstützt wird (Aufruf über rtsp://ip:7447/id) und nicht nur RTSPS (was ja Symcon nicht unterstützt).
2.) Ich teste aktuell eine G6 Pro Bullet mit Enhancer und eine G6 180 und der erste Eindruck ist hervorragend. Aber die G6 möchte ich im Hallway modus betreiben und laut Oberfläche von Ubiquity heißt es, dass man diese Kamera nicht draußen in diesem Modus betreiben soll. Weiß jemand warum?
3.) Ich will meine BWM (weil so unzuverlässig) alle abschalten und durch die Personenerkennung der Kameras ersetzten. Hierfür nutze ich den Webhook der Kamera und auf Seiten von Symcon. Das funktioniert perfekt. Weiß jemand, wie es funktioniert das in die andere Richtung zu initiieren, um der Kamera mitzuteilen, das die Alarmanlage eingeschaltet ist und damit dem Alarm Manager mitzuteilen, dass er eine bestimmte Regel anwenden soll?
Danke und Gruß
Und noch eine vierte Frage: Funktioniert der Snapshot eigentlich nur mit SSL / HTTPS? Oder auch ohne? https://192.168.50.82/proxy/protect/integration/v1/cameras/id/snapshot
Musst in der Instanz den Timer auf <> 0 Stellen, dann werden die Aktiv.
Und zu 4. Snapshot vermutlich nur über https… zumindestlaut doku,
Top! Vielen Dank! Mit Timer > 0 funktioniert die Instanz.
Allerdings nicht der Snapshot. Der ist als Fehlerhaft gekennzeichnet. Fehlermeldung vom Debug: 06.06.2026, 17:54:28 | UnifiPDevice | Snapshot error: Failed to parse ‚request-query‘
Klasse, wenn zukünftig das Modul auch die Alarmprofile unterstützt…
Falls du nicht auf der Beta bist, teste die mal bitte.
Es gibt nun eine neue Beta mit Alarm Profiles Instanz, darüber kann das aktive Alarm Profil ausgewählt werden und Aktiv/Inaktiv geschaltet werden.
Bitte darauf achten das der Alammanager-Modus auf Lokal steht, sonst bleiben die Profile leer!

Top! Vielen Dank! Der Snapshot klappt mit der Beta 1.6. Super. Beim Image-Graber gibt es eine Funktion IG_UpdateImage, wenn man programmatisch ein Bild aktualisieren will, z.B. kurz vor E-Mail Versand oder Anzeige im WebFront o.ä. Hast Du sowas auch vorgesehen?
Bzgl. der Alarm Profile: Hier habe ich mir gestern bereits selber eine Lösung implementiert und mir drei Profile definiert: Abwesend - Alarm aktiv, Anwesend - Alarm inaktiv und Anwesend - Alarm reduziert. Ich habe das mit einer entsprechenden Prüfung umgesetzt, weil das erfolgreiche Setzten des Profils extrem wichtig ist. Ausgelesen habe ich meine Profile mit den folgenden Request, der mir die entsprechenden IDs zurück gibt:
https://192.168.50.XY/proxy/protect/integration/v1/arm-profiles
Und dann folgende Funktion zum Wiederverwenden:
<?php
// UNIFI PROTECT ARM FUNKTIONSBIBLIOTHEK ZUM SETZTEN DES JEWEILIGEN ALARM-PROFILS in UNIFI PROTECT
define("UNIFI_NVR_IP", "192.168.50.XY"); // IP NVR
define("UNIFI_API_KEY", "KEY");
define("UNIFI_PRUEF_ID", 46351); // Objekt-ID von Event-Skript
define("UNIFI_ERWARTET_VAR",32330); // ID der String-Variable "Erwartetes_Profil"
define("UNIFI_AKTIV_VAR", 46506); // String-Variable "Aktives_Profil" (Name fürs WebFront)
// Push- und Mail-Ziele
define("MOBILE_PUSH_ID", 14130);
define("FEHLER_MAIL_ID", 33644);
// Zentrale Zuordnung Profil-ID -> Klartextname
function unifiProfilNamen(): array {
return [
"6a24464400e3e303e4009ed7" => "UNTERWEGS - ALARM AKTIV",
"6a24496300d1e303e400a01b" => "ZUHAUSE - ALARM REDUZIERT",
"6a2449750069e303e400a026" => "ZUHAUSE - ALARM INAKTIV",
];
}
function unifiProfilName(string $id): string {
$namen = unifiProfilNamen();
return $namen[$id] ?? "UNBEKANNT ($id)";
}
function SetArmProfile(string $profileId) {
$base = "https://" . UNIFI_NVR_IP . "/proxy/protect/integration";
// 1. Erst entschärfen – sonst lehnt die API den Profilwechsel ab ("Arm alarm is armed")
unifiRequest("$base/v1/arm-profiles/disable", "POST", "");
// 2. Profil auswählen (jetzt erlaubt, da unscharf)
unifiRequest("$base/v1/arm-profiles/settings", "PATCH",
json_encode(["armProfileId" => $profileId]));
// 3. Arm-System wieder aktivieren – mit dem neuen Profil
unifiRequest("$base/v1/arm-profiles/enable", "POST", "");
// 4. Sollwert (ID) für die Prüfung merken
SetValueString(UNIFI_ERWARTET_VAR, $profileId);
IPS_LogMessage("ALARMANLAGE", "INFO 1010 - UNIFIY PROTECT ALARM PROFIL GESETZT AUF " . unifiProfilName($profileId) . " – PRÜFUNG IN 90 SEKUNDEN");
// 5. Verzögerte Prüfung planen (90s wegen bis zu 60s Aktivierungsverzögerung beim AWAY-Profil)
IPS_SetScriptTimer(UNIFI_PRUEF_ID, 90);
}
function unifiRequest($url, $method, $body) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => [
"X-API-KEY: " . UNIFI_API_KEY,
"Content-Type: application/json"
],
]);
if ($body !== "") curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
$r = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code < 200 || $code >= 300) {
IPS_LogMessage("UniFi", "API-Fehler $code bei $url: $r");
}
return $r;
}
?>
Und der entsprechende Aufruf (Beispiel Alarm scharf):
<?php
require_once(IPS_GetScriptFile(32445));
SetArmProfile("6a24464400e3e303e4009ed7");
?>
Last but not least ein Script, das Timer-gesteuert jeweils prüft, ob der jeweilige Alarm erfolgreich gesetzt wurde, weil das extrem wichtig zu wissen ist:
<?php
// ZEITVERZOEGERTE STATUSPRUEFUNG DES ALARM-PROFILS
IPS_SetScriptTimer($_IPS['SELF'], 0); // einmalige Prüfung: Timer aus
require_once(IPS_GetScriptFile(32445));
$base = "https://" . UNIFI_NVR_IP . "/proxy/protect/integration";
$response = unifiRequest("$base/v1/nvrs", "GET", "");
$erwartet = GetValueString(UNIFI_ERWARTET_VAR); // erwartete Profil-ID
$erwartetName = unifiProfilName($erwartet);
$data = json_decode($response, true);
$armMode = $data['armMode'] ?? null;
if ($armMode === null) {
meldeFehler("NVR NICHT ERREICHBAR ODER ANTWORT OHNE ARMMODE.", $erwartetName, "-", "-");
return;
}
$iststatus = $armMode['status'] ?? "unbekannt"; // Originalwert für die Vergleichslogik!
$istProfil = $armMode['armProfileId'] ?? "";
$istName = unifiProfilName($istProfil);
// Erfolg: richtiges Profil aktiv und System scharf ("armed", nicht mehr "arming")
$erfolg = ($istProfil === $erwartet && $iststatus === "armed");
if ($erfolg) {
// Verifizierter Status -> ins UI schreiben
SetValueString(UNIFI_AKTIV_VAR, $istName);
IPS_LogMessage("ALARMANLAGE", "INFO 1011 - STATUSPRÜFUNG OK - $istName (" . statusKlartext($iststatus) . ")");
} else {
meldeFehler("SOLL/IST-ABWEICHUNG BEIM ALARM-PROFIL.", $erwartetName, $istName, statusKlartext($iststatus));
}
// Wandelt den API-Status in Klartext um (nur für Anzeige/Meldung, nicht für Vergleiche)
function statusKlartext(string $status): string {
$map = [
"armed" => "SCHARF",
"disarmed" => "UNSCHARF",
"arming" => "WIRD SCHARF GESCHALTET",
];
return $map[$status] ?? strtoupper($status);
}
function meldeFehler(string $grund, string $sollName, string $istName, string $istStatus) {
$kurz = "UNIFI PROTECT ALARM PROFIL KONNTE NICHT KORREKT GESETZT WERDEN.";
// UI-Variable auf sprechenden Fehlertext setzen – inkl. tatsächlich gemeldetem Zustand
SetValueString(UNIFI_AKTIV_VAR,
"⚠ FEHLER - SOLL: $sollName / IST: $istName ($istStatus)");
$textEmail =
"FEHLER BEIM SETZEN DES UNIFI PROTECT ALARM-PROFILS.\n\n" .
"GRUND: $grund\n" .
"SOLL-PROFIL: $sollName\n" .
"IST-PROFIL: $istName\n" .
"IST-STATUS: $istStatus\n" .
"ZEITPUNKT: " . date("d.m.Y H:i:s") . "\n";
IPS_LogMessage("ALARMANLAGE", "FEHLER 1201 - $grund (SOLL: $sollName, IST: $istName / $istStatus)");
// Push-Benachrichtigung (Titel, Text, Sound, Ziel)
WFC_PushNotification(MOBILE_PUSH_ID, "ALARM-PROFIL FEHLER", $kurz . " ($sollName)", "alarm", 0);
// E-Mail
SMTP_SendMail(FEHLER_MAIL_ID, "FEHLER", $textEmail);
}
?>
Mir ist gerade noch etwas aufgefallen: Zumindest der “Snapshot” wird nicht aktualisiert entsprechend dem Intervall. Ich hatte hier 300 Sekunden gewählt aber die letzte Aktualisierung ist noch die manuelle von 14:10 (obwohl es jetzt bereits 16:51 Uhr ist).
Snapshot kannst du per RequestAction(43260,1); auf die entsprechende „Snapshot“ variable erstellen.
Das mit dem aktivieren und danach prüfen schau ich mir noch mal in Ruhe an, da fragst du ja den NVR endpoint ab, den hatte ich nicht auf dem Schirm. Muss mal testen ob das mit meiner UDM Pro auch geht.
Und der Timer ist nur für die normalen Daten, Snapshot wird damit nicht abgefragt.
Das kannst auch direkt per Ereignis auf die Variable machen z.B. .
Ich Merke mir das aber auch mal, vllt. bau ich einfach einen zweiten Timer ein, der ein Snapshot erstellt.
Das wäre klasse. Vielen Dank!
Ich bin so begeistert von den Ubiquity Produkten. Endlich nicht mehr diese vor Jahren stehengebliebenen Hikvision Kameras, bei denen keine Gesichts- und Personenerkennung funktioniert. Und was ich auch extrem klasse finde bei Ubiquity: wie gut der Support funktioniert und man direkt mit den Entwickler in Kontakt kommt. Genauso muss das sein! Ich werde die Kameras jetzt nach erfolgreichem Test auf jeden Fall vollständig gegen die Hikvision Kameras austauschen.
Moin,
in der neusten Beta kannst du nun einen Timer hinterlegen, damit wird der NVR dann abgefragt und zeigt dir den aktuellen Status an (Arm+Profil).
Vorm scharf schalten wird der Status einmal abgefragt und sollte der Alarm bereits aktiv sein, wird ein Fehler ins log geschrieben und der aktuelle Status abgerufen.
Zudem gibt’s in den Kamera Instanzen nun einen Timer um den Snapshot zu aktualisieren.
Super! Probiere das die nächsten Tage mal aus…
Ich habe mir jetzt auch den neuen Netzwerklautsprecher (AI Speaker) bestellt. Da kommt dann gleich die nächste neue Anforderung für das Modul… ![]()
Was Kann der Speaker denn? Wofür nutzt man sowas? ![]()
Mein Smart Home kann damit Statusmeldung ausgeben, zum Beispiel „Es sind noch Fenster im Haus geöffnet und deswegen lässt sich die Alarmanlage nicht einschalten“ oder „ Feuchtigkeit im Technikraum detektiert“. Oder schaltet automatisch die Musik ein, wenn der Bewegungsmelder im Bad erkennt, dass sich dort jemand befindet. Derzeit nutze ich dafür die Sprachausgabe von meinem Windows Server und einen externen Bluetooth Verstärker. Aber mit einem über das Netzwerk verbundenen IP basierten Lautsprecher, auf dem man Sprachnachrichten hochladen kann, bin ich dann dort endlich auch Plattform-unabhängig. Teilweise nutze ich auch den AWS Polly Dienst zur Sprachausgabe… Ich berichte mal, wenn ich das Teil ausprobiert habe…
Moin,
ich hab seit einiger Zeit Meldungen dieser Art im Logfile Stehen:
17.06.2026, 05:04:17 | FlowHandler | Kann Daten nicht zur Instanz #12781 weiterleiten:
Fatal error: Uncaught TypeError: UnifiProtectEvents::updateSmartDetectSelectionStates(): Argument #1 ($deviceID) must be of type string, null given, called in /mnt/data/symcon/modules/.store/bgersmann.unifiprotect/UnifiProtectEvents/module.php on line 158 and defined in /mnt/data/symcon/modules/.store/bgersmann.unifiprotect/UnifiProtectEvents/module.php:668
Stack trace:
#0 /mnt/data/symcon/modules/.store/bgersmann.unifiprotect/UnifiProtectEvents/module.php(158): UnifiProtectEvents->updateSmartDetectSelectionStates(NULL, Array)
#1 /mnt/data/symcon/modules/.store/bgersmann.unifiprotect/UnifiProtectEvents/module.php(90): UnifiProtectEvents->HandleEvent('{"item":{"id":"...')
#2 /-(3): UnifiProtectEvents->ReceiveData('{"Buffer":"7B22...')
#3 {main}
thrown in /mnt/data/symcon/modules/.store/bgersmann.unifiprotect/UnifiProtectEvents/module.php on line 668
Hast Du eine Idee, woran das liegen kann?
Gruß,
Loerdy
Hast du irgendein neues gerät hinzugefügt?
Vereinzelt hab ich schon mal gesehen das die DeviceID in Protect leer ist, das würde diesen Fehler auslösen.
Kann ich mal im Code abfangen.
Du könntest mal per var_dump(UNIFIPGW_getCameras(12345)); testen ob da ein device mit leerem „value“ zurück kommt. (ID=ProtectGateway)
Ich erhalte diese Ausgabe:
array(9) {
[0]=>
array(2) {
["caption"]=>
string(16) "Außen - Carport"
["value"]=>
string(24) "653fd7e100461403e40003f2"
}
[1]=>
array(2) {
["caption"]=>
string(17) "Außen - Gebimmel"
["value"]=>
string(24) "653fd7ea03e01403e40003f6"
}
[2]=>
array(2) {
["caption"]=>
string(17) "Außen - Haustür"
["value"]=>
string(24) "653fd7e100601403e40003f3"
}
[3]=>
array(2) {
["caption"]=>
string(14) "Garten - Front"
["value"]=>
string(24) "66ed739d02119e03e400075c"
}
[4]=>
array(2) {
["caption"]=>
string(17) "Garten - Schuppen"
["value"]=>
string(24) "66620f4003abd103e4000825"
}
[5]=>
array(2) {
["caption"]=>
string(17) "Garten - Terrasse"
["value"]=>
string(24) "653fd7e1002a1403e40003f1"
}
[6]=>
array(2) {
["caption"]=>
string(11) "Innen - HWR"
["value"]=>
string(24) "653fd7e1012c1403e40003f5"
}
[7]=>
array(2) {
["caption"]=>
string(8) "Schuppen"
["value"]=>
string(24) "653fd7e003de1403e40003ef"
}
[8]=>
array(2) {
["caption"]=>
string(14) "tapo-01-garten"
["value"]=>
string(24) "6900d73d01f57103e4808b14"
}
}
Wenn ich das richtig sehe ist das value überall vorhanden, oder?
Gruß,
Loerdy
Ja, das sieht gut aus. Hab gerade mal in den code geschaut, da kommt scheinbar ein Event ohne DeviceID. Ich würde da bei Gelegenheit mal einbauen das er dies prüft und sonst das Event ins Debug schiebt.