From f6ac1486885d4c2efa46e5c4c6218f8c942486d3 Mon Sep 17 00:00:00 2001
From: nasseeder1 <>
Date: Sun, 20 Dec 2015 07:44:08 +0000
Subject: [PATCH] 49_SSCam: function "snap" for taking snapshots added, fixed a
bug that functions may impact each other
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@10210 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
CHANGED | 2 +
FHEM/49_SSCam.pm | 670 +++++++++++++++++++++++++++++++----------------
2 files changed, 449 insertions(+), 223 deletions(-)
diff --git a/CHANGED b/CHANGED
index 01ad20428..68e221fc9 100644
--- a/CHANGED
+++ b/CHANGED
@@ -1,5 +1,7 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
+ - feature: 49_SSCam: function "snap" for taking snapshots added,
+ - bugfix: 49_SSCam: fixed a bug that functions may impact each other
- feature: 31_MilightDevice: Add restoreAtStart attribute so group devices (slot 'A') do not restore state by default at startup
- bugfix: 30_MilightBridge/31_MilightDevice: Fix startup restore. Fix crash on invalid hostname.
- feature: 30_pilight_xyz: possibility to change IO-Device (IODEV)
diff --git a/FHEM/49_SSCam.pm b/FHEM/49_SSCam.pm
index 9b90ea2d9..e40865775 100644
--- a/FHEM/49_SSCam.pm
+++ b/FHEM/49_SSCam.pm
@@ -4,7 +4,7 @@
# Copyright by Heiko Maaz
# e-mail: Heiko dot Maaz at t-online dot de
#
-# This Modul is used to manage Cameras defined in Synology Surveillance Station 7.0 or higher
+# This Modul is used to operate Cameras defined in Synology Surveillance Station 7.0 or higher
# It's based on Synology Surveillance Station API Guide 2.0
#
# This file is part of fhem.
@@ -25,6 +25,8 @@
######################################################################################################
# Versionshistorie:
#
+# 1.3 19.12.2015 function "snap" for taking snapshots added,
+# fixed a bug that functions may impact each other
# 1.2 14.12.2015 improve usage of verbose-modes
# 1.1 13.12.2015 use of InternalTimer instead of fhem(sleep)
# 1.0 12.12.2015 changed completly to HttpUtils_NonblockingGet for calling websites nonblocking,
@@ -54,9 +56,7 @@ use warnings;
use HttpUtils;
-sub
-SSCam_Initialize($)
-{
+sub SSCam_Initialize($) {
# die Namen der Funktionen, die das Modul implementiert und die fhem.pl aufrufen soll
my ($hash) = @_;
$hash->{DefFn} = "SSCam_Define";
@@ -68,7 +68,7 @@ SSCam_Initialize($)
$hash->{AttrList} =
"webCmd ".
$readingFnAttributes;
-
+
}
sub SSCam_Define {
@@ -105,11 +105,16 @@ sub SSCam_Define {
$hash->{RECTIME} = $rectime;
# benötigte API's in $hash einfügen
- $hash->{HELPER}{APIINFO} = "SYNO.API.Info"; # Info-Seite für alle API's, einzige statische Seite !
- $hash->{HELPER}{APIAUTH} = "SYNO.API.Auth";
- $hash->{HELPER}{APIEXTREC} = "SYNO.SurveillanceStation.ExternalRecording";
- $hash->{HELPER}{APICAM} = "SYNO.SurveillanceStation.Camera";
-
+ $hash->{HELPER}{APIINFO} = "SYNO.API.Info"; # Info-Seite für alle API's, einzige statische Seite !
+ $hash->{HELPER}{APIAUTH} = "SYNO.API.Auth";
+ $hash->{HELPER}{APIEXTREC} = "SYNO.SurveillanceStation.ExternalRecording";
+ $hash->{HELPER}{APICAM} = "SYNO.SurveillanceStation.Camera";
+ $hash->{HELPER}{APISNAPSHOT} = "SYNO.SurveillanceStation.SnapShot";
+
+ # Anfangswerte setzen
+ $hash->{HELPER}{ACTIVE} = "off";
+ readingsSingleUpdate($hash,"Record","Stop",0);
+
return undef;
}
@@ -126,64 +131,149 @@ sub SSCam_Attr {
sub SSCam_Set {
my ( $hash, @a ) = @_;
return "\"set X\" needs at least an argument" if ( @a < 2 );
- my $device = shift @a;
+ my $name = shift @a;
my $opt = shift @a;
my %SSCam_sets = (
- on => "on",
- off => "off");
- my $camname = $hash->{CAMNAME};
+ on => "on",
+ off => "off",
+ snap => "snap"
+ );
+
+ my $camname = $hash->{CAMNAME};
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")
- {
- $logstr = "Recording of Camera $camname should be started now";
- &printlog($hash,$logstr,"4");
-
- $hash->{OPMODE} = "Start";
- &getapisites_nonbl($hash);
- }
-
-
- # Aufnahme stoppen
- if ($opt eq "off")
- {
- $logstr = "Recording of Camera $camname should be stopped now";
- &printlog($hash,$logstr,"4");
-
- $hash->{OPMODE} = "Stop";
- &getapisites_nonbl($hash);
- }
+ if(!defined($SSCam_sets{$opt}))
+ {
+ @cList = keys %SSCam_sets;
+ return "Unknown argument $opt, choose one of " . join(" ", @cList);
+ }
+ else
+ {
+ if ($opt eq "on")
+ {
+ &camstartrec($hash);
+ }
+ elsif ($opt eq "off")
+ {
+ &camstoprec($hash);
+ }
+ elsif ($opt eq "snap")
+ {
+ &camsnap($hash);
+ }
}
}
+#############################################################################################################################
+######### OpMode-Startroutinen #############
+######### #############
+######### $hash->{HELPER}{ACTIVE} = "on" -> eine Routine läuft, Start anderer Routine erst wenn "off". #############
+######### $hash->{HELPER}{ACTIVE} = "off" -> keine andere Routine läuft, sofortiger Start möglich #############
+#############################################################################################################################
+
+###############################################################################
+### Kamera Aufnahme starten
+
+sub camstartrec ($) {
+ my ($hash) = @_;
+ my $camname = $hash->{CAMNAME};
+ my $name = $hash->{NAME};
+ my $logstr;
+
+ if ($hash->{HELPER}{ACTIVE} ne "on" and ReadingsVal("$name", "Record", "Start") ne "Start") {
+ # Aufnahme starten
+ $logstr = "Recording of Camera $camname should be started now";
+ &printlog($hash,$logstr,"4");
+
+ $hash->{OPMODE} = "Start";
+ $hash->{HELPER}{ACTIVE} = "on";
+
+ &getapisites_nonbl($hash);
+ }
+ else
+ {
+ InternalTimer(gettimeofday()+0.1, "camstartrec", $hash, 0);
+ }
+}
+
+###############################################################################
+### Kamera Aufnahme stoppen
+
+sub camstoprec ($) {
+ my ($hash) = @_;
+ my $camname = $hash->{CAMNAME};
+ my $name = $hash->{NAME};
+ my $logstr;
+
+ if ($hash->{HELPER}{ACTIVE} ne "on" and ReadingsVal("$name", "Record", "Stop") ne "Stop") {
+ # Aufnahme stoppen
+ $logstr = "Recording of Camera $camname should be stopped now";
+ &printlog($hash,$logstr,"4");
+
+ $hash->{OPMODE} = "Stop";
+ $hash->{HELPER}{ACTIVE} = "on";
+
+ &getapisites_nonbl($hash);
+ }
+ else
+ {
+ InternalTimer(gettimeofday()+0.1, "camstoprec", $hash, 0);
+ }
+}
+
+###############################################################################
+### Kamera Schappschuß aufnehmen
+
+sub camsnap ($) {
+ my ($hash) = @_;
+ my $camname = $hash->{CAMNAME};
+ my $name = $hash->{NAME};
+ my $logstr;
+
+ if ($hash->{HELPER}{ACTIVE} ne "on") {
+ # einen Schnappschuß aufnehmen
+ $logstr = "Take Snapshot of Camera $camname";
+ &printlog($hash,$logstr,"4");
+
+ $hash->{OPMODE} = "Snap";
+ $hash->{HELPER}{ACTIVE} = "on";
+
+ &getapisites_nonbl($hash);
+ }
+ else
+ {
+ InternalTimer(gettimeofday()+0.1, "camsnap", $hash, 0);
+ }
+}
+
+
+
#############################################################################################################################
####### Begin Kameraoperationen mit NonblockingGet (nicht blockierender HTTP-Call) #######
####### #######
####### Ablauflogik: #######
####### #######
+####### #######
+####### OpMode-Startroutine #######
+####### | #######
####### getapisites_nonbl -> login_nonbl -> getcamid_nonbl -> camop_nonbl -> camret_nonbl -> logout_nonbl #######
-####### | | #######
-####### Start Stop #######
+####### | #######
+####### OpMode #######
####### #######
#############################################################################################################################
sub getapisites_nonbl {
my ($hash) = @_;
- my $servername = $hash->{SERVERNAME};
- my $serverport = $hash->{SERVERPORT};
- my $apiinfo = $hash->{HELPER}{APIINFO}; # Info-Seite für alle API's, einzige statische Seite !
- my $apiauth = $hash->{HELPER}{APIAUTH}; # benötigte API-Pfade für Funktionen,
- my $apiextrec = $hash->{HELPER}{APIEXTREC}; # in der Abfrage-Url an Parameter "&query="
- my $apicam = $hash->{HELPER}{APICAM}; # mit Komma getrennt angeben
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $apiinfo = $hash->{HELPER}{APIINFO}; # Info-Seite für alle API's, einzige statische Seite !
+ my $apiauth = $hash->{HELPER}{APIAUTH}; # benötigte API-Pfade für Funktionen,
+ my $apiextrec = $hash->{HELPER}{APIEXTREC}; # in der Abfrage-Url an Parameter "&query="
+ my $apicam = $hash->{HELPER}{APICAM}; # mit Komma getrennt angeben
+ my $apitakesnap = $hash->{HELPER}{APISNAPSHOT};
my $logstr;
my $url;
my $param;
@@ -194,7 +284,7 @@ sub getapisites_nonbl {
&printlog($hash,$logstr,"4");
# URL zur Abfrage der Eigenschaften von API SYNO.SurveillanceStation.ExternalRecording,$apicam
- $url = "http://$servername:$serverport/webapi/query.cgi?api=$apiinfo&method=Query&version=1&query=$apiauth,$apiextrec,$apicam";
+ $url = "http://$servername:$serverport/webapi/query.cgi?api=$apiinfo&method=Query&version=1&query=$apiauth,$apiextrec,$apicam,$apitakesnap";
$param = {
url => $url,
@@ -216,15 +306,16 @@ sub getapisites_nonbl {
sub login_nonbl ($) {
my ($param, $err, $myjson) = @_;
- my $hash = $param->{hash};
- my $device = $hash->{NAME};
- my $servername = $hash->{SERVERNAME};
- my $serverport = $hash->{SERVERPORT};
- my $username = $hash->{USERNAME};
- my $password = $hash->{HELPER}{PASSWORD};
- my $apiauth = $hash->{HELPER}{APIAUTH};
- my $apiextrec = $hash->{HELPER}{APIEXTREC};
- my $apicam = $hash->{HELPER}{APICAM};
+ my $hash = $param->{hash};
+ my $device = $hash->{NAME};
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $username = $hash->{USERNAME};
+ my $password = $hash->{HELPER}{PASSWORD};
+ my $apiauth = $hash->{HELPER}{APIAUTH};
+ my $apiextrec = $hash->{HELPER}{APIEXTREC};
+ my $apicam = $hash->{HELPER}{APICAM};
+ my $apitakesnap = $hash->{HELPER}{APISNAPSHOT};
my $data;
my $logstr;
my $url;
@@ -235,6 +326,8 @@ sub login_nonbl ($) {
my $apiextrecmaxver;
my $apicampath;
my $apicammaxver;
+ my $apitakesnappath;
+ my $apitakesnapmaxver;
my $error;
# Verarbeitung der asynchronen Rückkehrdaten aus sub "getapisites_nonbl"
@@ -269,92 +362,100 @@ sub login_nonbl ($) {
$logstr = "JSON returned: ". Dumper $data;
&printlog($hash,$logstr,"4");
- # Pfad und Maxversion von "SYNO.API.Auth" ermitteln
+ # Pfad und Maxversion von "SYNO.API.Auth" ermitteln
- $apiauthpath = $data->{'data'}->{$apiauth}->{'path'};
- # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
- $apiauthpath =~ tr/_//d;
+ $apiauthpath = $data->{'data'}->{$apiauth}->{'path'};
+ # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
+ $apiauthpath =~ tr/_//d;
+ $apiauthmaxver = $data->{'data'}->{$apiauth}->{'maxVersion'};
- # 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");
- $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
- # Pfad und Maxversion von "SYNO.SurveillanceStation.ExternalRecording" ermitteln
+ $apiextrecpath = $data->{'data'}->{$apiextrec}->{'path'};
+ # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
+ $apiextrecpath =~ tr/_//d;
+ $apiextrecmaxver = $data->{'data'}->{$apiextrec}->{'maxVersion'};
- $apiextrecpath = $data->{'data'}->{$apiextrec}->{'path'};
- # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
- $apiextrecpath =~ tr/_//d;
+ $logstr = "Path of $apiextrec selected: $apiextrecpath";
+ &printlog($hash, $logstr,"4");
+ $logstr = "MaxVersion of $apiextrec selected: $apiextrecmaxver";
+ &printlog($hash, $logstr,"4");
- # maximale Version ermitteln
- $apiextrecmaxver = $data->{'data'}->{$apiextrec}->{'maxVersion'};
+ # Pfad und Maxversion von "SYNO.SurveillanceStation.Camera" ermitteln
+
+ $apicampath = $data->{'data'}->{$apicam}->{'path'};
+ # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
+ $apicampath =~ tr/_//d;
+ $apicammaxver = $data->{'data'}->{$apicam}->{'maxVersion'};
+ # um 1 verringern - Fehlerprävention
+ if (defined $apicammaxver) {$apicammaxver -= 1};
- $logstr = "Path of $apiextrec selected: $apiextrecpath";
- &printlog($hash, $logstr,"4");
- $logstr = "MaxVersion of $apiextrec selected: $apiextrecmaxver";
- &printlog($hash, $logstr,"4");
+ $logstr = "Path of $apicam selected: $apicampath";
+ &printlog($hash, $logstr,"4");
+ $logstr = "MaxVersion of $apicam (optimized): $apicammaxver";
+ &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 (optimized): $apicammaxver";
- &printlog($hash, $logstr,"4");
-
- # ermittelte Werte in $hash einfügen
- $hash->{HELPER}{APIAUTHPATH} = $apiauthpath;
- $hash->{HELPER}{APIAUTHMAXVER} = $apiauthmaxver;
- $hash->{HELPER}{APIEXTRECPATH} = $apiextrecpath;
- $hash->{HELPER}{APIEXTRECMAXVER} = $apiextrecmaxver;
- $hash->{HELPER}{APICAMPATH} = $apicampath;
- $hash->{HELPER}{APICAMMAXVER} = $apicammaxver;
-
-
- # Setreading
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash,"Errorcode","none");
- readingsBulkUpdate($hash,"Error","none");
- readingsEndUpdate($hash,1);
-
- # Logausgabe
- $logstr = "--- End Function getapisites nonblocking ---";
- &printlog($hash,$logstr,"4");
-
- }
- else
- {
-
- # Fehlertext setzen
- $error = "couldn't call API-Infosite";
-
- # Setreading
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash,"Errorcode","none");
- readingsBulkUpdate($hash,"Error",$error);
- readingsEndUpdate($hash, 1);
+ # Pfad und Maxversion von "SYNO.SurveillanceStation.SnapShot" ermitteln
+
+ $apitakesnappath = $data->{'data'}->{$apitakesnap}->{'path'};
+ # Unterstriche im Ergebnis z.B. "_______entry.cgi" eleminieren
+ $apitakesnappath =~ tr/_//d;
+ $apitakesnapmaxver = $data->{'data'}->{$apitakesnap}->{'maxVersion'};
+
+ $logstr = "Path of $apitakesnap selected: $apitakesnappath";
+ &printlog($hash, $logstr,"4");
+ $logstr = "MaxVersion of $apitakesnap: $apitakesnapmaxver";
+ &printlog($hash, $logstr,"4");
- # Logausgabe
- $logstr = "ERROR - the API-Query couldn't be executed successfully";
- &printlog($hash,$logstr,"1");
-
- $logstr = "--- End Function getapisites nonblocking with error ---";
- &printlog($hash,$logstr,"4");
- return;
- }
-
-
+
+ # ermittelte Werte in $hash einfügen
+ $hash->{HELPER}{APIAUTHPATH} = $apiauthpath;
+ $hash->{HELPER}{APIAUTHMAXVER} = $apiauthmaxver;
+ $hash->{HELPER}{APIEXTRECPATH} = $apiextrecpath;
+ $hash->{HELPER}{APIEXTRECMAXVER} = $apiextrecmaxver;
+ $hash->{HELPER}{APICAMPATH} = $apicampath;
+ $hash->{HELPER}{APICAMMAXVER} = $apicammaxver;
+ $hash->{HELPER}{APITAKESNAPPATH} = $apitakesnappath;
+ $hash->{HELPER}{APITAKESNAPMAXVER} = $apitakesnapmaxver;
+
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","none");
+ readingsEndUpdate($hash,1);
+ # Logausgabe
+ $logstr = "--- End Function getapisites nonblocking ---";
+ &printlog($hash,$logstr,"4");
+ }
+ else
+ {
+ # ausgeführte Funktion ist erledigt
+ $hash->{HELPER}{ACTIVE} = "off";
+
+ # 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");
+
+ $logstr = "--- End Function getapisites nonblocking with error ---";
+ &printlog($hash,$logstr,"4");
+ return;
+ }
}
# Login und SID ermitteln
@@ -455,6 +556,9 @@ sub getcamid_nonbl ($) {
}
else
{
+ # ausgeführte Funktion ist erledigt
+ $hash->{HELPER}{ACTIVE} = "off";
+
# Errorcode aus JSON ermitteln
$errorcode = $data->{'error'}->{'code'};
@@ -507,15 +611,18 @@ sub getcamid_nonbl ($) {
sub camop_nonbl ($) {
my ($param, $err, $myjson) = @_;
- my $hash = $param->{hash};
- my $servername = $hash->{SERVERNAME};
- my $serverport = $hash->{SERVERPORT};
- my $camname = $hash->{CAMNAME};
- my $apiextrec = $hash->{HELPER}{APIEXTREC};
- my $apiextrecpath = $hash->{HELPER}{APIEXTRECPATH};
- my $apiextrecmaxver = $hash->{HELPER}{APIEXTRECMAXVER};
- my $sid = $hash->{HELPER}{SID};
- my $OpMode = $hash->{OPMODE};
+ my $hash = $param->{hash};
+ my $servername = $hash->{SERVERNAME};
+ my $serverport = $hash->{SERVERPORT};
+ my $camname = $hash->{CAMNAME};
+ my $apiextrec = $hash->{HELPER}{APIEXTREC};
+ my $apiextrecpath = $hash->{HELPER}{APIEXTRECPATH};
+ my $apiextrecmaxver = $hash->{HELPER}{APIEXTRECMAXVER};
+ my $apitakesnap = $hash->{HELPER}{APISNAPSHOT};
+ my $apitakesnappath = $hash->{HELPER}{APITAKESNAPPATH};
+ my $apitakesnapmaxver = $hash->{HELPER}{APITAKESNAPMAXVER};
+ my $sid = $hash->{HELPER}{SID};
+ my $OpMode = $hash->{OPMODE};
my $url;
my $camid;
my $data;
@@ -607,6 +714,9 @@ sub camop_nonbl ($) {
else
{
# die Abfrage konnte nicht ausgeführt werden
+ # ausgeführte Funktion ist erledigt
+ $hash->{HELPER}{ACTIVE} = "off";
+
# Errorcode aus JSON ermitteln
$errorcode = $data->{'error'}->{'code'};
@@ -641,6 +751,11 @@ sub camop_nonbl ($) {
# die Aufnahme wird gestoppt, Rückkehr wird mit "camret_nonbl" verarbeitet
$url = "http://$servername:$serverport/webapi/$apiextrecpath?api=$apiextrec&method=Record&version=$apiextrecmaxver&cameraId=$camid&action=stop&session=SurveillanceStation&_sid=\"$sid\"";
}
+ elsif ($OpMode eq "Snap")
+ {
+ # ein Schnappschuß wird gemacht und in SS gespeichert, Rückkehr wird mit "camret_nonbl" verarbeitet
+ $url = "http://$servername:$serverport/webapi/$apitakesnappath?api=\"$apitakesnap\"&dsId=0&method=\"TakeSnapshot\"&version=\"$apitakesnapmaxver\"&camId=$camid&blSave=true&_sid=\"$sid\"";
+ }
$param = {
url => $url,
@@ -681,6 +796,7 @@ sub camret_nonbl ($) {
my $success;
my $error;
my $errorcode;
+ my $snapid;
# Verarbeitung der asynchronen Rückkehrdaten aus sub "camop_nonbl"
if ($err ne "") # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist
@@ -717,6 +833,7 @@ sub camret_nonbl ($) {
if ($OpMode eq "Start")
{
+ # bedingt Browseraktualisierung und Status der "Lampen"
$hash->{STATE} = "on";
# Setreading
@@ -725,30 +842,25 @@ sub camret_nonbl ($) {
readingsBulkUpdate($hash,"Errorcode","none");
readingsBulkUpdate($hash,"Error","none");
readingsEndUpdate($hash, 1);
-
+
# Logausgabe
$logstr = "Camera $camname with Recordtime $rectime"."s started";
&printlog($hash,$logstr,"3");
$logstr = "--- End Function cam: $OpMode nonblocking ---";
&printlog($hash,$logstr,"4");
- # Generiert das Ereignis "on", bedingt Browseraktualisierung und Status der "Lampen" wenn kein longpoll=1
- # { fhem "trigger $device on" }
-
# Logausgabe
$logstr = "Time for Recording is set to: $rectime";
&printlog($hash,$logstr,"4");
- # Stop der Aufnahme wird eingeleitet
- $logstr = "Recording of Camera $camname should be stopped in $rectime seconds";
- &printlog($hash,$logstr,"4");
- $hash->{OPMODE} = "Stop";
- InternalTimer(gettimeofday()+$rectime, "getapisites_nonbl", $hash, 0);
+ # Stop der Aufnahme nach Ablauf $rectime
+ InternalTimer(gettimeofday()+$rectime, "camstoprec", $hash, 0);
}
elsif ($OpMode eq "Stop")
{
+ # bedingt Browseraktualisierung und Status der "Lampen"
$hash->{STATE} = "off";
# Setreading
@@ -769,6 +881,25 @@ sub camret_nonbl ($) {
$logstr = "--- End Function cam: $OpMode nonblocking ---";
&printlog($hash,$logstr,"4");
}
+ elsif ($OpMode eq "Snap")
+ {
+ # ein Schnapschuß wurde aufgenommen
+
+ $snapid = $data->{data}{'id'};
+
+ # Setreading
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Errorcode","none");
+ readingsBulkUpdate($hash,"Error","none");
+ readingsBulkUpdate($hash,"LastSnapId",$snapid);
+ readingsEndUpdate($hash, 1);
+
+ # Logausgabe
+ $logstr = "Snapshot of Camera $camname has been done successfully";
+ &printlog($hash,$logstr,"3");
+ $logstr = "--- End Function cam: $OpMode nonblocking ---";
+ &printlog($hash,$logstr,"4");
+ }
}
else
{
@@ -790,6 +921,10 @@ sub camret_nonbl ($) {
&printlog($hash,$logstr,"1");
$logstr = "--- End Function cam: $OpMode nonblocking with error ---";
&printlog($hash,$logstr,"4");
+
+ # ausgeführte Funktion ist erledigt
+ $hash->{HELPER}{ACTIVE} = "off";
+
return;
}
@@ -829,7 +964,9 @@ sub logout_nonbl ($) {
my $error;
my $errorcode;
- # Verarbeitung der asynchronen Rückkehrdaten aus sub "camop_nonbl"
+ # ausgeführte Funktion ist erledigt
+ $hash->{HELPER}{ACTIVE} = "off";
+
if($err ne "") # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist
{
$logstr = "error while requesting ".$param->{url}." - $err";
@@ -843,7 +980,7 @@ sub logout_nonbl ($) {
{
$logstr = "URL-Call: ".$param->{url};
&printlog($hash,$logstr,"4");
-
+
# An dieser Stelle die Antwort parsen / verarbeiten mit $myjson
# Evaluiere ob Daten im JSON-Format empfangen wurden
@@ -984,7 +1121,7 @@ sub experror {
414 => "Some events not exist",
415 => "message connect failed",
417 => "Test Connection Error",
- 418 => "Object is not exist / The VisualStation ID does not exist",
+ 418 => "Object is not exist",
419 => "Visualstation name repetition",
439 => "Too many items selected",
);
@@ -1017,36 +1154,44 @@ return;
SSCam
- Using this Modul you are able to start and stop recordings of cameras which are defined in Synology Surveillance Station.
- The recordings are stored in Synology Surveillance Station and are managed like the other (normal) recordings defined by Surveillance Station rules.
+ Using this Module you are able to operate with cameras which are defined in Synology Surveillance Station.
+ At present the following functions are available:
+
+ - Start a Rocording
+ - Stop a Recording
+ - Trigger a Snapshot
+
+ The recordings and snapshots will be stored in Synology Surveillance Station and are managed like the other (normal) recordings / snapshots defined by Surveillance Station rules.
For example the recordings are stored for a defined time in Surveillance Station and will be deleted after that period.
Prerequisites
- This module uses the CPAN-module JSON. Consider to install these package (Debian: libjson-perl).
- You don't need to install LWP anymore, because of SSCam is now completely using the nonblocking functions of HttpUtils respectively HttpUtils_NonblockingGet.
+ This module uses the CPAN-module JSON. Please consider to install this package (Debian: libjson-perl).
+ You don't need to install LWP anymore, because of SSCam is completely using the nonblocking functions of HttpUtils respectively HttpUtils_NonblockingGet now.
You also need to add an user in Synology DSM as member of Administrators group for using in this module.
Define
+
define <name> SSCam <Servername> <Port> <Username> <Password> <Cameraname> <RecordTime>
Defines a new camera device for SSCam. At first the devices have to be set up and operable in Synology Surveillance Station 7.0 and above.
- The parameter "RecordTime" describes the minimum Recordtime. Dependend on other factors like the performance of you Synology Diskstation and
+ The parameter <RecordTime> describes the minimum Recordtime. Dependend on other factors like the performance of your Synology Diskstation and
Surveillance Station the effective Recordtime could be longer.
The Modul SSCam ist based on functions of Synology Surveillance Station API.
Please refer the Web API Guide.
- At present only HTTP-Protokoll is supported to call Synology DS.
+ At present only HTTP-protocol is supported to call Synology DS.
The parameters are in detail:
+
name : | the name of the new device to use in FHEM |
Servername : | the name or IP-address of Synology Surveillance Station Host. If Servername is used, make sure the name can be discovered in network by DNS |
Port : | the Port Synology surveillance Station Host, normally 5000 (HTTP only) |
@@ -1058,43 +1203,80 @@ return;
- Examples:
+ Examples:
define CamDoor SSCAM ds1.myds.ds 5000 apiuser apipass Door 10
-
- Set
+
+
+
+Set
- There are two options for set.
-
- "on" : starts a recording. The recording will be stopped after the period given by the value of <RecordTime> in device definition.
-
- Command: set <name> on
-
- "off" : stops a running recording manually or other event (for example by using at, notify or others).
-
- Command: set <name> off
-
+ There are the following options for "Set" at present:
+
+
+
+ "on": | starts a recording. The recording will be stopped automatically after a period of <RecordTime> as determined |
+ "off" : | stopps a running recording manually or using other events (e.g. with at, notify) |
+ "snap": | triggers a snapshot of the relevant camera and store it into Synology Surveillance Station |
+
+
+
+ Example for simple Start/Stop of Recording:
+
+
+
+ set <name> on | starts a recording of camera <name>, stops automatically after the time <RecordTime> as determined in device-definition |
+ set <name> off | stops the recording of camera <name> |
+
+
+
+ A snapshot can be triggered with:
+
+ set <name> snap
+
+
+ Subsequent some Examples for taking snapshots:
+
+ If a serial of snapshots should be released, it can be done using the following notify command.
+ For the example a serial of snapshots are to be triggerd if the recording of a camera starts.
+ When the recording of camera "CamHE1" starts (Attribut event-on-change-reading -> "Record" has to be set), then 3 snapshots at intervals of 2 seconds are triggered.
+
+
+ define he1_snap_3 notify CamHE1:Record.*Start define h3 at +*{3}00:00:02 set CamHE1 snap
+
+
+ Release of 2 Snapshots of camera "CamHE1" at intervals of 6 seconds after the motion sensor "MelderHE1" has sent an event,
+ can be done e.g. with following notify-command:
+
+
+ define he1_snap_2 notify MelderHE1:on.* define h2 at +*{2}00:00:06 set CamHE1 snap
+
+
+ The ID of the last snapshot will be displayed as value of variable "LastSnapId" in the device-Readings.
-
- Attributes
+
+
+
+Attributes
Different Verbose-Level are supported.
- Those are in detail:
+ 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 - all outputs will be logged for error-analyses. Please use it carefully, a lot of data could be written into the logfile !
-
+
+
+ 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 | all outputs will be logged for error-analyses. Caution: a lot of data could be written into the logfile ! | |
+
@@ -1111,30 +1293,37 @@ return;
SSCam
- Mit diesem Modul kann die Aufnahme von in der Synology Surveillance Station definierten Kameras gestartet bzw. gestoppt werden.
+ Mit diesem Modul können Operationen von in der Synology Surveillance Station definierten Kameras ausgeführt werden.
+ Zur Zeit werden folgende Funktionen unterstützt:
+
+ - Start einer Aufnahme
+ - Stop einer Aufnahme
+ - Aufnehmen eines Schnappschusses und Ablage in der Synology Surveillance Station
+
Die Aufnahmen stehen in der Synology Surveillance Station zur Verfügung und unterliegen, wie jede andere Aufnahme, den in der Synology Surveillance Station eingestellten Regeln.
- So werden zum Beispiel die Aufnahmen entsprechend ihrer Archivierungsfrist gehalten und dann gelöscht.
+ So werden zum Beispiel die Aufnahmen entsprechend ihrer Archivierungsfrist gehalten und dann gelöscht.
+
Vorbereitung
Dieses Modul nutzt das CPAN Module JSON. Bitte darauf achten dieses Paket zu installieren. (Debian: libjson-perl).
Das CPAN-Modul LWP wird für SSCam nicht mehr benötigt. Das Modul verwendet für HTTP-Calls die nichtblockierenden Funktionen von HttpUtils bzw. HttpUtils_NonblockingGet.
- Im DSM muß ebenfalls ein Nutzer als Mitglied der Administratorgruppe angelegt sein. Die Daten werden beim define des Gerätes benötigt.
+ Im DSM muß ebenfalls ein Nutzer als Mitglied der Administratorgruppe angelegt sein. Die Daten werden bei der Definition des Gerätes benötigt.
-
- Define
+
+Define
+
define <name> SSCam <Servername> <Port> <Username> <Password> <Cameraname> <RecordTime>
Definiert eine neue Kamera für SSCam. Zunächst muß diese Kamera in der Synology Surveillance Station 7.0 oder höher eingebunden sein und entsprechend funktionieren.
- Der Parameter "RecordTime" beschreibt die Mindestaufnahmezeit. Abhängig von Faktoren wie Performance der Synology Diskstation und der Surveillance Station
+ Der Parameter "<RecordTime> beschreibt die Mindestaufnahmezeit. Abhängig von Faktoren wie Performance der Synology Diskstation und der Surveillance Station
kann die effektive Aufnahmezeit geringfügig länger sein.
Das Modul SSCam basiert auf Funktionen der Synology Surveillance Station API.
- Weitere Inforamtionen unter: Web API Guide.
+ Weitere Informationen unter: Web API Guide.
- Es müssen die Perl-Module LWP (Debian: libwww-perl) und JSON (Debian: libjson-perl) installiert sein.
Momentan wird nur das HTTP-Protokoll unterstützt um die Web-Services der Synology DS aufzurufen.
Die Parameter beschreiben im Einzelnen:
@@ -1142,56 +1331,91 @@ return;
- name : | der Name des neuen Gerätes in FHEM |
- Servername : | der Name oder die IP-Addresse des Synology Surveillance Station Host. Wenn der Servername benutzt wird ist sicherzustellen dass der Name im Netzwerk aufgelöst werden kann. |
- Port : | der Port des Synology Surveillance Station Host. Normalerweise ist das 5000 (nur HTTP) |
- Username : | Name des in der Diskstation definierten Nutzers. Er muß ein Mitglied der Admin-Gruppe sein |
- Password : | das Passwort des Nutzers |
- Cameraname : | Kameraname wie er in der Synology Surveillance Station angegeben ist. Leerzeichen im Namen sind nicht erlaubt ! |
- Recordtime : | die definierte Aufnahmezeit |
+
+ name: | der Name des neuen Gerätes in FHEM |
+ Servername: | der Name oder die IP-Addresse des Synology Surveillance Station Host. Wenn der Servername benutzt wird ist sicherzustellen dass der Name im Netzwerk aufgelöst werden kann. |
+ Port: | der Port des Synology Surveillance Station Host. Normalerweise ist das 5000 (nur HTTP) |
+ Username: | Name des in der Diskstation definierten Nutzers. Er muß ein Mitglied der Admin-Gruppe sein |
+ Password: | das Passwort des Nutzers |
+ Cameraname: | Kameraname wie er in der Synology Surveillance Station angegeben ist. Leerzeichen im Namen sind nicht erlaubt ! |
+ Recordtime: | die definierte Aufnahmezeit |
- Beispiel:
+ Beispiel:
define CamTür SSCAM ds1.myds.ds 5000 apiuser apipass Tür 10
-
- Set
-
-
- Es gibt zur Zeit zwei Optionen für "Set".
+
+
+Set
+
+ Es gibt zur Zeit folgende Optionen für "Set":
- "on" : startet eine Aufnahme. Die Aufnahme wird automatisch nach Ablauf der Zeit <RecordTime> gestoppt.
-
- Befehl: set <name> on
-
- "off" : stoppt eine laufende Aufnahme manuell oder durch die Nutzung anderer Events (z.B. durch at, notify oder andere)
-
- Befehl: set <name> off
-
+
+
+ "on": | startet eine Aufnahme. Die Aufnahme wird automatisch nach Ablauf der Zeit <RecordTime> gestoppt. |
+ "off" : | stoppt eine laufende Aufnahme manuell oder durch die Nutzung anderer Events (z.B. über at, notify) |
+ "snap": | löst einen Schnappschuß der entsprechenden Kamera aus und speichert ihn in der Synology Surveillance Station |
+
+
+
+ Beispiele für einfachen Start/Stop einer Aufnahme:
-
+
+
+ set <name> on | startet die Aufnahme der Kamera <name>, automatischer Stop der Aufnahme nach Ablauf der Zeit <RecordTime> wie im define angegeben |
+ set <name> off | stoppt die Aufnahme der Kamera <name> |
+
-
- Attributes
+ Ein Schnappschuß kann ausgelöst werden durch:
+
+ set <name> snap
+
+
+ Nachfolgend einige Beispiele für die Auslösung von Schnappschüssen.
+
+ Soll eine Reihe von Schnappschüssen ausgelöst werden wenn eine Aufnahme startet, kann das z.B. durch folgendes notify geschehen.
+ Sobald der Start der Kamera CamHE1 ausgelöst wird (Attribut event-on-change-reading -> "Record" setzen), werden abhängig davon 3 Snapshots im Abstand von 2 Sekunden getriggert.
+
+
+ define he1_snap_3 notify CamHE1:Record.*Start define h3 at +*{3}00:00:02 set CamHE1 snap
+
+
+ Triggern von 2 Schnappschüssen der Kamera "CamHE1" im Abstand von 6 Sekunden nachdem der Bewegungsmelder "MelderHE1" einen Event gesendet hat,
+ kann z.B. mit folgendem notify geschehen:
+
+
+ define he1_snap_2 notify MelderHE1:on.* define h2 at +*{2}00:00:06 set CamHE1 snap
+
+
+ Es wird die ID des letzten Snapshots als Wert der Variable "LastSnapId" in den Readings der Kamera ausgegeben.
+
+
+
+
+
+
+
+Attributes
Es werden verschiedene Verbose-Level unterstützt.
- Dies sind im Einzelnen:
+ 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 - alle Ausgaben zur Fehleranalyse werden geloggt. ACHTUNG: unter Umständen sehr viele Daten im Logfile !
-
+
+
+ 0 | Start/Stop-Ereignisse werden geloggt |
+ 1 | Fehlermeldungen werden geloggt |
+ 3 | gesendete Kommandos werden geloggt |
+ 4 | gesendete und empfangene Daten werden geloggt |
+ 5 | alle Ausgaben zur Fehleranalyse werden geloggt. ACHTUNG: möglicherweise werden sehr viele Daten in das Logfile geschrieben! |
+