";
+ }
+
+ my $servername = $a[2];
+ my $serverport = $a[3];
+ my $username = $a[4];
+ my $password = $a[5];
+ my $camname = $a[6];
+ my $rectime = $a[7];
+
+
+ unless ($rectime =~ /^\d+$/) { return " The given Recordtime is not valid. Use only figures 0-9 without decimal places !";}
+ # führende Nullen entfernen
+ $rectime =~ s/^0+//;
+
+ $hash->{SERVERNAME} = $servername;
+ $hash->{SERVERPORT} = $serverport;
+ $hash->{USERNAME} = $username;
+ $hash->{PASSWORD} = $password;
+ $hash->{CAMNAME} = $camname;
+ $hash->{RECTIME} = $rectime;
+
+ return undef;
+}
+
+
+sub SSCam_Undef {
+ my ($hash, $arg) = @_;
+ return undef;
+}
+
+sub SSCam_Attr {
+}
+
+sub SSCam_Set {
+ my ( $hash, @a ) = @_;
+ return "\"set X\" needs at least an argument" if ( @a < 2 );
+ my $name = shift @a;
+ my $opt = shift @a;
+ my $value = join("", @a);
+ my %SSCam_sets = (
+ on => "on",
+ off => "off");
+ my $errorcode;
+ my $s;
+ my $logstr;
+ my @cList;
+
+ # ist die angegebene Option verfügbar ?
+ if(!defined($SSCam_sets{$opt})) {
+ @cList = keys %SSCam_sets;
+ return "Unknown argument $opt, choose one of " . join(" ", @cList);
+ } else {
+
+ # Aufnahme starten
+ if ($opt eq "on") {
+ # wegen Syno-105-Fehler mehrfaches durchlaufen bis kein 105-Fehler mehr oder Aufgabe nach x Durchläufen ($s = Schleifendurchlauf)
+ $errorcode = "105";
+ $s = 30;
+ while ($errorcode eq "105" && $s > 0) {
+ &camstart($hash);
+ $errorcode = ReadingsVal("$name","Errorcode","none");
+ # Logausgabe
+ $logstr = "Readingsval $name".":Errorcode is: $errorcode";
+ $logstr = "Readingsval $name".":Errorcode is still $errorcode but end of loop reached, giving up!" if ($s == 1);
+ &printlog($hash,$logstr,"5");
+ $s -=1;
+ }
+ }
+
+
+ # Aufnahme stoppen
+ if ($opt eq "off") {
+ # wegen Syno-105-Fehler mehrfaches durchlaufen bis kein 105-Fehler mehr oder Aufgabe nach x Durchläufen ($s = Schleifendurchlauf)
+ $errorcode = "105";
+ $s = 30;
+ while ($errorcode eq "105" && $s > 0) {
+ &camstop($hash);
+ $errorcode = ReadingsVal("$name","Errorcode","none");
+ # Logausgabe
+ $logstr = "Readingsval $name".":Errorcode is: $errorcode";
+ $logstr = "Readingsval $name".":Errorcode is still $errorcode but end of loop reached, giving up!" if ($s == 1);
+ &printlog($hash,$logstr,"5");
+ $s -=1;
+ }
+ }
+ }
+}
+
+
+###############################################################################
+#### Starten einer Kameraaufnahme
+
+sub camstart {
+ # Übernahmewerte sind $username, $password,$camname, $servername, $serverport
+ my ($hash) = @_;
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $username = $hash->{USERNAME};
+ my $password = $hash->{PASSWORD};
+ my $camname = $hash->{CAMNAME};
+ my $device = $hash->{NAME};
+ my $rectime = $hash->{RECTIME};
+ my $logstr;
+ my $validurl;
+ my $success;
+ my $sid;
+ my $camid;
+ my $apiextrecpath;
+ my $apiextrecmaxver;
+ my $errorcode;
+ my $url;
+ my $myjson;
+ my $data;
+ my $error;
+
+ # Logausgabe
+ $logstr = "--- Begin Function camstart ---";
+ &printlog($hash,$logstr,"5");
+
+ $logstr = "Recording of Camera $camname should be started now";
+ &printlog($hash,$logstr,"5");
+
+ # Erreichbarkeit Disk Station Url testen
+ $validurl = &validurl($hash);
+ unless ($validurl eq "true") {return};
+
+ # API-Pfade und MaxVersions ermitteln
+ ($hash, $success) = &getapisites($hash);
+ unless ($success eq "true") {return};
+
+ # Login und SID ermitteln
+ ($sid, $success) = &serverlogin($hash);
+ unless ($success eq "true") {return};
+
+ # Kamera-ID anhand des Kamaeranamens ermitteln
+ ($camid, $success) = &getcamid($hash,$sid);
+ unless ($success eq "true") {&serverlogout($hash,$sid); return};
+
+ # Start der Aufnahme
+ $apiextrecpath = $hash->{APIEXTRECPATH};
+ $apiextrecmaxver = $hash->{APIEXTRECMAXVER};
+ $errorcode = "";
+ $url = "http://$servername:$serverport/webapi/$apiextrecpath?api=SYNO.SurveillanceStation.ExternalRecording&method=Record&version=$apiextrecmaxver&cameraId=$camid&action=start&session=SurveillanceStation&_sid=$sid";
+ $myjson = get $url;
+
+ # Evaluiere ob Daten im JSON-Format empfangen
+ ($hash, $success) = &evaljson($hash,$myjson,$url);
+ unless ($success eq "true") {&serverlogout($hash,$sid); return};
+
+ # Logausgabe
+ $logstr = "URL call: $url";
+ &printlog($hash,$logstr,"4");
+ $logstr = "JSON response: $myjson";
+ &printlog($hash,$logstr,"4");
+
+ # dekodiere Response aus JSON Format
+ $data = decode_json($myjson);
+ $success = $data->{'success'};
+
+
+ if ($success eq "true") {
+
+ # die URL konnte erfolgreich aufgerufen werden
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Record","Start");
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","none");
+ readingsEndUpdate($hash, 1);
+ $hash->{STATE} = "on";
+
+ # bedingt Browseraktualisierung und Status der "Lampen"
+ { fhem "trigger $device on" }
+
+ # Logausgabe
+ $logstr = "Camera $camname with Recordtime $rectime"."s started";
+ &printlog($hash,$logstr,"3");
+
+ # FHEM Sleep Kommando, kein blockieren von FHEM
+ {fhem("sleep $rectime;set $device off")};
+ $logstr = "Autostop command: {fhem(\"sleep $rectime quiet;set $device off\")}";
+ &printlog($hash,$logstr,"5");
+
+ }
+ else {
+ # die URL konnte nicht erfolgreich aufgerufen werden
+ # Errorcode aus JSON ermitteln
+ $errorcode = $data->{'error'}->{'code'};
+
+ # Fehlertext zum Errorcode ermitteln
+ $error = &experror($hash,$errorcode);
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode",$errorcode);
+ readingsBulkUpdate($hash,"Error",$error);
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "ERROR - Start Recording of Camera $camname not possible. Errorcode: $errorcode - $error";
+ &printlog($hash,$logstr,"1");
+ }
+ &serverlogout($hash,$sid);
+
+ # Logausgabe
+ $logstr = "--- End Function camstart ---";
+ &printlog($hash,$logstr,"5");
+
+return;
+}
+
+##############################################################################
+### Stoppen Kameraaufnahme
+
+sub camstop {
+ # Übernahmewerte sind $username, $password,$camname, $servername, $serverport
+ my ($hash) = @_;
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $username = $hash->{USERNAME};
+ my $password = $hash->{PASSWORD};
+ my $camname = $hash->{CAMNAME};
+ my $device = $hash->{NAME};
+ my $logstr;
+ my $validurl;
+ my $success;
+ my $sid;
+ my $camid;
+ my $apiextrecpath;
+ my $apiextrecmaxver;
+ my $errorcode;
+ my $url;
+ my $myjson;
+
+ # Logausgabe
+ $logstr = "--- Begin Function camstop ---";
+ &printlog($hash,$logstr,"5");
+
+ $logstr = "Recording of Camera $camname should be stopped now";
+ &printlog($hash,$logstr,"5");
+
+ # Erreichbarkeit Disk Station Url testen
+ $validurl = &validurl($hash);
+ unless ($validurl eq "true") {return};
+
+ # API-Pfade und MaxVersions ermitteln
+ ($hash, $success) = &getapisites($hash);
+ unless ($success eq "true") {return};
+
+ # SID ermitteln nach Login
+ ($sid, $success) = &serverlogin($hash);
+ unless ($success eq "true") {return};
+
+ ($camid, $success) = &getcamid($hash,$sid);
+ unless ($success eq "true") {&serverlogout($hash,$sid); return};
+
+ $apiextrecpath = $hash->{APIEXTRECPATH};
+ $apiextrecmaxver = $hash->{APIEXTRECMAXVER};
+
+ $errorcode = "";
+ $url = "http://$servername:$serverport/webapi/$apiextrecpath?api=SYNO.SurveillanceStation.ExternalRecording&method=Record&version=$apiextrecmaxver&cameraId=$camid&action=stop&session=SurveillanceStation&_sid=$sid";
+ $myjson = get $url;
+
+ # Evaluiere ob Daten im JSON-Format empfangen
+ ($hash, $success) = &evaljson($hash,$myjson,$url);
+ unless ($success eq "true") {&serverlogout($hash,$sid); return};
+
+ # Logausgabe
+ $logstr = "URL call: $url";
+ &printlog($hash,$logstr,"4");
+ $logstr = "JSON response: $myjson";
+ &printlog($hash,$logstr,"4");
+
+ # dekodiere Response aus JSON Format
+ my $data = decode_json($myjson);
+ $success = $data->{'success'};
+
+ if ($success eq "true") {
+ # die URL konnte erfolgreich aufgerufen werden
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Record","Stop");
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","none");
+ readingsEndUpdate($hash, 1);
+ $hash->{STATE} = "off";
+
+ # bedingt Browseraktualisierung und Status der "Lampen"
+ { fhem "trigger $device on" }
+
+ # Logausgabe
+ $logstr = "Camera $camname Recording stopped";
+ &printlog($hash,$logstr,"3");
+ }
+ else {
+ # die URL konnte nicht erfolgreich aufgerufen werden
+ # Errorcode aus JSON ermitteln
+ $errorcode = $data->{'error'}->{'code'};
+
+ # Fehlertext zum Errorcode ermitteln
+ my $error = &experror($hash,$errorcode);
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode",$errorcode);
+ readingsBulkUpdate($hash,"Error",$error);
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ my $logstr = "ERROR - Stop Recording Camera $camname not possible. Errorcode: $errorcode - $error";
+ &printlog($hash,$logstr,"1");
+ }
+
+ &serverlogout($hash,$sid);
+
+ # Logausgabe
+ $logstr = "--- End Function camstop ---";
+ &printlog($hash,$logstr,"5");
+
+return;
+}
+
+############################################################################
+#### Login auf SS Server und ermitteln _sid
+
+sub serverlogin {
+ my ($hash) = @_;
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $username = $hash->{USERNAME};
+ my $password = $hash->{PASSWORD};
+ my $apiauthpath = $hash->{APIAUTHPATH};
+ my $apiauthmaxver = $hash->{APIAUTHMAXVER};
+ my $sid = "";
+ my $logstr;
+ my $loginurl;
+ my $myjson;
+ my $success;
+ my $data;
+ my $errorcode;
+ my $error;
+
+
+ # Logausgabe
+ $logstr = "--- Begin Function serverlogin ---";
+ &printlog($hash,$logstr,"5");
+
+ $loginurl = "http://$servername:$serverport/webapi/$apiauthpath?api=SYNO.API.Auth&version=$apiauthmaxver&method=Login&account=$username&passwd=$password&session=SurveillanceStation&format=sid";
+ $myjson = get $loginurl;
+
+ # Evaluiere ob Daten im JSON-Format empfangen
+ ($hash, $success) = &evaljson($hash,$myjson,$loginurl);
+ unless ($success eq "true") {return($sid, $success)};
+
+ # Logausgabe
+ $logstr = "URL call: $loginurl";
+ &printlog($hash,$logstr,"4");
+ $logstr = "JSON response: $myjson";
+ &printlog($hash,$logstr,"4");
+
+ # die Response wird im JSON Format geliefert, Beispiel: {"data":{"sid":"zvJraLU.5Yg6E14A0MIN235902"},"success":true}
+ $data = decode_json($myjson);
+ $success = $data->{'success'};
+
+ # der login war erfolgreich
+ if ($success eq "true") {
+ $sid = $data->{'data'}->{'sid'};
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","none");
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "Login of User $username successful - SID: $sid";
+ &printlog($hash,$logstr,"5");
+ } else {
+ # Errorcode aus JSON ermitteln
+ $errorcode = $data->{'error'}->{'code'};
+
+ # Fehlertext zum Errorcode ermitteln
+ $error = &experrorauth($hash,$errorcode);
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode",$errorcode);
+ readingsBulkUpdate($hash,"Error",$error);
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "ERROR - Login of User $username unsuccessful. Errorcode: $errorcode - $error";
+ &printlog($hash,$logstr,"1");
+ }
+
+ # Logausgabe
+ $logstr = "--- End Function serverlogin ---";
+ &printlog($hash,$logstr,"5");
+
+return ($sid, $success);
+}
+
+
+############################################################################
+### Logout Session
+
+sub serverlogout {
+ # Übernahmewerte sind Session-id: $sid, $servername, $serverport
+ my ($hash,@sid) = @_;
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $apiauthpath = $hash->{APIAUTHPATH};
+ my $apiauthmaxver = $hash->{APIAUTHMAXVER};
+ my $username = $hash->{USERNAME};
+ my $sid = shift @sid;
+ my $logstr;
+ my $logouturl;
+ my $myjson;
+ my $success;
+ my $data;
+ my $errorcode;
+ my $error;
+
+
+ # Logausgabe
+ $logstr = "--- Begin Function serverlogout ---";
+ &printlog($hash,$logstr,"5");
+
+ $logouturl = "http://$servername:$serverport/webapi/$apiauthpath?api=SYNO.API.Auth&version=$apiauthmaxver&method=Logout&session=SurveillanceStation&_sid=$sid";
+ $myjson = get $logouturl;
+
+ # Evaluiere ob Daten im JSON-Format empfangen
+ ($hash, $success) = &evaljson($hash,$myjson,$logouturl);
+ unless ($success eq "true") {return};
+
+ # Logausgabe
+ $logstr = "URL call: $logouturl";
+ &printlog($hash,$logstr,"4");
+ $logstr = "JSON response: $myjson";
+ &printlog($hash,$logstr,"4");
+
+ # Response erfolgt im JSON Format der Art: {"success":true}
+ $data = decode_json($myjson);
+ $success = $data->{'success'};
+
+ if ($success eq "true") {
+ # die URL konnte erfolgreich aufgerufen werden
+
+ # Logausgabe
+ $logstr = "Session of User $username quit - SID: $sid.";
+ &printlog($hash,$logstr,"5");
+ } else {
+ # Errorcode aus JSON ermitteln
+ $errorcode = $data->{'error'}->{'code'};
+
+ # Fehlertext zum Errorcode ermitteln
+ $error = &experrorauth($hash,$errorcode);
+
+ # Logausgabe
+ $logstr = "ERROR - Logout of User $username was not successful. Errorcode: $errorcode - $error";
+ &printlog($hash,$logstr,"1");
+ }
+ # Logausgabe
+ $logstr = "--- End Function serverlogout ---";
+ &printlog($hash,$logstr,"5");
+
+return;
+}
+
+###############################################################################
+### Test ob JSON-String empfangen wurde
+
+sub evaljson {
+ my ($hash,$myjson,$url)= @_;
+ my $success = "true";
+ my $e;
+ my $logstr;
+
+ eval {decode_json($myjson);1;} or do
+ {
+ $success = "false";
+ $e = $@;
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","malformed JSON string received");
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "URL call: $url";
+ &printlog($hash,$logstr,"4");
+ $logstr = "Output eval: ERROR - $e";
+ &printlog($hash,$logstr,"3");
+ };
+return($hash,$success);
+}
+
+
+###############################################################################
+### Id für einen Kameranamen ermitteln
+
+sub getcamid {
+ # Übernahmewerte sind Session-id $sid, Kameraname: $camname, $servername, $serverport
+ my ($hash,@sid) = @_;
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $camname = $hash->{CAMNAME};
+ my $apicampath = $hash->{APICAMPATH};
+ my $apicammaxver = $hash->{APICAMMAXVER};
+ my $sid = shift @sid;
+ my $camid = "";
+ my $logstr;
+ my $url;
+ my $myjson;
+ my $success;
+ my $data;
+ my $camcount;
+ my $i;
+ my %allcams;
+ my $name;
+ my $id;
+ my $errorcode;
+ my $error;
+
+ # Logausgabe
+ $logstr = "--- Begin Function getcamid ---";
+ &printlog($hash,$logstr,"5");
+
+ # einlesen aller Kameras
+ $url = "http://$servername:$serverport/webapi/$apicampath?api=SYNO.SurveillanceStation.Camera&version=$apicammaxver&method=List&session=SurveillanceStation&_sid=$sid";
+ $myjson = get $url;
+
+ # Evaluiere ob Daten im JSON-Format empfangen
+ ($hash, $success) = &evaljson($hash,$myjson,$url);
+ unless ($success eq "true") {return($camid,$success)};
+
+ # Logausgabe
+ $logstr = "URL call: $url";
+ &printlog($hash,$logstr,"4");
+ # $logstr = "JSON response: $myjson";
+ # &printlog($hash,$logstr,"5");
+
+ # Response erfolgt im JSON Format der Art: {"success":true}
+ $data = decode_json($myjson);
+ $success = $data->{'success'};
+
+
+ if ($success eq "true") {
+ # die Liste aller Kameras konnte ausgelesen werden
+ # Anzahl der definierten Kameras ist in Var "total"
+ $camcount = $data->{'data'}->{'total'};
+
+ $i = 0;
+ # Namen aller installierten Kameras mit Id's in Hash (Assoziatives Array) einlesen
+ %allcams = ();
+ while ($i < $camcount) {
+ $name = $data->{'data'}->{'cameras'}->[$i]->{'name'};
+ $id = $data->{'data'}->{'cameras'}->[$i]->{'id'};
+ $allcams{"$name"} = "$id";
+ $i += 1;
+ }
+ # Ist der gesuchte Kameraname im Hash enhalten (in SS eingerichtet ?)
+ if (exists($allcams{$camname})) {
+ $camid = $allcams{$camname};
+ } else {
+ # Kameraname nicht gefunden, id = ""
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","Kamera(ID) nicht gefunden");
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "ERROR - Cameraname $camname wasn't found in Surveillance Station. Check Cameraname and Spelling.";
+ &printlog($hash,$logstr,"1");
+ $success = "false";
+ }
+ }
+ else {
+ # die Abfrage konnte nicht ausgeführt werden
+ # Errorcode aus JSON ermitteln
+ $errorcode = $data->{'error'}->{'code'};
+
+ # Fehlertext zum Errorcode ermitteln
+ $error = &experror($hash,$errorcode);
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode",$errorcode);
+ readingsBulkUpdate($hash,"Error",$error);
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "ERROR - ID of Camera $camname couldn't be selected. Errorcode: $errorcode - $error";
+ &printlog($hash,$logstr,"1");
+ }
+ # Logausgabe
+ $logstr = "--- End Function getcamid ---";
+ &printlog($hash,$logstr,"5");
+
+return ($camid,$success);
+}
+
+##############################################################################
+### Auflösung Errorcodes bei Login / Logout
+
+sub experrorauth {
+ # Übernahmewerte sind $hash, $errorcode
+ my ($hash,@errorcode) = @_;
+ my $device = $hash->{NAME};
+ my $errorcode = shift @errorcode;
+ my %errorlist;
+ my $error;
+
+ # Aufbau der Errorcode-Liste (siehe Surveillance_Station_Web_API_v2.0.pdf)
+ %errorlist = (
+ 100 => "Unknown error",
+ 101 => "The account parameter is not specified",
+ 102 => "API does not exist",
+ 400 => "Invalid user or password",
+ 401 => "Guest or disabled account",
+ 402 => "Permission denied",
+ 403 => "One time password not specified",
+ 404 => "One time password authenticate failed",
+ );
+ unless (exists ($errorlist {$errorcode})) {$error = "Meldung nicht gefunden. (bitte API-Guide konsultieren)"; return ($error);}
+
+ # Fehlertext aus Hash-Tabelle oben ermitteln
+ $error = $errorlist {$errorcode};
+return ($error);
+}
+
+##############################################################################
+### Auflösung Errorcodes SS API
+
+sub experror {
+ # Übernahmewerte sind $hash, $errorcode
+ my ($hash,@errorcode) = @_;
+ my $device = $hash->{NAME};
+ my $errorcode = shift @errorcode;
+ my %errorlist;
+ my $error;
+
+
+ # Aufbau der Errorcode-Liste (siehe Surveillance_Station_Web_API_v2.0.pdf)
+ %errorlist = (
+ 100 => "Unknown error",
+ 101 => "Invalid parameters",
+ 102 => "API does not exist",
+ 103 => "Method does not exist",
+ 104 => "This API version is not supporte",
+ 105 => "Insufficient user privilege",
+ 106 => "Connection time out",
+ 107 => "Multiple login detected",
+ 400 => "Execution failed",
+ 401 => "Parameter invalid",
+ 402 => "Camera disabled",
+ 403 => "Insufficient license",
+ 404 => "Codec acitvation failed",
+ 405 => "CMS server connection failed",
+ 407 => "CMS closed",
+ 410 => "Service is not enabled",
+ 412 => "Need to add license",
+ 413 => "Reach the maximum of platform",
+ 414 => "Some events not exist",
+ 415 => "message connect failed",
+ 417 => "Test Connection Error",
+ 418 => "Object is not exist / The VisualStation ID does not exist",
+ 419 => "Visualstation name repetition",
+ 439 => "Too many items selected",
+ );
+ unless (exists ($errorlist {$errorcode})) {$error = "Meldung nicht gefunden. (bitte API-Guide konsultieren)"; return ($error);}
+
+ # Fehlertext aus Hash-Tabelle oben ermitteln
+ $error = $errorlist {$errorcode};
+ return ($error);
+}
+
+############################################################################
+### Logausgabe
+
+sub printlog {
+ # Übernahmewerte ist $hash, $logstr, $verb (Verbose-Level)
+ my ($hash,$logstr,$verb)= @_;
+ my $name = $hash->{NAME};
+
+ Log3 ($name, $verb, "$name - $logstr");
+return;
+}
+
+############################################################################
+### ist die angegebene URL erreichbar ?
+
+sub validurl {
+ # Übernahmewerte ist $hash
+ my ($hash)= @_;
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $validurl = " ";
+ my $url;
+ my $logstr;
+
+ # Seite zum testen
+ $url = "http://$servername:$serverport";
+
+ # Logausgabe
+ $logstr = "--- Begin Function validurl ---";
+ &printlog($hash,$logstr,"5");
+
+ if (head($url)) {
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","none");
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "Site http://$servername:$serverport reachable";
+ &printlog($hash,$logstr,"5");
+ $validurl = "true";
+
+ } else {
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","Site http://$servername:$serverport not reachable");
+ readingsEndUpdate($hash, 1);
+
+ #Logausgabe
+ $logstr = "ERROR - Site http://$servername:$serverport not reachable. Check Servername / IP-Adresse and Port";
+ &printlog($hash,$logstr,"1");
+ $validurl = "false";
+ }
+
+ # Logausgabe
+ $logstr = "--- End Function validurl ---";
+ &printlog($hash,$logstr,"5");
+
+return($validurl);
+}
+
+############################################################################
+#### Ermittlung der Web API -Pfade und MaxVersionen
+
+sub getapisites {
+ # Übernahmewerte sind $servername, $serverport
+ my ($hash) = @_;
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $success = " ";
+ my $apiauth;
+ my $apiextrec;
+ my $apicam;
+ my $logstr;
+ my $url;
+ my $myjson;
+ my $data;
+ my $apiauthpath;
+ my $apiauthmaxver;
+ my $apiextrecpath;
+ my $apiextrecmaxver;
+ my $apicampath;
+ my $apicammaxver;
+ my $error;
+
+
+ # benötigte API-Pfade, in der Abfrage-Url an Parameter "&query=" mit Komma getrennt angeben
+ $apiauth = "SYNO.API.Auth";
+ $apiextrec = "SYNO.SurveillanceStation.ExternalRecording";
+ $apicam = "SYNO.SurveillanceStation.Camera";
+
+ # Logausgabe
+ $logstr = "--- Begin Function getapisites ---";
+ &printlog($hash,$logstr,"5");
+
+ # Abfrage der Eigenschaften von API SYNO.SurveillanceStation.ExternalRecording,$apicam
+ $url = "http://$servername:$serverport/webapi/query.cgi?api=SYNO.API.Info&method=Query&version=1&query=$apiauth,$apiextrec,$apicam";
+ $myjson = get $url;
+
+ # Evaluiere ob Daten im JSON-Format empfangen
+ ($hash, $success) = &evaljson($hash,$myjson,$url);
+ unless ($success eq "true") {return($hash,$success)};
+
+ # Logausgabe
+ $logstr = "URL call: $url";
+ &printlog($hash,$logstr,"4");
+ $logstr = "JSON response: $myjson";
+ &printlog($hash,$logstr,"4");
+
+ # Response erfolgt im JSON Format
+ $data = decode_json($myjson);
+ $success = $data->{'success'};
+
+
+ if ($success eq "true") {
+
+ # Pfad und Maxversion von "SYNO.API.Auth" ermitteln
+
+ $apiauthpath = $data->{'data'}->{$apiauth}->{'path'};
+ # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
+ $apiauthpath =~ tr/_//d;
+
+ # maximale Version ermitteln
+ $apiauthmaxver = $data->{'data'}->{$apiauth}->{'maxVersion'};
+
+ $logstr = "Path of $apiauth selected: $apiauthpath";
+ &printlog($hash, $logstr,"4");
+ $logstr = "MaxVersion of $apiauth selected: $apiauthmaxver";
+ &printlog($hash, $logstr,"4");
+
+ # Pfad und Maxversion von "SYNO.SurveillanceStation.ExternalRecording" ermitteln
+
+ $apiextrecpath = $data->{'data'}->{$apiextrec}->{'path'};
+ # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
+ $apiextrecpath =~ tr/_//d;
+
+ # maximale Version ermitteln
+ $apiextrecmaxver = $data->{'data'}->{$apiextrec}->{'maxVersion'};
+
+ $logstr = "Path of $apiextrec selected: $apiextrecpath";
+ &printlog($hash, $logstr,"4");
+ $logstr = "MaxVersion of $apiextrec selected: $apiextrecmaxver";
+ &printlog($hash, $logstr,"4");
+
+ # Pfad und Maxversion von "SYNO.SurveillanceStation.Camera" ermitteln
+
+ $apicampath = $data->{'data'}->{$apicam}->{'path'};
+ # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
+ $apicampath =~ tr/_//d;
+
+ # maximale Version ermitteln
+ $apicammaxver = $data->{'data'}->{$apicam}->{'maxVersion'};
+ # um 1 verringern - Fehlerprävention
+ if (defined $apicammaxver) {$apicammaxver -= 1};
+
+ $logstr = "Path of $apicam selected: $apicampath";
+ &printlog($hash, $logstr,"4");
+ $logstr = "MaxVersion of $apicam: $apicammaxver";
+ &printlog($hash, $logstr,"4");
+
+ # ermittelte Werte in $hash einfügen
+ $hash->{APIAUTHPATH} = $apiauthpath;
+ $hash->{APIAUTHMAXVER} = $apiauthmaxver;
+ $hash->{APIEXTRECPATH} = $apiextrecpath;
+ $hash->{APIEXTRECMAXVER} = $apiextrecmaxver;
+ $hash->{APICAMPATH} = $apicampath;
+ $hash->{APICAMMAXVER} = $apicammaxver;
+
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","none");
+ readingsEndUpdate($hash, 1);
+
+ } else {
+
+ # Fehlertext setzen
+ $error = "couldn't call API-Infosite";
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error",$error);
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "ERROR - the API-Query couldn't be executed successfully";
+ &printlog($hash,$logstr,"1");
+ }
+ # Logausgabe
+ $logstr = "--- End Function getapisites ---";
+ &printlog($hash,$logstr,"5");
+
+return($hash,$success);
+}
+
+
+
+1;
+
+=pod
+=begin html
+
+
+SSCam
+
+
+ Prerequisites
+ This module uses other CPAN-modules LWP and JSON. Consider to install these packages (Debian: libwww-perl, libjson-perl).
+ You also need to add an user in Synology DSM as member of Administrators group for using in this module.
+
+
+
+ Define
+
+
+
+ Set
+
+
+ There are two options for set.
+
+
+ "on" : triggers start of record.
+ "off" : triggers stop of record.
+
+
+
+
+
+
+ Attributes
+
+
+ Different Verbose-Level are supported.
+ Those are in detail:
+
+
+ 0 - Start/Stop-Event will be logged
+ 1 - Error messages will be logged
+ 3 - sended commands will be logged
+ 4 - sended and received informations will be logged
+ 5 - further outputs will be logged due to error-analyses
+
+
+
+
+ readingFnAttributes
+
+
+
+
+
+=end html
+=begin html_DE
+
+
+SSCam
+
+
+Vorbereitung
+ Dieses Modul nutzt weitere CPAN Module LWP und JSON. Bitte darauf achten diese Pakete zu installieren. (Debian: libwww-perl, libjson-perl).
+ Im DSM muß ebenfalls ein Nutzer als Mitglied der Administratorgruppe angelegt sein. Die Daten werden beim define des Gerätes benötigt.
+
+
+ Define
+
+
+
+ Set
+
+
+ Es gibt zwei Optionen für "Set".
+
+
+ "on" : startet die Aufnahme.
+ "off" : stoppt die Aufnahme.
+
+
+
+
+
+
+ Attributes
+
+
+ Es werden verschiedene Verbose-Level unterstützt.
+ Dies sind im Einzelnen:
+
+
+ 0 - Start/Stop-Ereignisse werden geloggt
+ 1 - Fehlermeldungen werden geloggt
+ 3 - gesendete Kommandos werden geloggt
+ 4 - gesendete und empfangene Daten werden geloggt
+ 5 - weitere Ausgaben zur Fehleranalyse werden geloggt
+
+
+
+
+ readingFnAttributes
+
+
+
+
+=end html_DE
+=cut
+