Neues Modul : IP-Symcon als HikVision Alarm Center

Hier eine Frage / Lösung den Alarm zu aktivieren/deaktivieren

Was genau möchtest du de/aktivieren ? Die Boolesche Variable ? oder auch das herunterladen der Bilder ?
Soll dieser parameter in der Instanz gesetzt werden oder über eine weitere Boolesche Variable ?

Ich habe bei mir eine einfache Lösung implementiert :
Der Kamera Alarm triggered bei mir eine Sonos Sprachausgabe sowie eine Anzeige auf IPS VIEW bei Bedarf eine SMS, Sprachanruf über VOIP oder eine EMAIL-

Das Programm/Script dazu wird über die Boolesche Variable der Moduls getriggert. Zusätzlich lege ich eine weitere Boolesche Variable (Aktivieren/Deaktivieren) an die im Webfront bzw. IPSVIEW geschaltet werden kann. Das Ereignis wird so parametrisiert das als zusätzliche Bedingung diese Variable auf true (aktiviert) steht

Eine weitere Möglichkeit besteht darin das Ereignis selbst im Webfront bzw. IPS View zu aktivieren bzw. deaktivieren.

Welche Boolsche Variable meinst Du konkret?
Ich meine die De-/Aktivierung der Bewegungserkung/Smart Events der Kamera. Also nicht die aktuellen Funktionsumfang deines Moduls.

Ich möchte das die Kameras nur auf Smartereignisse, wie z.B. Einbruchserkennung, Linienerkennung etc. reagieren, wenn wir Abwesend (das würde einer Variable in Symcon lösen)

Folgende Fälle will ich damit Abdecken:

  • Alarmausslösen z.B. via Push_Meldung und Mail, gut wäre mit Bild
  • Automatisch Akustischen Alarm auslösen (Sirenen der Kameras) - das lässt sich direkt in der Kamera konfigurieren, bessere wäre allerdings wenn ich dies zusätzlich durch ein Programm auslösen könnte. So könnte man Ereignismeldungen wie zuvor genannt getrennt melden, ohne gleich einen Akustischen Alarm auslösen zu lassen und andernfalls könnte ich sogar, wenn nur bei einer Kamera eine „Eindringung“ erkannt wurde - und gff. noch eine Bewegungserkennung durch einen PIR-Sensor im Außenbereich - den Akustischen Alarm bei allen Kameras im Außenbereich auslösen. Dann würden bei ums Haus herum überall eine Sirene ertönen :wink:

Ist-Stand: Aktuell feuern bei mir alle Kameras ständig Ereignismeldungen über die Hik-Connect App, also auch wenn wir zuhause sind - weil Hikvision in der eigenen Softwarelösung bedauerlicherweise nur eine Zeitsteuerung bietet, aber eben leider kein An/Abwesenheitsmodus.

Das führt dazu, dass ich den Akustischen Alarm der Kameras bisher nicht nutzen kann, da der Alarm auch durch uns ausgelöst würde - Weiterhin nervt es natürlich, wenn ich für jedes erkannte Ereignis, welches durch uns ausgelöst wird aktuell eine Meldung erhalte.

Dabei kommt hinzu, dass ich die Kameras über die HIK-Connect APP bisher auch nicht über eine Gruppe ansteuern kann, um z.B. die Bewegungs/Smart-Erkennung bei Anwesenheit zu deaktivieren. Ich müsste derzeit jedes mal in die Einstellungen jeder einzelnen Cam gehen, um dies jeweils zu De-/Aktivieren.

Daher wäre eine Integration der Funktion in dein Modul genial. Wenn sich das mit der separaten Zuschaltung des Akustischen Alarm nicht realisieren lässt, würde es mir zumindest helfen, wenn Du die De-/Aktivierung der Bewegungserkennung (der Kamera) in dein Modul integrieren würdest. Wenn ich dich richtig verstanden habe, wäre das setzen über eine Boolsche-Variable prima.

Dann würde ich bei mir den einfachsten Anwendungsfall realisieren können:

  • Bei Abwesenheit (Symconvariable) Bewegungserkennung der Kameras aktivieren [in dem Fall könnte ich die „Akustische Ausgabe“ (Sirene) z.B. Linienüberquerung fest in der Kamera konfigurieren und bei Erkennung auslösen lassen. Dabei würden die Ereignisse auch über die HIK-Connect APP gefeuert - sofern man diese nutzt]
  • Bei Anwesenheit die Erkennung deaktivieren (Kameras zeichnen im Außenbereich bei uns dennoch 24/7 auf )

Ich hoffe ich konnte meinen Anwendungsfall verständlich schildern

PS: Beitrag wurde noch einmal von mir aktualisiert, um auf deine Frage konkreter einzugehen

Ursache gefunden - Man muss immer den gesamten XML-Baum zurücksenden. Ich habe es einmal mit Postman versucht um die Bewegungserkennung zu De/-Aktivieren

Der Aufruf

http://192.168.60.91/ISAPI/System/Video/inputs/channels/1/motionDetection" und Body: (ich musste Grafiken einfügen. XML führt zu Problemen

führt zum selben Fehler. Sende ich den gesamten XML Body (vorher mit GET geholt)

erhalte ich nachfolgendes zurück und die Bewegungserkennung wird aktiviert. Setze ich den Parameter auf „false“ und sende erneut ab, wird die Erkennung deaktiviert.

Man muss also immer den gesamten Body senden
Kannst Du das irgendwie einbauen? :wink:

Und den „Testalarm“ (vom Benutzer selbst eingestellte Audioausgabe für 5 Sekunden) kann ich gesichert über „/ISAPI/Event/triggers/notifications/AudioAlarm/1/test?format=json“ auslösen.
Getestet auf 2 Kameras. läuft 5 Sekunden und könnte danach wiederholt werden - indem der Befehl neu abgesetzt wird. Also wenn Du die beiden Sachen da irgendwie rein bekommst, wäre das genial!

Super, Du hast dir eine Menge Arbeit gemacht und mir eine Menge Arbeit erspart. Herzlichen Dank.

Ich werde versuchen das nachzustellen und melde mich wenn ich probleme bekomme.

Sobald ich eine Version zum Testen habe schicke ich Dir einen Link (wird leider ein paar Tage dauern)

1 „Gefällt mir“

Ich habe auch noch herausgefunden, wie der Digitaleingang angesteuert und so u.a. /z.B. für den Akustischen, Alarm und Blitzlicht verwendet werden kann. Ich würde daher empfehlen alle Varianten zu implementieren, da es ja sein kann das jemand ggf. den Digitaleingang bereits anderweitig verwendet, also nicht nur für einen Akustischen Alarm (Bsp. Nutze ich bei einer Kamera den Digitaleingang um ein Bild, zu machen, jemand die Klingel betätigt )

die Ansteuerung geht über folgenden Aufruf
/ISAPI/System/IO/inputs/1 - auch hier muss m.E. der ganze Body (Methode PUT) gesendet werden.

Parameter „enable“ kann „true“ oder „false“ sein
Parameter „triggering“ kann „low“ oder „high“ sein. Der Wert „low“ löst den Eingang - in dem Fall den Alarm mit Blitzlicht aus - aus. Der Wert „high“ deaktiviert den Eingang - und somit den Alarm.


Ich freu mich, wenn ich testen darf :slight_smile:

Update: Wenn ich noch eine Empfehlung aussprechen darf: Es vielleicht am besten, den gesamten Aufbau (also Body) vorher erst immer mittels GET-Methode aktuell zu holen und dann die Werte für die zukünftig zur Verfügung gestellten Parameter in deinem Modul mittels Post oder PUT-Methode (je nach Anforderung) im gesamten zurück zu schreiben. So würden vermutlich auch Fehleranfälligkeit bei zukünftigen Firmwareupdates von Hikvision reduziert, wenn von Hikvision mal weitere Optionen hinzukommen, da ja scheinbar immer die gesamte Body zurückgesendet werden muss.

Ich habe mich mit dem Ein bzw. Ausschalten der verschiedenen Alarme auseinandergesetzt. Die genaue Beschreibung der API ist in dem folgenden Dokument zu finden : https://www.docdroid.net/wlD2i8v/hikvision-isapi-26-ipmd-service-pdf#page=5

Die Sache ist etwas komplex da die enable Tags je nach Event Type unterschiedlich sein können.

Im folgenden ist ein PHP Programm das es dir ermöglicht alle Event Typen einer Kamera ein bzw auszuschalten :

<?php
function callMotionDetectionAPI($ip, $username, $password, $path) {
    $url = "http://$ip/ISAPI/$path";
    //echo $url."\n";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }

    curl_close($ch);
    return $response;
}

function convertXMLToArray($xmlString) {
    $xmlObject = simplexml_load_string($xmlString);
    $json = json_encode($xmlObject);
    return json_decode($json, true);
}

function updateDetectionEnabled($xmlString, $detectionType, $id, $newEnabledValue) {
    // Load the XML string into a DOMDocument
    $doc = new DOMDocument();
    $doc->preserveWhiteSpace = false;
    $doc->formatOutput = true;
    $doc->loadXML($xmlString);

    // Create a DOMXPath object
    $xpath = new DOMXPath($doc);

    // Extract the namespace URI from the root element
    $rootNamespace = $doc->documentElement->namespaceURI;

    // Register the default namespace with a prefix
    $xpath->registerNamespace('ns', $rootNamespace);

    // Build the XPath expression dynamically based on the detection type
    $xpathExpression = "/ns:{$detectionType}List/ns:{$detectionType}[ns:id='{$id}']/ns:enabled";

    // Query for the <enabled> node
    $enabledNodeList = $xpath->query($xpathExpression);

    // Check if the node exists and update its value
    if ($enabledNodeList->length > 0) {
        $enabledNode = $enabledNodeList->item(0);
        $enabledNode->nodeValue = $newEnabledValue;
    } else {
        // Optionally handle the case where the <id> is not found
        throw new Exception("{$detectionType} with id {$id} not found or does not have an <enabled> tag.");
    }

    // Return the modified XML as a string
    return $doc->saveXML();
}


function getStringAfterSmart($inputString) {
    // Use strpos to find the position of "Smart/" in the string
    $position = strpos($inputString, 'Smart/');
    
    // Check if "Smart/" is found in the string
    if ($position !== false) {
        // Calculate the starting position of the substring after "Smart/"
        $startPosition = $position + strlen('Smart/');
        
        // Use substr to extract the substring from the starting position to the end
        return substr($inputString, $startPosition);
    } else {
        // If "Smart/" is not found, return the original string or handle as needed
        return $inputString;
    }
}

function sendModifiedXML($ip, $username, $password, $path, $modifiedXml) {
    $url = "http://$ip/ISAPI/$path";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml'));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $modifiedXml);

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }

    curl_close($ch);
    return $response;
}

// Example usage:

$username = "admin";
$password = "XXXXXX";

//$path = "System/Video/inputs/channels/1/motionDetection";
$path_array = ["Smart/FieldDetection","Smart/LineDetection","Smart/RegionEntrance","Smart/RegionExiting"];
$newEnabledValue = 'true';


$search = array("192.168.50.");
$location = 'ProcessCameraEvents';
$type = 2; // Object Type (0: Category, 1: Instance, 2: Variable, 3: Script, 4: Event, 5: Media, 6: Link)

$gesuchte_objekte = array_filter(IPS_GetObjectList(), function ($object) use ($search, $location, $type) {
    $name = IPS_GetName($object);
    $locationStr = IPS_GetLocation($object);
    $objectType = IPS_GetObject($object)['ObjectType'];

    // Check if any of the search terms are present in the name
    $nameMatch = false;
    foreach ($search as $searchStr) {
        if (strpos($name, $searchStr) !== false) {
            $nameMatch = true;
            break;
        }
    }

    // Check if the location matches
    $locationMatch = strpos($locationStr, $location) !== false;

    // Return true if all conditions are met
    return $nameMatch && $locationMatch && ($objectType == $type);
});

foreach($gesuchte_objekte as $key => $ip_var_id)
{
    $ip = GetValueString($ip_var_id);
    echo $ip."\n";
    foreach($path_array as $key => $path)
    {
        //echo $ip." ". $username." ".$password." ".$path."\n";
        $response = callMotionDetectionAPI($ip, $username, $password, $path);
        //echo $response;
        //$newEnabledValue = 'false';


        try {
        // Update FieldDetection with id=1
        $modifiedXml= updateDetectionEnabled($response, getStringAfterSmart($path), 1,$newEnabledValue );
        } catch (Exception $e) {
            echo 'Error: ' . $e->getMessage();
        }



        // Send modified XML back to the API
        $sendResponse = sendModifiedXML($ip, $username, $password, $path, $modifiedXml);
        echo $sendResponse;

    }
}
?>

Ich werde längere Zeit benötigen um diese Funktion wie auch die anderen von dir genannten in das Modul zu integrieren. Ab nächster Woche bin ich für 4 Wochen auf Reisen und kann nicht weiter am Modul arbeiten. Danach bin ich für 6 Monate in Florida und muss mir erst ein HIKVISION Kamera besorgen. Bis ich das Modul fertig habe solltest du in der Lage sein deine Kameras mit dem oben beigefügten Code zu aktivieren oder zu deaktivieren.

User Name, Password und Subnet müssen gesetzt werden. Das Programm aktiviert bzw deaktiviert alle Kameras die unterhalb des Moduls liegen. Soll nur eine Kamera geschaltet werden dann einfach die komplette IP Adresse eingeben

@novatrust Ich gehe davon aus das im Modul jede Ebene schaltbar sein soll.

Das heißt man kann Line, Field und Region in/out jeweils pro Kamera aktivieren, dann alle pro Kamera und danach alle für jede Kamera unterhalb des Moduls.

Dazu wird jeweils eine boolesche Variable angelegt und per RequestAction geschaltet

Das habe ich so realisiert das immer der gesamte XML String geladen, danach modifiziert und zurück geschickt wird