diff --git a/fhem/CHANGED b/fhem/CHANGED
index 491f497f2..9f018b1c5 100644
--- a/fhem/CHANGED
+++ b/fhem/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: V2.6.1, new commands snapGallery, createSnapGallery and
+ corresponding attributes
- feature: 34_ESPEasy.pm: plugin neopixelfx/nfx added (Forum #73949)
- new: 31_Nello: first release
- feature: 01_FHEMWEB.pm: add webCmdLabel (Forum #72581)
diff --git a/fhem/FHEM/49_SSCam.pm b/fhem/FHEM/49_SSCam.pm
index aa65987b3..b849a5e47 100644
--- a/fhem/FHEM/49_SSCam.pm
+++ b/fhem/FHEM/49_SSCam.pm
@@ -27,6 +27,15 @@
#########################################################################################################################
# Versions History:
#
+# 2.6.1 07.08.2017 some changes in composegallery if createSnapGallery used, room Snapshots changed to SnapGalllery
+# commandref revised
+# 2.6.0 06.08.2017 new command createSnapGallery
+# 2.5.4 05.08.2017 analyze $hash->{CL} in SetFn bzw. GetFn, set snapGallery only if snapGalleryBoost=1 is set,
+# some snapGallery improvements and fixes
+# 2.5.3 02.08.2017 implement snapGallery as set-command
+# 2.5.2 01.08.2017 get snapGallery with or without snapGalleryBoost (some more attributes for snapGallery)
+# 2.5.1 31.07.2017 sub composegallery (no polling necessary)
+# 2.5.0 31.07.2017 logtext revised, new get snapGallery command
# 2.4.1 29.07.2017 fix behavior of state when starting lastsnap_fw, fix "uninitialized value in pattern match (m//)
# at ./FHEM/49_SSCam.pm line 2895"
# 2.4.0 28.07.2017 new set command runView lastsnap_fw, commandref revised, minor fixes
@@ -178,7 +187,7 @@ use Time::HiRes;
use HttpUtils;
# no if $] >= 5.017011, warnings => 'experimental';
-my $SSCamVersion = "2.4.1";
+my $SSCamVersion = "2.6.1";
# Aufbau Errorcode-Hashes (siehe Surveillance Station Web API)
my %SSCam_errauthlist = (
@@ -223,6 +232,10 @@ my %SSCam_errlist = (
600 => "Presetname and PresetID not found in Hash",
);
+# Standardvariablen
+my $SSCam_slim = 3; # default Anzahl der abzurufenden Schnappschüsse mit snapGallery
+my $SSCAM_snum = "1,2,3,4,5,6,7,8,9,10"; # mögliche Anzahl der abzurufenden Schnappschüsse mit snapGallery
+
sub SSCam_Initialize($) {
my ($hash) = @_;
$hash->{DefFn} = "SSCam_Define";
@@ -244,6 +257,11 @@ sub SSCam_Initialize($) {
"loginRetries:1,2,3,4,5,6,7,8,9,10 ".
"videofolderMap ".
"pollcaminfoall ".
+ "snapGalleryBoost:0,1 ".
+ "snapGallerySize:Icon,Full ".
+ "snapGalleryNumber:$SSCAM_snum ".
+ "snapGalleryColumns ".
+ "snapGalleryHtmlAttr ".
"pollnologging:1,0 ".
"debugactivetoken:1 ".
"rectime ".
@@ -335,6 +353,10 @@ sub SSCam_Delete {
# gespeicherte Credentials löschen
setKeyValue($index, undef);
+
+ # löschen snapGallerie-Device falls vorhanden
+ my $sgdev = "SSCam.$hash->{NAME}.snapgallery";
+ CommandDelete($hash->{CL},"$sgdev");
return undef;
}
@@ -372,7 +394,72 @@ sub SSCam_Attr {
delete($defs{$name}{READINGS}{StmKeyUnicst}) if ($defs{$name}{READINGS}{StmKeyUnicst});
delete($defs{$name}{READINGS}{LiveStreamUrl}) if ($defs{$name}{READINGS}{LiveStreamUrl});
}
- }
+ }
+
+ if ($aName eq "snapGallerySize") {
+ if($cmd eq "set") {
+ $do = ($aVal eq "Icon")?1:2;
+ }
+ $do = 0 if($cmd eq "del");
+
+ if ($do == 0) {
+ delete($hash->{HELPER}{SNAPHASH}) if(AttrVal($name,"snapGalleryBoost",0)); # Snaphash nur löschen wenn Snaps gepollt werden
+ Log3($name, 4, "$name - Snapshot hash deleted");
+ } elsif (AttrVal($name,"snapGalleryBoost",0)) {
+ # snap-Infos abhängig ermitteln wenn gepollt werden soll
+ my ($slim,$ssize);
+ $hash->{HELPER}{GETSNAPGALLERY} = 1;
+ $slim = AttrVal($name,"snapGalleryNumber",$SSCam_slim); # Anzahl der abzurufenden Snaps
+ $ssize = $do;
+ RemoveInternalTimer($hash, "getsnapinfo");
+ InternalTimer(gettimeofday()+0.7, "getsnapinfo", "$name:$slim:$ssize", 0);
+ }
+ }
+
+ if ($aName eq "snapGalleryBoost") {
+ if($cmd eq "set") {
+ $do = ($aVal == 1)?1:0;
+ }
+ $do = 0 if($cmd eq "del");
+
+ if ($do == 0) {
+ delete($hash->{HELPER}{SNAPHASH}); # Snaphash löschen
+ Log3($name, 4, "$name - Snapshot hash deleted");
+
+ } else {
+ # snapgallery regelmäßig neu einlesen wenn Polling ein
+ return "When you want activate \"snapGalleryBoost\", you have to set the attribute \"pollcaminfoall\" first because the functionality depends on retrieving snapshots periodical."
+ if(!AttrVal($name,"pollcaminfoall",0));
+
+ my ($slim,$ssize);
+ $hash->{HELPER}{GETSNAPGALLERY} = 1;
+ $slim = AttrVal($name,"snapGalleryNumber",$SSCam_slim); # Anzahl der abzurufenden Snaps
+ my $sg = AttrVal($name,"snapGallerySize","Icon"); # Auflösung Image
+ $ssize = ($sg eq "Icon")?1:2;
+ RemoveInternalTimer($hash, "getsnapinfo");
+ InternalTimer(gettimeofday()+0.7, "getsnapinfo", "$name:$slim:$ssize", 0);
+ }
+ }
+
+ if ($aName eq "snapGalleryNumber" && AttrVal($name,"snapGalleryBoost",0)) {
+ my ($slim,$ssize);
+ if($cmd eq "set") {
+ $do = ($aVal != 0)?1:0;
+ }
+ $do = 0 if($cmd eq "del");
+
+ if ($do == 0) {
+ $slim = 3;
+ } else {
+ $slim = $aVal;
+ }
+
+ $hash->{HELPER}{GETSNAPGALLERY} = 1;
+ my $sg = AttrVal($name,"snapGallerySize","Icon"); # Auflösung Image
+ $ssize = ($sg eq "Icon")?1:2;
+ RemoveInternalTimer($hash, "getsnapinfo");
+ InternalTimer(gettimeofday()+0.7, "getsnapinfo", "$name:$slim:$ssize", 0);
+ }
if ($aName eq "simu_SVSversion") {
delete $hash->{HELPER}{APIPARSET};
@@ -380,16 +467,20 @@ sub SSCam_Attr {
}
if ($cmd eq "set") {
- if ($aName eq "pollcaminfoall") {
- unless ($aVal =~ /^\d+$/) { return " The Value for $aName is not valid. Use only figures 0-9 without decimal places !";}
- }
- if ($aName eq "rectime") {
- unless ($aVal =~ /^\d+$/) { return " The Value for $aName is not valid. Use only figures 0-9 without decimal places !";}
- }
- if ($aName eq "httptimeout") {
- unless ($aVal =~ /^[0-9]+$/) { return " The Value for $aName is not valid. Use only figures 1-9 !";}
- }
+ if ($aName =~ m/httptimeout|snapGalleryColumns|rectime|pollcaminfoall/ ) {
+ unless ($aVal =~ /^\d+$/) { return " The Value for $aName is not valid. Use only figures 1-9 !";}
+ }
}
+
+ if ($cmd eq "del") {
+ if ($aName =~ m/pollcaminfoall/ ) {
+ # Polling nicht ausschalten wenn snapGalleryBoost ein (regelmäßig neu einlesen)
+ return "Please switch off \"snapGalleryBoost\" first if you want to deactivate \"pollcaminfoall\" because the functionality of \"snapGalleryBoost\" depends on retrieving snapshots periodical."
+ if(AttrVal($name,"snapGalleryBoost",1));
+ }
+ }
+
+
return undef;
}
@@ -408,242 +499,258 @@ sub SSCam_Set {
my $setlist;
my @prop;
- $setlist = "Unknown argument $opt, choose one of ".
- "credentials ".
- "expmode:auto,day,night ".
- "on ".
- "off ".
- "motdetsc:disable,camera,SVS ".
- "snap ".
- "enable ".
- "disable ".
- "runView:live_fw,live_link,live_open,lastrec_fw,lastrec_open,lastsnap_fw ".
- "stopView:noArg ".
- "extevent:1,2,3,4,5,6,7,8,9,10 ".
- ((ReadingsVal("$name", "CapPTZPan", "false") ne "false") ? "runPatrol:".ReadingsVal("$name", "Patrols", "")." " : "").
- ((ReadingsVal("$name", "CapPTZPan", "false") ne "false") ? "goPreset:".ReadingsVal("$name", "Presets", "")." " : "").
- ((ReadingsVal("$name", "CapPTZAbs", "false")) ? "goAbsPTZ"." " : "").
- ((ReadingsVal("$name", "CapPTZDirections", "0") > 0) ? "move"." " : "");
+ return "module is deactivated" if(IsDisabled($name));
+
+ $setlist = "Unknown argument $opt, choose one of ".
+ "credentials ".
+ "expmode:auto,day,night ".
+ "on ".
+ "off ".
+ "motdetsc:disable,camera,SVS ".
+ "snap ".
+ (AttrVal($name, "snapGalleryBoost",0)?(AttrVal($name,"snapGalleryNumber",undef) || AttrVal($name,"snapGalleryBoost",0))?"snapGallery:noArg ":"snapGallery:$SSCAM_snum ":" ").
+ "createSnapGallery:noArg ".
+ "enable ".
+ "disable ".
+ "runView:live_fw,live_link,live_open,lastrec_fw,lastrec_open,lastsnap_fw ".
+ "stopView:noArg ".
+ "extevent:1,2,3,4,5,6,7,8,9,10 ".
+ ((ReadingsVal("$name", "CapPTZPan", "false") ne "false") ? "runPatrol:".ReadingsVal("$name", "Patrols", "")." " : "").
+ ((ReadingsVal("$name", "CapPTZPan", "false") ne "false") ? "goPreset:".ReadingsVal("$name", "Presets", "")." " : "").
+ ((ReadingsVal("$name", "CapPTZAbs", "false")) ? "goAbsPTZ"." " : "").
+ ((ReadingsVal("$name", "CapPTZDirections", "0") > 0) ? "move"." " : "");
-
- if ($opt eq "on") {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ if (!$hash->{CREDENTIALS} && $opt ne "credentials") {
+ # sind die Credentials gesetzt ?
+ return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";
+
+ } elsif ($opt eq "on") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- if (defined($prop)) {
- unless ($prop =~ /^\d+$/) { return " The Value for \"$opt\" is not valid. Use only figures 0-9 without decimal places !";}
- $hash->{HELPER}{RECTIME_TEMP} = $prop;
- }
- camstartrec($hash);
+ if (defined($prop)) {
+ unless ($prop =~ /^\d+$/) { return " The Value for \"$opt\" is not valid. Use only figures 0-9 without decimal places !";}
+ $hash->{HELPER}{RECTIME_TEMP} = $prop;
+ }
+ camstartrec($hash);
- }
- elsif ($opt eq "off")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- camstoprec($hash);
- }
- elsif ($opt eq "snap")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- camsnap($hash);
- }
- elsif ($opt eq "enable")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- camenable($hash);
- }
- elsif ($opt eq "disable")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- camdisable($hash);
- }
- elsif ($opt eq "motdetsc")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- if (!$prop || $prop !~ /^(disable|camera|SVS)$/) { return " \"$opt\" needs one of those arguments: disable, camera, SVS !";}
+ } elsif ($opt eq "off") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ camstoprec($hash);
+
+ } elsif ($opt eq "snap") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ camsnap($hash);
+
+ } elsif ($opt eq "snapGallery") {
+ if(!AttrVal($name, "snapGalleryBoost",0)) {
+ # Snaphash ist nicht vorhanden und wird neu abgerufen und ausgegeben
+ if (defined($hash->{CL})) {
+ # Clienthash auflösen zur Fehlersuche (aufrufende FHEMWEB Instanz)
+ while (my ($key,$val) = each(%{$hash->{CL}})) {
+ $val = $val?$val:" ";
+ Log3($name, 4, "$name - snapGallery Clienthash: $key -> $val");
+ }
+ } else {
+ Log3($name, 2, "$name - snapGallery Clienthash wasn't delivered !");
+ return "Clienthash wasn't delivered. Can't use asynchronous output for snapGallery.";
+ }
+
+ $hash->{HELPER}{CL} = $hash->{CL};
+ $hash->{HELPER}{GETSNAPGALLERY} = 1;
+
+ # snap-Infos für Gallerie abrufen
+ my ($sg,$slim,$ssize);
+ $slim = $prop?AttrVal($name,"snapGalleryNumber",$prop):AttrVal($name,"snapGalleryNumber",$SSCam_slim); # Anzahl der abzurufenden Snapshots
+ $ssize = (AttrVal($name,"snapGallerySize","Icon") eq "Icon")?1:2; # Image Size 1-Icon, 2-Full
+
+ getsnapinfo("$name:$slim:$ssize");
+
+ } else {
+ # Snaphash ist vorhanden und wird zur Ausgabe aufbereitet
+ my $htmlCode = composegallery($name);
+ return $htmlCode;
+ }
+
+ } elsif ($opt eq "createSnapGallery") {
+ my ($ret,$sgdev);
+ return "When you want use \"$opt\", you have to set the attribute \"snapGalleryBoost\" first because the functionality depends on retrieving snapshots automatically."
+ if(!AttrVal($name,"snapGalleryBoost",0));
+ $sgdev = "SSCam.$name.snapgallery";
+ $ret = CommandDefine($hash->{CL},"$sgdev weblink htmlCode {composegallery('$name','$sgdev')}");
+ return $ret if($ret);
+ my $wlname = "SSCam.$name.snapgallery";
+ my $room = "SnapGallery";
+ CommandAttr($hash->{CL},$wlname." room ".$room);
+ return "Snapgallery device \"$sgdev\" was created successfully. Please have a look to room $room.
You can now assign it to another room if you want. Don't rename this new device ! ";
+
+ } elsif ($opt eq "enable") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ camenable($hash);
+
+ } elsif ($opt eq "disable") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ camdisable($hash);
+
+ } elsif ($opt eq "motdetsc") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ if (!$prop || $prop !~ /^(disable|camera|SVS)$/) { return " \"$opt\" needs one of those arguments: disable, camera, SVS !";}
- $hash->{HELPER}{MOTDETSC} = $prop;
+ $hash->{HELPER}{MOTDETSC} = $prop;
- if ($prop1) {
- # check ob Zahl zwischen 1 und 99
- return "invalid value for sensitivity (SVS or camera) - use number between 1 - 99" if ($prop1 !~ /^([1-9]|[1-9][0-9])*$/);
- $hash->{HELPER}{MOTDETSC_PROP1} = $prop1;
- }
- if ($prop2) {
- # check ob Zahl zwischen 1 und 99
- return "invalid value for threshold (SVS) / object size (camera) - use number between 1 - 99" if ($prop2 !~ /^([1-9]|[1-9][0-9])*$/);
- $hash->{HELPER}{MOTDETSC_PROP2} = $prop2;
- }
- if ($prop3) {
- # check ob Zahl zwischen 1 und 99
- return "invalid value for threshold (SVS) / object size (camera) - use number between 1 - 99" if ($prop3 !~ /^([1-9]|[1-9][0-9])*$/);
- $hash->{HELPER}{MOTDETSC_PROP3} = $prop3;
- }
- cammotdetsc($hash);
- }
- elsif ($opt eq "credentials")
- {
- return "module is deactivated" if(IsDisabled($name));
- return "Credentials are incomplete, use username password" if (!$prop || !$prop1);
- delete $hash->{HELPER}{SID} if($hash->{HELPER}{SID});
- ($success) = setcredentials($hash,$prop,$prop1);
- $hash->{HELPER}{ACTIVE} = "off";
- if($success) {
- getsvsinfo($hash);
- return "Username and Password saved successfully";
- } else {
- return "Error while saving Username / Password - see logfile for details";
- }
+ if ($prop1) {
+ # check ob Zahl zwischen 1 und 99
+ return "invalid value for sensitivity (SVS or camera) - use number between 1 - 99" if ($prop1 !~ /^([1-9]|[1-9][0-9])*$/);
+ $hash->{HELPER}{MOTDETSC_PROP1} = $prop1;
+ }
+ if ($prop2) {
+ # check ob Zahl zwischen 1 und 99
+ return "invalid value for threshold (SVS) / object size (camera) - use number between 1 - 99" if ($prop2 !~ /^([1-9]|[1-9][0-9])*$/);
+ $hash->{HELPER}{MOTDETSC_PROP2} = $prop2;
+ }
+ if ($prop3) {
+ # check ob Zahl zwischen 1 und 99
+ return "invalid value for threshold (SVS) / object size (camera) - use number between 1 - 99" if ($prop3 !~ /^([1-9]|[1-9][0-9])*$/);
+ $hash->{HELPER}{MOTDETSC_PROP3} = $prop3;
+ }
+ cammotdetsc($hash);
+
+ } elsif ($opt eq "credentials") {
+ return "Credentials are incomplete, use username password" if (!$prop || !$prop1);
+ delete $hash->{HELPER}{SID} if($hash->{HELPER}{SID});
+ ($success) = setcredentials($hash,$prop,$prop1);
+ $hash->{HELPER}{ACTIVE} = "off";
+
+ if($success) {
+ getsvsinfo($hash);
+ return "Username and Password saved successfully";
+ } else {
+ return "Error while saving Username / Password - see logfile for details";
+ }
- }
- elsif ($opt eq "expmode")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- unless ($prop) { return " \"$opt\" needs one of those arguments: auto, day, night !";}
+ } elsif ($opt eq "expmode") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ unless ($prop) { return " \"$opt\" needs one of those arguments: auto, day, night !";}
- $hash->{HELPER}{EXPMODE} = $prop;
- camexpmode($hash);
- }
- elsif ($opt eq "goPreset")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- if (!$prop) {return "Function \"goPreset\" needs a \"Presetname\" as an argument";}
+ $hash->{HELPER}{EXPMODE} = $prop;
+ camexpmode($hash);
+
+ } elsif ($opt eq "goPreset") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ if (!$prop) {return "Function \"goPreset\" needs a \"Presetname\" as an argument";}
- @prop = split(/;/, $prop);
- $prop = $prop[0];
- @prop = split(/,/, $prop);
- $prop = $prop[0];
- $hash->{HELPER}{GOPRESETNAME} = $prop;
- $hash->{HELPER}{PTZACTION} = "gopreset";
- doptzaction($hash);
- }
- elsif ($opt eq "runPatrol")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- if (!$prop) {return "Function \"runPatrol\" needs a \"Patrolname\" as an argument";}
+ @prop = split(/;/, $prop);
+ $prop = $prop[0];
+ @prop = split(/,/, $prop);
+ $prop = $prop[0];
+ $hash->{HELPER}{GOPRESETNAME} = $prop;
+ $hash->{HELPER}{PTZACTION} = "gopreset";
+ doptzaction($hash);
+
+ } elsif ($opt eq "runPatrol") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ if (!$prop) {return "Function \"runPatrol\" needs a \"Patrolname\" as an argument";}
- @prop = split(/;/, $prop);
- $prop = $prop[0];
- @prop = split(/,/, $prop);
- $prop = $prop[0];
- $hash->{HELPER}{GOPATROLNAME} = $prop;
- $hash->{HELPER}{PTZACTION} = "runpatrol";
- doptzaction($hash);
- }
- elsif ($opt eq "goAbsPTZ")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ @prop = split(/;/, $prop);
+ $prop = $prop[0];
+ @prop = split(/,/, $prop);
+ $prop = $prop[0];
+ $hash->{HELPER}{GOPATROLNAME} = $prop;
+ $hash->{HELPER}{PTZACTION} = "runpatrol";
+ doptzaction($hash);
+
+ } elsif ($opt eq "goAbsPTZ") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- if ($prop eq "up" || $prop eq "down" || $prop eq "left" || $prop eq "right") {
- if ($prop eq "up") {$hash->{HELPER}{GOPTZPOSX} = 320; $hash->{HELPER}{GOPTZPOSY} = 480;}
- if ($prop eq "down") {$hash->{HELPER}{GOPTZPOSX} = 320; $hash->{HELPER}{GOPTZPOSY} = 0;}
- if ($prop eq "left") {$hash->{HELPER}{GOPTZPOSX} = 0; $hash->{HELPER}{GOPTZPOSY} = 240;}
- if ($prop eq "right") {$hash->{HELPER}{GOPTZPOSX} = 640; $hash->{HELPER}{GOPTZPOSY} = 240;}
+ if ($prop eq "up" || $prop eq "down" || $prop eq "left" || $prop eq "right") {
+ if ($prop eq "up") {$hash->{HELPER}{GOPTZPOSX} = 320; $hash->{HELPER}{GOPTZPOSY} = 480;}
+ if ($prop eq "down") {$hash->{HELPER}{GOPTZPOSX} = 320; $hash->{HELPER}{GOPTZPOSY} = 0;}
+ if ($prop eq "left") {$hash->{HELPER}{GOPTZPOSX} = 0; $hash->{HELPER}{GOPTZPOSY} = 240;}
+ if ($prop eq "right") {$hash->{HELPER}{GOPTZPOSX} = 640; $hash->{HELPER}{GOPTZPOSY} = 240;}
- $hash->{HELPER}{PTZACTION} = "goabsptz";
- doptzaction($hash);
- return undef;
- }
- else
- {
- if ($prop !~ /\d+/ || $prop1 !~ /\d+/ || abs($prop) > 640 || abs($prop1) > 480) {
- return "Function \"goAbsPTZ\" needs two coordinates, posX=0-640 and posY=0-480, as arguments or use up, down, left, right instead";
- }
+ $hash->{HELPER}{PTZACTION} = "goabsptz";
+ doptzaction($hash);
+ return undef;
+
+ } else {
+ if ($prop !~ /\d+/ || $prop1 !~ /\d+/ || abs($prop) > 640 || abs($prop1) > 480) {
+ return "Function \"goAbsPTZ\" needs two coordinates, posX=0-640 and posY=0-480, as arguments or use up, down, left, right instead";
+ }
- $hash->{HELPER}{GOPTZPOSX} = abs($prop);
- $hash->{HELPER}{GOPTZPOSY} = abs($prop1);
+ $hash->{HELPER}{GOPTZPOSX} = abs($prop);
+ $hash->{HELPER}{GOPTZPOSY} = abs($prop1);
- $hash->{HELPER}{PTZACTION} = "goabsptz";
- doptzaction($hash);
+ $hash->{HELPER}{PTZACTION} = "goabsptz";
+ doptzaction($hash);
- return undef;
+ return undef;
- }
- return "Function \"goAbsPTZ\" needs two coordinates, posX=0-640 and posY=0-480, as arguments or use up, down, left, right instead";
+ }
+ return "Function \"goAbsPTZ\" needs two coordinates, posX=0-640 and posY=0-480, as arguments or use up, down, left, right instead";
- }
- elsif ($opt eq "move")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ } elsif ($opt eq "move") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- if (!defined($prop) || ($prop ne "up" && $prop ne "down" && $prop ne "left" && $prop ne "right" && $prop !~ m/dir_\d/)) {return "Function \"move\" needs an argument like up, down, left, right or dir_X (X = 0 to CapPTZDirections-1)";}
+ if (!defined($prop) || ($prop ne "up" && $prop ne "down" && $prop ne "left" && $prop ne "right" && $prop !~ m/dir_\d/)) {return "Function \"move\" needs an argument like up, down, left, right or dir_X (X = 0 to CapPTZDirections-1)";}
- $hash->{HELPER}{GOMOVEDIR} = $prop;
- $hash->{HELPER}{GOMOVETIME} = defined($prop1) ? $prop1 : 1;
+ $hash->{HELPER}{GOMOVEDIR} = $prop;
+ $hash->{HELPER}{GOMOVETIME} = defined($prop1) ? $prop1 : 1;
- $hash->{HELPER}{PTZACTION} = "movestart";
- doptzaction($hash);
- }
- elsif ($opt eq "runView")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ $hash->{HELPER}{PTZACTION} = "movestart";
+ doptzaction($hash);
+
+ } elsif ($opt eq "runView") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- if ($prop eq "live_open") {
- if ($prop1) {$hash->{HELPER}{VIEWOPENROOM} = $prop1;} else {delete $hash->{HELPER}{VIEWOPENROOM};}
- $hash->{HELPER}{OPENWINDOW} = 1;
- $hash->{HELPER}{WLTYPE} = "link";
- $hash->{HELPER}{ALIAS} = "LiveView";
- $hash->{HELPER}{RUNVIEW} = "live_open";
- } elsif ($prop eq "live_link") {
- $hash->{HELPER}{OPENWINDOW} = 0;
- $hash->{HELPER}{WLTYPE} = "link";
- $hash->{HELPER}{ALIAS} = "LiveView";
- $hash->{HELPER}{RUNVIEW} = "live_link";
- } elsif ($prop eq "lastrec_open") {
- if ($prop1) {$hash->{HELPER}{VIEWOPENROOM} = $prop1;} else {delete $hash->{HELPER}{VIEWOPENROOM};}
- $hash->{HELPER}{OPENWINDOW} = 1;
- $hash->{HELPER}{WLTYPE} = "link";
- $hash->{HELPER}{ALIAS} = "LastRecording";
- $hash->{HELPER}{RUNVIEW} = "lastrec_open";
- } elsif ($prop eq "lastrec_fw") {
- $hash->{HELPER}{OPENWINDOW} = 0;
- $hash->{HELPER}{WLTYPE} = "iframe";
- $hash->{HELPER}{ALIAS} = " ";
- $hash->{HELPER}{RUNVIEW} = "lastrec";
- } elsif ($prop eq "live_fw") {
- $hash->{HELPER}{OPENWINDOW} = 0;
- $hash->{HELPER}{WLTYPE} = "image";
- $hash->{HELPER}{ALIAS} = " ";
- $hash->{HELPER}{RUNVIEW} = "live_fw";
- } elsif ($prop eq "lastsnap_fw") {
- $hash->{HELPER}{OPENWINDOW} = 0;
- $hash->{HELPER}{WLTYPE} = "base64img";
- $hash->{HELPER}{ALIAS} = " ";
- $hash->{HELPER}{RUNVIEW} = "lastsnap_fw";
- } else {
- return "$prop isn't a valid option of runview, use one of live_fw, live_link, live_open, lastrec_fw, lastrec_open, lastsnap_fw";
- }
- runliveview($hash);
+ if ($prop eq "live_open") {
+ if ($prop1) {$hash->{HELPER}{VIEWOPENROOM} = $prop1;} else {delete $hash->{HELPER}{VIEWOPENROOM};}
+ $hash->{HELPER}{OPENWINDOW} = 1;
+ $hash->{HELPER}{WLTYPE} = "link";
+ $hash->{HELPER}{ALIAS} = "LiveView";
+ $hash->{HELPER}{RUNVIEW} = "live_open";
+ } elsif ($prop eq "live_link") {
+ $hash->{HELPER}{OPENWINDOW} = 0;
+ $hash->{HELPER}{WLTYPE} = "link";
+ $hash->{HELPER}{ALIAS} = "LiveView";
+ $hash->{HELPER}{RUNVIEW} = "live_link";
+ } elsif ($prop eq "lastrec_open") {
+ if ($prop1) {$hash->{HELPER}{VIEWOPENROOM} = $prop1;} else {delete $hash->{HELPER}{VIEWOPENROOM};}
+ $hash->{HELPER}{OPENWINDOW} = 1;
+ $hash->{HELPER}{WLTYPE} = "link";
+ $hash->{HELPER}{ALIAS} = "LastRecording";
+ $hash->{HELPER}{RUNVIEW} = "lastrec_open";
+ } elsif ($prop eq "lastrec_fw") {
+ $hash->{HELPER}{OPENWINDOW} = 0;
+ $hash->{HELPER}{WLTYPE} = "iframe";
+ $hash->{HELPER}{ALIAS} = " ";
+ $hash->{HELPER}{RUNVIEW} = "lastrec";
+ } elsif ($prop eq "live_fw") {
+ $hash->{HELPER}{OPENWINDOW} = 0;
+ $hash->{HELPER}{WLTYPE} = "image";
+ $hash->{HELPER}{ALIAS} = " ";
+ $hash->{HELPER}{RUNVIEW} = "live_fw";
+ } elsif ($prop eq "lastsnap_fw") {
+ $hash->{HELPER}{OPENWINDOW} = 0;
+ $hash->{HELPER}{WLTYPE} = "base64img";
+ $hash->{HELPER}{ALIAS} = " ";
+ $hash->{HELPER}{RUNVIEW} = "lastsnap_fw";
+ } else {
+ return "$prop isn't a valid option of runview, use one of live_fw, live_link, live_open, lastrec_fw, lastrec_open, lastsnap_fw";
+ }
+ runliveview($hash);
- }
- elsif ($opt eq "extevent")
- {
- return "module is deactivated" if(IsDisabled($name));
- if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ } elsif ($opt eq "extevent") {
+ if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- $hash->{HELPER}{EVENTID} = $prop;
- extevent($hash);
- }
- elsif ($opt eq "stopView")
- {
- return "module is deactivated" if(IsDisabled($name));
- stopliveview($hash);
- }
- else
- {
- return "$setlist";
- }
+ $hash->{HELPER}{EVENTID} = $prop;
+ extevent($hash);
+
+ } elsif ($opt eq "stopView") {
+ stopliveview($hash);
+
+ } else {
+ return "$setlist";
+ }
+
return;
}
@@ -653,9 +760,13 @@ sub SSCam_Get {
return "\"get X\" needs at least an argument" if ( @a < 2 );
my $name = shift @a;
my $opt = shift @a;
-
+ my $arg = shift @a;
+ my $ret = "";
+
my $getlist = "Unknown argument $opt, choose one of ".
"caminfoall:noArg ".
+ ((AttrVal($name,"snapGalleryNumber",undef) || AttrVal($name,"snapGalleryBoost",0))
+ ?"snapGallery:noArg ":"snapGallery:$SSCAM_snum ").
"snapinfo:noArg ".
"svsinfo:noArg ".
"snapfileinfo:noArg ".
@@ -677,8 +788,42 @@ sub SSCam_Get {
} elsif ($opt eq "svsinfo") {
getsvsinfo($hash);
+ } elsif ($opt eq "snapGallery") {
+ if(!AttrVal($name, "snapGalleryBoost",0)) {
+ # Snaphash ist nicht vorhanden und wird neu abgerufen und ausgegeben
+ if (defined($hash->{CL})) {
+ # Clienthash auflösen zur Fehlersuche (aufrufende FHEMWEB Instanz)
+ while (my ($key,$val) = each(%{$hash->{CL}})) {
+ $val = $val?$val:" ";
+ Log3($name, 4, "$name - snapGallery Clienthash: $key -> $val");
+ }
+ } else {
+ Log3($name, 2, "$name - snapGallery Clienthash wasn't delivered !");
+ return "Clienthash wasn't delivered. Can't use asynchronous output for snapGallery.";
+ }
+ return "Clienthash doesn't contain \"canAsyncOutput\" and therefore can't use asynchronous output for snapGallery. Please set attribute \"snapGalleryBoost=1\" if this error appears constantly."
+ if(!$hash->{CL}{canAsyncOutput});
+
+ $hash->{HELPER}{CL} = $hash->{CL};
+ $hash->{HELPER}{GETSNAPGALLERY} = 1;
+
+ # snap-Infos für Gallerie abrufen
+ my ($sg,$slim,$ssize);
+ $slim = $arg?AttrVal($name,"snapGalleryNumber",$arg):AttrVal($name,"snapGalleryNumber",$SSCam_slim); # Anzahl der abzurufenden Snapshots
+ $ssize = (AttrVal($name,"snapGallerySize","Icon") eq "Icon")?1:2; # Image Size 1-Icon, 2-Full
+
+ getsnapinfo("$name:$slim:$ssize");
+
+ } else {
+ # Snaphash ist vorhanden und wird zur Ausgabe aufbereitet
+ my $htmlCode = composegallery($name);
+ return $htmlCode;
+ }
+
} elsif ($opt eq "snapinfo") {
- getsnapinfo("$name:0:0");
+ # Schnappschußgalerie abrufen (snapGalleryBoost) oder nur Info des letzten Snaps
+ my ($slim,$ssize) = snaplimsize($hash);
+ getsnapinfo("$name:$slim:$ssize");
} elsif ($opt eq "snapfileinfo") {
if (!ReadingsVal("$name", "LastSnapId", undef)) {return "Reading LastSnapId is empty - please take a snapshot before !"}
@@ -700,7 +845,7 @@ sub SSCam_Get {
} else {
return "$getlist";
}
-return;
+return $ret; # not generate trigger out of command
}
######################################################################################
@@ -768,7 +913,11 @@ sub initonboot ($) {
getsvsinfo($hash);
# Kameraspezifische Infos holen
getcaminfo($hash);
- getsnapinfo("$name:0:0");
+
+ # Schnappschußgalerie abrufen (snapGalleryBoost) oder nur Info des letzten Snaps
+ my ($slim,$ssize) = snaplimsize($hash);
+ getsnapinfo("$name:$slim:$ssize");
+
getcapabilities($hash);
# Preset/Patrollisten in Hash einlesen zur PTZ-Steuerung
getptzlistpreset($hash);
@@ -1241,10 +1390,7 @@ sub runliveview ($) {
# Liveview starten
$hash->{OPMODE} = "runliveview";
$hash->{HELPER}{ACTIVE} = "on";
- $hash->{HELPER}{LOGINRETRIES} = 0;
- $hash->{HELPER}{SNAPLIMIT} = 1; # nur 1 Snap laden, für lastsnap_fw
- $hash->{HELPER}{SNAPIMGSIZE} = 2; # full size picture, für lastsnap_fw
- $hash->{HELPER}{KEYWORD} = $camname; # nur Snaps von $camname selektieren, für lastsnap_fw
+ $hash->{HELPER}{LOGINRETRIES} = 0;
# erzwingen die Camid zu ermitteln und bei login-Fehler neue SID zu holen
delete $hash->{CAMID};
@@ -1541,9 +1687,13 @@ sub getcaminfoall {
geteventlist($hash);
RemoveInternalTimer($hash, "getcaminfo");
InternalTimer(gettimeofday()+0.4, "getcaminfo", $hash, 0);
+
+ # Schnappschußgalerie abrufen (snapGalleryBoost) oder nur Info des letzten Snaps
+ my ($slim,$ssize) = snaplimsize($hash);
RemoveInternalTimer($hash, "getsnapinfo");
- InternalTimer(gettimeofday()+0.6, "getsnapinfo", "$name:0:0", 0);
- RemoveInternalTimer($hash, "getmotionenum");
+ InternalTimer(gettimeofday()+0.6, "getsnapinfo", "$name:$slim:$ssize", 0);
+
+ RemoveInternalTimer($hash, "getmotionenum");
InternalTimer(gettimeofday()+0.8, "getmotionenum", $hash, 0);
RemoveInternalTimer($hash, "getcapabilities");
InternalTimer(gettimeofday()+1.3, "getcapabilities", $hash, 0);
@@ -1582,7 +1732,7 @@ return;
}
###########################################################################
-# Infos zum letzten Snap abfragen (z.B. weil nicht über SSCam ausgelöst)
+# Infos zu Snaps abfragen (z.B. weil nicht über SSCam ausgelöst)
###########################################################################
sub getsnapinfo ($) {
my ($str) = @_;
@@ -1594,9 +1744,10 @@ sub getsnapinfo ($) {
if ($hash->{HELPER}{ACTIVE} eq "off") {
$hash->{OPMODE} = "getsnapinfo";
+ $hash->{OPMODE} = "getsnapgallery" if(exists($hash->{HELPER}{GETSNAPGALLERY}));
$hash->{HELPER}{ACTIVE} = "on";
$hash->{HELPER}{LOGINRETRIES} = 0;
- $hash->{HELPER}{SNAPLIMIT} = $slim; # alle Snapshots werden abgerufen und ausgewertet
+ $hash->{HELPER}{SNAPLIMIT} = $slim; # 0-alle Snapshots werden abgerufen und ausgewertet, sonst $slim
$hash->{HELPER}{SNAPIMGSIZE} = $ssize; # 0-Do not append image, 1-Icon size, 2-Full size
$hash->{HELPER}{KEYWORD} = $camname;
@@ -2450,11 +2601,12 @@ sub sscam_camop ($) {
readingsSingleUpdate($hash,"state", "snap", 1);
readingsSingleUpdate($hash, "LastSnapId", "", 0);
- } elsif ($OpMode eq "getsnapinfo") {
+ } elsif ($OpMode eq "getsnapinfo" || $OpMode eq "getsnapgallery") {
# Informationen über den letzten oder mehrere Schnappschüsse ermitteln
my $limit = $hash->{HELPER}{SNAPLIMIT};
my $imgsize = $hash->{HELPER}{SNAPIMGSIZE};
my $keyword = $hash->{HELPER}{KEYWORD};
+ Log3($name,4, "$name - Call getsnapinfo with params: Image numbers => $limit, Image size => $imgsize, Keyword => $keyword");
$url = "http://$serveraddr:$serverport/webapi/$apitakesnappath?api=\"$apitakesnap\"&method=\"List\"&version=\"$apitakesnapmaxver\"&keyword=\"$keyword\"&imgSize=\"$imgsize\"&limit=\"$limit\"&_sid=\"$sid\"";
} elsif ($OpMode eq "getsnapfilename") {
@@ -2645,9 +2797,9 @@ sub sscam_camop ($) {
} elsif ($OpMode eq "runliveview" && $hash->{HELPER}{RUNVIEW} =~ /snap/) {
# den letzten Schnappschuß life anzeigen
- my $limit = $hash->{HELPER}{SNAPLIMIT};
- my $imgsize = $hash->{HELPER}{SNAPIMGSIZE};
- my $keyword = $hash->{HELPER}{KEYWORD};
+ my $limit = 1; # nur 1 Snap laden, für lastsnap_fw
+ my $imgsize = 2; # full size picture, für lastsnap_fw
+ my $keyword = $hash->{CAMNAME}; # nur Snaps von $camname selektieren, für lastsnap_fw
$url = "http://$serveraddr:$serverport/webapi/$apitakesnappath?api=\"$apitakesnap\"&method=\"List\"&version=\"$apitakesnapmaxver\"&keyword=\"$keyword\"&imgSize=\"$imgsize\"&limit=\"$limit\"&_sid=\"$sid\"";
}
@@ -2829,61 +2981,45 @@ sub sscam_camop_parse ($) {
} elsif ($OpMode eq "Snap") {
# ein Schnapschuß wurde aufgenommen
# falls Aufnahme noch läuft -> state = on setzen
- if (ReadingsVal("$name", "Record", "Stop") eq "Start") {
- readingsSingleUpdate( $hash,"state", "on", 0);
- } else {
- readingsSingleUpdate($hash,"state", "off", 0);
- }
+ my $st;
+ (ReadingsVal("$name", "Record", "") eq "Start")?$st="on":$st="off";
+ readingsSingleUpdate($hash,"state", $st, 0);
$snapid = $data->{data}{'id'};
readingsBeginUpdate($hash);
readingsBulkUpdate($hash,"Errorcode","none");
readingsBulkUpdate($hash,"Error","none");
- readingsBulkUpdate($hash,"LastSnapId",$snapid);
readingsEndUpdate($hash, 1);
# Logausgabe
Log3($name, 3, "$name - Snapshot of Camera $camname has been done successfully");
- # nach Snap Aufnahme Filename des Snaps ermitteln
- getsnapfilename($hash);
+ # Token freigeben vor nächstem Kommando
+ $hash->{HELPER}{ACTIVE} = "off";
+
+ # Schnappschußgalerie abrufen (snapGalleryBoost) oder nur Info des letzten Snaps
+ my ($slim,$ssize) = snaplimsize($hash);
+ RemoveInternalTimer($hash, "getsnapinfo");
+ InternalTimer(gettimeofday()+0.6, "getsnapinfo", "$name:$slim:$ssize", 0);
- } elsif ($OpMode eq "getsnapinfo" || $OpMode eq "runliveview") {
- # Informationen zu einem oder mehreren Schnapschüssen wurde abgerufen bzw. Lifeanzeige Schappschuß
- my $i = 0;
- my $sn = 0;
- my %allsnaps = ();
- while ($data->{'data'}{'data'}[$i]) {
- if($data->{'data'}{'data'}[$i]{'camName'} ne $camname) {
- $i += 1;
- next;
- }
- $snapid = $data->{'data'}{'data'}[$i]{'id'};
- my $createdTm = $data->{'data'}{'data'}[$i]{'createdTm'};
- my $fileName = $data->{'data'}{'data'}[$i]{'fileName'};
- my $imageData = $data->{'data'}{'data'}[$i]{'imageData'}; # Image data of snapshot in base64 format
-
- $allsnaps{$sn}{"snapid"} = $snapid;
- my @t = split(" ", FmtDateTime($createdTm));
+ } elsif ($OpMode eq "getsnapinfo" || $OpMode eq "getsnapgallery" || $OpMode eq "runliveview") {
+ # Informationen zu einem oder mehreren Schnapschüssen wurde abgerufen bzw. Lifeanzeige Schappschuß
+ my $lsid = exists($data->{data}{data}[0]{id})?$data->{data}{data}[0]{id}:"n.a.";
+ my $lfname = exists($data->{data}{data}[0]{fileName})?$data->{data}{data}[0]{fileName}:"n.a.";
+
+ my $lstime;
+ if(exists($data->{data}{data}[0]{createdTm})) {
+ $lstime = $data->{data}{data}[0]{createdTm};
+ my @t = split(" ", FmtDateTime($lstime));
my @d = split("-", $t[0]);
- $createdTm = "$d[2].$d[1].$d[0] / $t[1]";
- $allsnaps{$sn}{createdTm} = $createdTm;
- $allsnaps{$sn}{fileName} = $fileName;
- $allsnaps{$sn}{imageData} = $imageData;
- $sn += 1;
- $i += 1;
- }
+ $lstime = "$d[2].$d[1].$d[0] / $t[1]";
+ } else {
+ $lstime = "n.a.";
+ }
- my @as = sort{$a <=>$b}keys(%allsnaps);
- foreach my $key (@as) {
- Log3($name,5, "$name - Snap '$key': ID => $allsnaps{$key}{snapid}, File => $allsnaps{$key}{fileName}, Created => $allsnaps{$key}{createdTm}");
- }
-
- my $lsid = exists($allsnaps{0}{snapid})?$allsnaps{0}{snapid}:"n.a.";
- my $lfname = exists($allsnaps{0}{fileName})?$allsnaps{0}{fileName}:"n.a.";
- my $lstime = exists($allsnaps{0}{createdTm})?$allsnaps{0}{createdTm}:"n.a.";
-
+ Log3($name,4, "$name - Snap [0]: ID => $lsid, File => $lfname, Created => $lstime");
+
readingsBeginUpdate($hash);
readingsBulkUpdate($hash,"Errorcode","none");
readingsBulkUpdate($hash,"Error","none");
@@ -2893,20 +3029,67 @@ sub sscam_camop_parse ($) {
readingsEndUpdate($hash, 1);
# Schnapschuss soll als liveView angezeigt werden (mindestens 1 Bild vorhanden)
- if (exists($hash->{HELPER}{RUNVIEW}) && $hash->{HELPER}{RUNVIEW} =~ /snap/ && exists($allsnaps{0}{imageData})) {
+ Log3($name, 3, "$name - There is no snapshot of camera $camname to display ! Take one snapshot before.")
+ if(exists($hash->{HELPER}{RUNVIEW}) && $hash->{HELPER}{RUNVIEW} =~ /snap/ && !exists($data->{'data'}{'data'}[0]{imageData}));
+
+ if (exists($hash->{HELPER}{RUNVIEW}) && $hash->{HELPER}{RUNVIEW} =~ /snap/ && exists($data->{'data'}{'data'}[0]{imageData})) {
delete $hash->{HELPER}{RUNVIEW};
# Aufnahmestatus in state abbilden
my $st;
(ReadingsVal("$name", "Record", "") eq "Start")?$st="on":$st="off";
readingsSingleUpdate($hash,"state", $st, 1);
- $hash->{HELPER}{LINK} = $allsnaps{0}{imageData};
+ $hash->{HELPER}{LINK} = $data->{data}{data}[0]{imageData};
# Longpoll refresh
DoTrigger($name,"startview");
}
+
+ if($OpMode eq "getsnapgallery") {
+ # es soll eine Schnappschußgallerie bereitgestellt (Attr snapGalleryBoost=1) bzw. gleich angezeigt werden (Attr snapGalleryBoost=0)
+ my $i = 0;
+ my $sn = 0;
+ my %allsnaps = (); # Schnappschuss Hash wird leer erstellt
+
+ $hash->{HELPER}{TOTALCNT} = $data->{data}{total}; # total Anzahl Schnappschüsse
+
+ while ($data->{'data'}{'data'}[$i]) {
+ if($data->{'data'}{'data'}[$i]{'camName'} ne $camname) {
+ $i += 1;
+ next;
+ }
+ $snapid = $data->{data}{data}[$i]{id};
+ my $createdTm = $data->{data}{data}[$i]{createdTm};
+ my $fileName = $data->{data}{data}[$i]{fileName};
+ my $imageData = $data->{data}{data}[$i]{imageData}; # Image data of snapshot in base64 format
+
+ $allsnaps{$sn}{snapid} = $snapid;
+ my @t = split(" ", FmtDateTime($createdTm));
+ my @d = split("-", $t[0]);
+ $createdTm = "$d[2].$d[1].$d[0] / $t[1]";
+ $allsnaps{$sn}{createdTm} = $createdTm;
+ $allsnaps{$sn}{fileName} = $fileName;
+ $allsnaps{$sn}{imageData} = $imageData;
+ Log3($name,4, "$name - Snap '$sn' added to gallery hash: ID => $allsnaps{$sn}{snapid}, File => $allsnaps{$sn}{fileName}, Created => $allsnaps{$sn}{createdTm}");
+ $sn += 1;
+ $i += 1;
+ }
+
+ # Hash der Schnapschüsse erstellen
+ $hash->{HELPER}{SNAPHASH} = \%allsnaps;
+
+ # Direktausgabe Snaphash wenn nicht gepollt wird
+ if(!AttrVal($name, "snapGalleryBoost",0)) {
+ my $htmlCode = composegallery($name);
+ asyncOutput($hash->{HELPER}{CL}, "$htmlCode");
+ delete($hash->{HELPER}{SNAPHASH}); # Snaphash löschen wenn nicht gepollt wird
+ delete($hash->{HELPER}{CL});
+ }
+
+ delete($hash->{HELPER}{GETSNAPGALLERY}); # Steuerbit getsnapgallery statt getsnapinfo
+ }
# Logausgabe
- Log3($name, $verbose, "$name - Snapinfos of Camera $camname have been retrieved successfully");
+ Log3($name, $verbose, "$name - Snapinfos of camera $camname retrieved");
} elsif ($OpMode eq "getsnapfilename") {
@@ -3090,7 +3273,7 @@ sub sscam_camop_parse ($) {
readingsBulkUpdate($hash,"Error","none");
readingsEndUpdate($hash, 1);
- Log3($name, $verbose, "$name - Informations related to Surveillance Station retrieved successfully");
+ Log3($name, $verbose, "$name - Informations related to Surveillance Station retrieved");
} elsif ($OpMode eq "getStmUrlPath") {
# Parse SVS-Infos
@@ -3134,7 +3317,7 @@ sub sscam_camop_parse ($) {
readingsEndUpdate($hash, 1);
# Logausgabe
- Log3($name, $verbose, "$name - Stream-URLs of $camname retrieved successfully");
+ Log3($name, $verbose, "$name - Stream-URLs of camera $camname retrieved");
} elsif ($OpMode eq "Getcaminfo") {
# Parse Caminfos
@@ -3251,7 +3434,7 @@ sub sscam_camop_parse ($) {
readingsEndUpdate($hash, 1);
# Logausgabe
- Log3($name, $verbose, "$name - Informations of camera $camname have been retrieved successfully");
+ Log3($name, $verbose, "$name - Informations of camera $camname retrieved");
} elsif ($OpMode eq "geteventlist") {
my $eventnum = $data->{'data'}{'total'};
@@ -3280,7 +3463,7 @@ sub sscam_camop_parse ($) {
readingsEndUpdate($hash, 1);
# Logausgabe
- Log3($name, $verbose, "$name - Query eventlist of camera $camname have been retrieved successfully");
+ Log3($name, $verbose, "$name - Query eventlist of camera $camname retrieved");
} elsif ($OpMode eq "getmotionenum") {
@@ -3347,7 +3530,7 @@ sub sscam_camop_parse ($) {
readingsEndUpdate($hash, 1);
# Logausgabe
- Log3($name, $verbose, "$name - Enumerate motion detection parameters of $camname have been retrieved successfully");
+ Log3($name, $verbose, "$name - Enumerate motion detection parameters of camera $camname retrieved");
} elsif ($OpMode eq "Getcapabilities") {
# Parse Infos
@@ -3424,7 +3607,7 @@ sub sscam_camop_parse ($) {
readingsEndUpdate($hash, 1);
# Logausgabe
- Log3($name, $verbose, "$name - Capabilities of Camera $camname have been retrieved successfully");
+ Log3($name, $verbose, "$name - Capabilities of camera $camname retrieved");
} elsif ($OpMode eq "Getptzlistpreset") {
# Parse PTZ-ListPresets
@@ -3457,7 +3640,7 @@ sub sscam_camop_parse ($) {
# Logausgabe
- Log3($name, $verbose, "$name - PTZ Presets of $camname retrieved");
+ Log3($name, $verbose, "$name - PTZ Presets of camera $camname retrieved");
} elsif ($OpMode eq "Getptzlistpatrol") {
# Parse PTZ-ListPatrols
@@ -3490,7 +3673,7 @@ sub sscam_camop_parse ($) {
readingsEndUpdate($hash, 1);
# Logausgabe
- Log3($name, $verbose, "$name - PTZ Patrols of $camname retrieved");
+ Log3($name, $verbose, "$name - PTZ Patrols of camera $camname retrieved");
}
} else {
@@ -3516,11 +3699,14 @@ sub sscam_camop_parse ($) {
Log3($name, 2, "$name - ERROR - Operation $OpMode of Camera $camname was not successful. Errorcode: $errorcode - $error");
}
}
-
+
+ # Token freigeben
$hash->{HELPER}{ACTIVE} = "off";
+
if ($attr{$name}{debugactivetoken}) {
Log3($name, 3, "$name - Active-Token deleted by OPMODE: $hash->{OPMODE}");
}
+
return;
}
@@ -3803,7 +3989,6 @@ return;
###############################################################################
# Test ob JSON-String empfangen wurde
-
sub evaljson {
my ($hash,$myjson,$url)= @_;
my $success = 1;
@@ -3823,9 +4008,118 @@ sub evaljson {
return($hash,$success);
}
+###############################################################################
+# Schnappschußgalerie abrufen (snapGalleryBoost) oder nur Info des letzten Snaps
+sub snaplimsize ($) {
+ my ($hash)= @_;
+ my $name = $hash->{NAME};
+ my ($slim,$ssize);
+
+ if(!AttrVal($name,"snapGalleryBoost",0)) {
+ $slim = 1;
+ $ssize = 0;
+ } else {
+ $hash->{HELPER}{GETSNAPGALLERY} = 1;
+ $slim = AttrVal($name,"snapGalleryNumber",$SSCam_slim); # Anzahl der abzurufenden Snaps
+ my $sg = AttrVal($name,"snapGallerySize","Icon"); # Auflösung Image
+ $ssize = ($sg eq "Icon")?1:2;
+ }
+return ($slim,$ssize);
+}
+
+###############################################################################
+# Schnappschußgalerie zusammenstellen
+sub composegallery ($;$$) {
+ my ($name,$wlname) = @_;
+ my $hash = $defs{$name};
+ my $camname = $hash->{CAMNAME};
+ my $allsnaps = $hash->{HELPER}{SNAPHASH}; # = \%allsnaps
+ my $sgc = AttrVal($name,"snapGalleryColumns",3); # Anzahl der Images in einer Tabellenzeile
+ my $lss = ReadingsVal($name, "LastSnapTime", " "); # Zeitpunkt neueste Aufnahme
+ my $lang = AttrVal("global","language","EN"); # Systemsprache
+ my $limit = $hash->{HELPER}{SNAPLIMIT}; # abgerufene Anzahl Snaps
+ my $totalcnt = $hash->{HELPER}{TOTALCNT}; # totale Anzahl Snaps
+ $limit = $totalcnt if ($limit > $totalcnt); # wenn weniger Snaps vorhanden sind als $limit -> Text in Anzeige korrigieren
+ my $lupt = ((ReadingsTimestamp($name,"LastSnapTime"," ") gt ReadingsTimestamp($name,"LastUpdateTime"," "))
+ ? ReadingsTimestamp($name, "LastSnapTime", " ")
+ : ReadingsTimestamp($name, "LastUpdateTime", " ")); # letzte Aktualisierung
+ $lupt =~ s/ / \/ /;
+
+ my $ha = AttrVal($name, "snapGalleryHtmlAttr", undef)?AttrVal($name, "snapGalleryHtmlAttr", undef):AttrVal($name, "htmlattr", 'width="500" height="325"');
+
+ # falls "composegallery" durch ein mit mit "createSnapGallery" angelegtes Device aufgerufen wird
+ my ($devWlink,$wlhash,$wlha,$wlalias);
+ if ($wlname) {
+ $wlalias = $attr{$wlname}{alias}?$attr{$wlname}{alias}:$wlname; # Linktext als Aliasname oder Devicename setzen
+ $devWlink = "$wlalias";
+ $wlhash = $defs{$wlname};
+ $wlha = $attr{$wlname}{htmlattr};
+ $ha = (defined($wlha))?$wlha:$ha; # htmlattr vom weblink-Device übernehmen falls von wl-Device aufgerufen und gesetzt
+ } else {
+ $devWlink = " ";
+ }
+
+ # wenn Weblink genutzt wird und attr "snapGalleryBoost" nicht gesetzt ist -> Warnung in Gallerie ausgeben
+ my $sgbnote = " ";
+ if($wlname && !AttrVal($name,"snapGalleryBoost",0)) {
+ $sgbnote = "CAUTION - No snapshots can be retrieved. Please set the attribute \"snapGalleryBoost=1\" in device $name" if ($lang eq "EN");
+ $sgbnote = "ACHTUNG - Es können keine Schnappschüsse abgerufen werden. Bitte setzen sie das Attribut \"snapGalleryBoost=1\" im Device $name" if ($lang eq "DE");
+ }
+
+ my $header;
+ if ($lang eq "EN") {
+ $header = "Snapshots ($limit/$totalcnt) of camera $camname - newest Snapshot: $lss
";
+ $header .= " (Possibly another snapshots are available. Last recall: $lupt)
" if(AttrVal($name,"snapGalleryBoost",0));
+ } else {
+ $header = "Schnappschüsse ($limit/$totalcnt) von Kamera $camname - neueste Aufnahme: $lss
";
+ $header .= " (Eventuell sind neuere Aufnahmen verfügbar. Letzter Abruf: $lupt)
" if(AttrVal($name,"snapGalleryBoost",0));
+ }
+ $header .= $sgbnote;
+
+ my $gattr = (AttrVal($name,"snapGallerySize","Icon") eq "Full")?$ha:" ";
+
+ my @as = sort{$a <=>$b}keys%{$allsnaps};
+
+ # Ausgabetabelle erstellen
+ my ($htmlCode,$ct);
+ $htmlCode = "";
+ $htmlCode .= sprintf( "$devWlink
$header
");
+ $htmlCode .= "
";
+ $htmlCode .= "";
+ $htmlCode .= "";
+ my $cell = 1;
+
+ foreach my $key (@as) {
+ $ct = $allsnaps->{$key}{createdTm};
+ my $html = sprintf( "$ct {$key}{imageData}\" /> | " );
+
+ $cell++;
+
+ if ( $cell == $sgc+1 ) {
+ $htmlCode .= $html;
+ $htmlCode .= "
";
+ $htmlCode .= "";
+ $cell = 1;
+ } else {
+ $htmlCode .= $html;
+ }
+ }
+
+ if ( $cell == 2 ) {
+ $htmlCode .= " | ";
+ }
+
+ $htmlCode .= "
";
+ $htmlCode .= "";
+ $htmlCode .= "
";
+ $htmlCode .= "
";
+ $htmlCode .= "";
+
+return $htmlCode;
+}
+
##############################################################################
# Auflösung Errorcodes bei Login / Logout
-
sub experrorauth {
# Übernahmewerte sind $hash, $errorcode
my ($hash,@errorcode) = @_;
@@ -3888,7 +4182,8 @@ sub experror {
trigger of external events 1-10 (action rules in SVS)
start and stop of camera livestreams, show the last recording and snapshot embedded
fetch of livestream-Url's with key (login not needed in that case)
- playback of last recording
+ playback of last recording and playback the last snapshot
+ create a gallery of the last 1-10 snapshots (as a Popup or permanent weblink-Device)
The recordings and snapshots will be stored in Synology Surveillance Station (SVS) and are managed like the other (normal) recordings / snapshots defined by Surveillance Station rules.
@@ -4005,7 +4300,8 @@ sub experror {
set ... goAbsPTZ | session: ServeillanceStation - observer with privilege objective control of camera |
set ... move | session: ServeillanceStation - observer with privilege objective control of camera |
set ... runView | session: ServeillanceStation - observer with privilege liveview of camera |
- set ... extevent | session: DSM - user as member of admin-group |
+ set ... snapGallery | session: ServeillanceStation - observer |
+ set ... extevent | session: DSM - user as member of admin-group |
set ... stopView | - |
set ... credentials | - |
get ... caminfoall | session: ServeillanceStation - observer |
@@ -4043,13 +4339,15 @@ sub experror {
"snap": | triggers a snapshot of the relevant camera and store it into Synology Surveillance Station |
"disable": | deactivates a camera in Synology Surveillance Station |
"enable": | activates a camera in Synology Surveillance Station |
- "credentials <username> <password>": | save a set of credentils |
+ "createSnapGallery": | creates a snapshot gallery as a permanent (weblink)Device |
+ "credentials <username> <password>": | save a set of credentils |
"expmode [ day | night | auto ]": | set the exposure mode to day, night or auto |
"extevent [ 1-10 ]": | triggers the external event 1-10 (see actionrule editor in SVS) |
"motdetsc [ camera | SVS | disable ]": | set motion detection to the desired mode |
"goPreset <Presetname>": | moves a PTZ-camera to a predefinied Preset-position |
"runPatrol <Patrolname>": | starts a predefinied patrol (PTZ-cameras) |
- "goAbsPTZ [ X Y | up | down | left | right ]": | moves a PTZ-camera to a absolute X/Y-coordinate or to direction up/down/left/right |
+ "snapGallery [1-10]": | creates an output of the last [n] snapshots |
+ "goAbsPTZ [ X Y | up | down | left | right ]": | moves a PTZ-camera to a absolute X/Y-coordinate or to direction up/down/left/right |
"move [ up | down | left | right | dir_X ]": | starts a continuous move of PTZ-camera to direction up/down/left/right or dir_X |
"runView [image | lastrec | lastrec_open | link | link_open <room> ]": | starts a livestream as embedded image or link |
"stopView": | stops a camera livestream |
@@ -4057,73 +4355,22 @@ sub experror {
- - set <name> [on|off]
-
- The command "set <name> on" starts a recording. The default recording time takes 15 seconds. It can be changed by the attribute "rectime" individualy.
- With the attribute (respectively the default value) provided recording time can be overwritten once by "set <name> on [rectime]".
- The recording will be stopped after processing time "rectime"automatically.
-
- A special case is the start using "set <name> on 0" respectively the attribute value "rectime = 0". In that case a endless-recording will be started. One have to stop this recording
- by command "set <name> off" explicitely.
-
- The recording behavior can be impacted with attribute "recextend" furthermore as explained as follows.
-
- Attribute "recextend = 0" or not set (default):
-
- - if, for example, a recording with rectimeme=22 is started, no other startcommand (for a recording) will be accepted until this started recording is finished.
- A hint will be logged in case of verboselevel = 3.
-
-
-
- Attribute "recextend = 1" is set:
-
- - a before started recording will be extend by the recording time "rectime" if a new start command is received. That means, the timer for the automatic stop-command will be
- renewed to "rectime" given bei the command, attribute or default value. This procedure will be repeated every time a new start command for recording is received.
- Therefore a running recording will be extended until no start command will be get.
-
- - a before started endless-recording will be stopped after recordingtime 2rectime" if a new "set on"-command is received (new set of timer). If it is unwanted make sure you
- don't set the attribute "recextend" in case of endless-recordings.
-
-
+ - set <name> credentials <username> <password>
+
+ set username / password combination for access the Synology Surveillance Station.
+ See Credentials
for further informations.
- Examples for simple Start/Stop a Recording:
-
-
-
- set <name> on [rectime] | starts a recording of camera <name>, stops automatically after [rectime] (default 15s or defined by attribute) |
- set <name> off | stops the recording of camera <name> |
-
-
-
-
- - set <name> snap
-
- 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.*on 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 and the filename of the last snapshot will be displayed as value of variable "LastSnapId" respectively "LastSnapFilename" in the device-Readings.
+
+
+ - set <name> createSnapGallery
+
+ A snapshot gallery will be created as a permanent (weblink)Device. The device will be provided in room "SnapGallery".
+ With the "snapGallery..."-attributes respectively the weblink-device specific attributes (what was created)
+ you are able to manipulate the properties of the new snapshot gallery device.
+
- set <name> [enable|disable]
@@ -4168,6 +4415,89 @@ sub experror {
+
+ - set <name> extevent [ 1-10 ]
+
+ This command triggers an external event (1-10) in SVS.
+ The actions which will are used have to be defined in the actionrule editor of SVS at first. There are the events 1-10 possible.
+ In the message application of SVS you may select Email, SMS or Mobil (DS-Cam) messages to release if an external event has been triggerd.
+ Further informations can be found in the online help of the actionrule editor.
+ The used user needs to be a member of the admin-group and DSM-session is needed too.
+
+
+
+
+ - set <name> goAbsPTZ [ X Y | up | down | left | right ]
+
+ This command can be used to move a PTZ-camera to an arbitrary absolute X/Y-coordinate, or to absolute position using up/down/left/right.
+ The option is only available for cameras which are having the Reading "CapPTZAbs=true". The property of a camera can be requested with "get <name> caminfoall" .
+
+
+ Example for a control to absolute X/Y-coordinates:
+
+
+ set <name> goAbsPTZ 120 450
+
+
+ In this example the camera lense moves to position X=120 und Y=450.
+ The valuation is:
+
+
+ X = 0 - 640 (0 - 319 moves lense left, 321 - 640 moves lense right, 320 don't move lense)
+ Y = 0 - 480 (0 - 239 moves lense down, 241 - 480 moves lense up, 240 don't move lense)
+
+
+ The lense can be moved in smallest steps to very large steps into the desired direction.
+ If necessary the procedure has to be repeated to bring the lense into the desired position.
+
+ If the motion should be done with the largest possible increment the following command can be used for simplification:
+
+
+ set <name> goAbsPTZ up [down|left|right]
+
+
+ In this case the lense will be moved with largest possible increment into the given absolute position.
+ Also in this case the procedure has to be repeated to bring the lense into the desired position if necessary.
+
+
+
+
+ - set <name> goPreset <Preset>
+
+ Using this command you can move PTZ-cameras to a predefined position.
+ The Preset-positions have to be defined first of all in the Synology Surveillance Station. This usually happens in the PTZ-control of IP-camera setup in SVS.
+ The Presets will be read ito FHEM with command "get <name> caminfoall" (happens automatically when FHEM restarts). The import process can be repeated regular by camera polling.
+ A long polling interval is recommendable in this case because of the Presets are only will be changed if the user change it in the IP-camera setup itself.
+
+
+ Here it is an example of a PTZ-control depended on IR-motiondetector event:
+
+
+ define CamFL.Preset.Wandschrank notify MelderTER:on.* set CamFL goPreset Wandschrank, ;; define CamFL.Preset.record at +00:00:10 set CamFL on 5 ;;;; define s3 at +*{3}00:00:05 set CamFL snap ;; define CamFL.Preset.back at +00:00:30 set CamFL goPreset Home
+
+
+ Operating Mode:
+
+ The IR-motiondetector registers a motion. Hereupon the camera "CamFL" moves to Preset-posion "Wandschrank". A recording with the length of 5 seconds starts 10 seconds later.
+ Because of the prerecording time of the camera is set to 10 seconds (cf. Reading "CamPreRecTime"), the effectice recording starts when the camera move begins.
+ When the recording starts 3 snapshots with an interval of 5 seconds will be taken as well.
+ After a time of 30 seconds in position "Wandschrank" the camera moves back to postion "Home".
+
+ An extract of the log illustrates the process:
+
+
+ 2016.02.04 15:02:14 2: CamFL - Camera Flur_Vorderhaus has moved to position "Wandschrank"
+ 2016.02.04 15:02:24 2: CamFL - Camera Flur_Vorderhaus Recording with Recordtime 5s started
+ 2016.02.04 15:02:29 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
+ 2016.02.04 15:02:30 2: CamFL - Camera Flur_Vorderhaus Recording stopped
+ 2016.02.04 15:02:34 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
+ 2016.02.04 15:02:39 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
+ 2016.02.04 15:02:44 2: CamFL - Camera Flur_Vorderhaus has moved to position "Home"
+
+
+
+
+
- set <name> motdetsc [camera|SVS|disable]
@@ -4216,90 +4546,7 @@ sub experror {
-
-
- - set <name> goPreset <Preset>
-
- Using this command you can move PTZ-cameras to a predefined position.
- The Preset-positions have to be defined first of all in the Synology Surveillance Station. This usually happens in the PTZ-control of IP-camera setup in SVS.
- The Presets will be read ito FHEM with command "get <name> caminfoall" (happens automatically when FHEM restarts). The import process can be repeated regular by camera polling.
- A long polling interval is recommendable in this case because of the Presets are only will be changed if the user change it in the IP-camera setup itself.
-
-
- Here it is an example of a PTZ-control depended on IR-motiondetector event:
-
-
- define CamFL.Preset.Wandschrank notify MelderTER:on.* set CamFL goPreset Wandschrank, ;; define CamFL.Preset.record at +00:00:10 set CamFL on 5 ;;;; define s3 at +*{3}00:00:05 set CamFL snap ;; define CamFL.Preset.back at +00:00:30 set CamFL goPreset Home
-
-
- Operating Mode:
-
- The IR-motiondetector registers a motion. Hereupon the camera "CamFL" moves to Preset-posion "Wandschrank". A recording with the length of 5 seconds starts 10 seconds later.
- Because of the prerecording time of the camera is set to 10 seconds (cf. Reading "CamPreRecTime"), the effectice recording starts when the camera move begins.
- When the recording starts 3 snapshots with an interval of 5 seconds will be taken as well.
- After a time of 30 seconds in position "Wandschrank" the camera moves back to postion "Home".
-
- An extract of the log illustrates the process:
-
-
- 2016.02.04 15:02:14 2: CamFL - Camera Flur_Vorderhaus has moved to position "Wandschrank"
- 2016.02.04 15:02:24 2: CamFL - Camera Flur_Vorderhaus Recording with Recordtime 5s started
- 2016.02.04 15:02:29 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
- 2016.02.04 15:02:30 2: CamFL - Camera Flur_Vorderhaus Recording stopped
- 2016.02.04 15:02:34 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
- 2016.02.04 15:02:39 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
- 2016.02.04 15:02:44 2: CamFL - Camera Flur_Vorderhaus has moved to position "Home"
-
-
-
-
-
- - set <name> runPatrol <Patrolname>
-
- This commans starts a predefined patrol (tour) of a PTZ-camera.
- At first the patrol has to be predefined in the Synology Surveillance Station. It can be done in the PTZ-control of IP-Kamera Setup -> PTZ-control -> patrol.
- The patrol tours will be read with command "get <name> caminfoall" which is be executed automatically when FHEM restarts.
- The import process can be repeated regular by camera polling. A long polling interval is recommendable in this case because of the patrols are only will be changed
- if the user change it in the IP-camera setup itself.
- Further informations for creating patrols you can get in the online-help of Surveillance Station.
-
-
-
-
- - set <name> goAbsPTZ [ X Y | up | down | left | right ]
-
- This command can be used to move a PTZ-camera to an arbitrary absolute X/Y-coordinate, or to absolute position using up/down/left/right.
- The option is only available for cameras which are having the Reading "CapPTZAbs=true". The property of a camera can be requested with "get <name> caminfoall" .
-
-
- Example for a control to absolute X/Y-coordinates:
-
-
- set <name> goAbsPTZ 120 450
-
-
- In this example the camera lense moves to position X=120 und Y=450.
- The valuation is:
-
-
- X = 0 - 640 (0 - 319 moves lense left, 321 - 640 moves lense right, 320 don't move lense)
- Y = 0 - 480 (0 - 239 moves lense down, 241 - 480 moves lense up, 240 don't move lense)
-
-
- The lense can be moved in smallest steps to very large steps into the desired direction.
- If necessary the procedure has to be repeated to bring the lense into the desired position.
-
- If the motion should be done with the largest possible increment the following command can be used for simplification:
-
-
- set <name> goAbsPTZ up [down|left|right]
-
-
- In this case the lense will be moved with largest possible increment into the given absolute position.
- Also in this case the procedure has to be repeated to bring the lense into the desired position if necessary.
-
-
-
+
- set <name> move [ up | down | left | right | dir_X ] [seconds]
@@ -4323,6 +4570,58 @@ sub experror {
+
+ - set <name> [on|off]
+
+ The command "set <name> on" starts a recording. The default recording time takes 15 seconds. It can be changed by the attribute "rectime" individualy.
+ With the attribute (respectively the default value) provided recording time can be overwritten once by "set <name> on [rectime]".
+ The recording will be stopped after processing time "rectime"automatically.
+
+ A special case is the start using "set <name> on 0" respectively the attribute value "rectime = 0". In that case a endless-recording will be started. One have to stop this recording
+ by command "set <name> off" explicitely.
+
+ The recording behavior can be impacted with attribute "recextend" furthermore as explained as follows.
+
+ Attribute "recextend = 0" or not set (default):
+
+ - if, for example, a recording with rectimeme=22 is started, no other startcommand (for a recording) will be accepted until this started recording is finished.
+ A hint will be logged in case of verboselevel = 3.
+
+
+
+ Attribute "recextend = 1" is set:
+
+ - a before started recording will be extend by the recording time "rectime" if a new start command is received. That means, the timer for the automatic stop-command will be
+ renewed to "rectime" given bei the command, attribute or default value. This procedure will be repeated every time a new start command for recording is received.
+ Therefore a running recording will be extended until no start command will be get.
+
+ - a before started endless-recording will be stopped after recordingtime 2rectime" if a new "set on"-command is received (new set of timer). If it is unwanted make sure you
+ don't set the attribute "recextend" in case of endless-recordings.
+
+
+
+ Examples for simple Start/Stop a Recording:
+
+
+
+ set <name> on [rectime] | starts a recording of camera <name>, stops automatically after [rectime] (default 15s or defined by attribute) |
+ set <name> off | stops the recording of camera <name> |
+
+
+
+
+
+ - set <name> runPatrol <Patrolname>
+
+ This commans starts a predefined patrol (tour) of a PTZ-camera.
+ At first the patrol has to be predefined in the Synology Surveillance Station. It can be done in the PTZ-control of IP-Kamera Setup -> PTZ-control -> patrol.
+ The patrol tours will be read with command "get <name> caminfoall" which is be executed automatically when FHEM restarts.
+ The import process can be repeated regular by camera polling. A long polling interval is recommendable in this case because of the patrols are only will be changed
+ if the user change it in the IP-camera setup itself.
+ Further informations for creating patrols you can get in the online-help of Surveillance Station.
+
+
+
- set <name> runView [live_fw | live_link | live_open [<room>] | lastrec_fw | lastrec_open [<room>] | lastsnap_fw]
@@ -4346,9 +4645,6 @@ sub experror {
attr <name> htmlattr width="700",height="525",top="200",left="300"
- With these attribute values a streaming link will be opened (by click on) in a new browser tab or windows. If the stream will be started as an image, the size changes appropriately the
- values of width and hight.
-
The command "set <name> runView live_open" starts the stream immediately in a new browser window (longpoll=1
must be set for WEB).
A browser window will be initiated to open for every FHEM session which is active. If you want to change this behavior,
@@ -4370,13 +4666,42 @@ sub experror {
- - set <name> extevent [ 1-10 ]
+ - set <name> snap
- This command triggers an external event (1-10) in SVS.
- The actions which will are used have to be defined in the actionrule editor of SVS at first. There are the events 1-10 possible.
- In the message application of SVS you may select Email, SMS or Mobil (DS-Cam) messages to release if an external event has been triggerd.
- Further informations can be found in the online help of the actionrule editor.
- The used user needs to be a member of the admin-group and DSM-session is needed too.
+ 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.*on 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 and the filename of the last snapshot will be displayed as value of variable "LastSnapId" respectively "LastSnapFilename" in the device-Readings.
+
+
+
+
+ - set <name> snapGallery [1-10]
+
+ The command is only available if the attribute "snapGalleryBoost=1" is set.
+ It creates an output of the last [x] snapshots as well as "get ... snapGallery". But differing from "get" with
+ attribute "snapGalleryBoost=1" no popup will be created. The snapshot gallery will be depicted as
+ an browserpage instead. All further functions and attributes are appropriate the "get ... snapGallery"
+ command.
@@ -4392,6 +4717,7 @@ sub experror {
get <name> caminfoall
get <name> eventlist
get <name> scanVirgin
+ get <name> snapGallery
get <name> stmUrlPath
get <name> svsinfo
get <name> snapfileinfo
@@ -4421,6 +4747,33 @@ sub experror {
+
+ - get <name> snapGallery [1-10]
+
+ A popup with the last [x] snapshots will be created. If the attribute "snapGalleryBoost" is set,
+ the last snapshots (default 3) are requested by polling and they will be stored in the FHEM-servers main memory.
+ This method is helpful to speed up the output especially in case of full size images, but it can be possible
+ that NOT the newest snapshots are be shown if they have not be initialized by the SSCAm-module itself.
+
+ To control this function behavior there are further attributes:
+
+
+ - snapGalleryBoost
+ - snapGalleryColumns
+ - snapGalleryHtmlAttr
+ - snapGalleryNumber
+ - snapGallerySize
+
+ available.
+
+
+
+ Note:
+ Depended from quantity and resolution (quality) of the snapshot images adequate CPU and/or main memory
+ ressources are needed.
+
+
+
- get <name> snapinfo
@@ -4567,6 +4920,37 @@ sub experror {
- simu_SVSversion
simulates another SVS version. (only a lower version than the installed one is possible !)
+
+ - snapGalleryBoost
+ If set, the last snapshots (default 3) will be retrieved by Polling, will be stored in the FHEM-servers main memory
+ and can be displayed by the "set/get ... snapGallery" command.
+ This mode is helpful if many or full size images shall be displayed.
+ If the attribute is set, you can't specify arguments in addition to the "set/get ... snapGallery" command.
+ (see also attribut "snapGalleryNumber")
+
+ - snapGalleryColumns
+ The number of snapshots which shall appear in one row of the gallery popup (default 3).
+
+ - snapGalleryHtmlAttr
+ the image parameter can be controlled by this attribute.
+ If the attribute isn't set, the value of attribute "htmlattr" will be used.
+ If "htmlattr" is also not set, default parameters are used instead (width="500" height="325").
+
+
+ Example:
+ attr <name> snapGalleryHtmlAttr width="325" height="225"
+
+
+
+
+ - snapGalleryNumber
+ The number of snapshots to retrieve (default 3).
+
+ - snapGallerySize
+ By this attribute the quality of the snapshot images can be controlled (default "Icon").
+ If mode "Full" is set, the images are retrieved with their original available resolution. That requires more ressources
+ and may slow down the display. By setting attribute "snapGalleryBoost=1" the display may accelerated, because in that case
+ the images will be retrieved by continuous polling and need only bring to display.
- showStmInfoFull
additional stream informations like LiveStreamUrl, StmKeyUnicst, StmKeymjpegHttp will be created
@@ -4695,7 +5079,8 @@ sub experror {
- auslösen externer Ereignisse 1-10 (Aktionsregel SVS)
- starten und beenden von Kamera-Livestreams, anzeigen der letzten Aufnahme oder des letzten Schnappschusses
- Abruf und Ausgabe der Kamera Streamkeys sowie Stream-Urls (Nutzung von Kamera-Livestreams ohne Session Id)
- - abspielen der letzten Aufnahme
+ - abspielen der letzten Aufnahme bzw. Anzeige des letzten Schnappschusses
+ - erzeugen einer Gallerie der letzten 1-10 Schnappschüsse (als Popup oder permanentes Device)
Die Aufnahmen stehen in der Synology Surveillance Station (SVS) zur Verfügung und unterliegen, wie jede andere Aufnahme, den in der Synology Surveillance Station eingestellten Regeln.
@@ -4809,7 +5194,8 @@ sub experror {
set ... motdetsc | session: ServeillanceStation - Manager |
set ... goPreset | session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera |
set ... runPatrol | session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera |
- set ... goAbsPTZ | session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera |
+ set ... snapGallery | session: ServeillanceStation - Betrachter |
+ set ... goAbsPTZ | session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera |
set ... move | session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera |
set ... runView | session: ServeillanceStation - Betrachter mit Privileg Liveansicht für Kamera |
set ... stopView | - |
@@ -4820,6 +5206,7 @@ sub experror {
get ... scanVirgin | session: ServeillanceStation - Betrachter |
get ... svsinfo | session: ServeillanceStation - Betrachter |
get ... snapfileinfo | session: ServeillanceStation - Betrachter |
+ get ... snapGallery | session: ServeillanceStation - Betrachter |
get ... snapinfo | session: ServeillanceStation - Betrachter |
get ... stmUrlPath | session: ServeillanceStation - Betrachter |
@@ -4841,7 +5228,7 @@ sub experror {
Set
- Es gibt zur Zeit folgende Optionen für "set <name> ...":
+ Es gibt zur Zeit folgende Optionen für "set <name> ...":
@@ -4851,13 +5238,15 @@ sub experror {
"snap": | löst einen Schnappschuß der entsprechenden Kamera aus und speichert ihn in der Synology Surveillance Station |
"disable": | deaktiviert eine Kamera in der Synology Surveillance Station |
"enable": | aktiviert eine Kamera in der Synology Surveillance Station |
- "credentials <username> <password>": | speichert die Zugangsinformationen |
+ "createSnapGallery": | erzeugt eine Schnappschußgallerie als (weblink)Device |
+ "credentials <username> <password>": | speichert die Zugangsinformationen |
"expmode [ day | night | auto ]": | aktiviert den Belichtungsmodus Tag, Nacht oder Automatisch |
"extevent [ 1-10 ]": | löst das externe Ereignis 1-10 aus (Aktionsregel in SVS) |
"motdetsc [ camera | SVS | disable ]": | schaltet die Bewegungserkennung in den gewünschten Modus (durch Kamera, SVS, oder deaktiviert) |
"goPreset <Presetname>": | bewegt eine PTZ-Kamera zu einer vordefinierten Preset-Position |
"runPatrol <Patrolname>": | startet eine vordefinierte Überwachungstour einer PTZ-Kamera |
- "goAbsPTZ [ X Y | up | down | left | right ]": | positioniert eine PTZ-camera zu einer absoluten X/Y-Koordinate oder maximalen up/down/left/right-position |
+ "snapGallery [1-10]": | erzeugt eine Ausgabe der letzten [n] Schnappschüsse |
+ "goAbsPTZ [ X Y | up | down | left | right ]": | positioniert eine PTZ-camera zu einer absoluten X/Y-Koordinate oder maximalen up/down/left/right-position |
"move [ up | down | left | right | dir_X ]": | startet kontinuerliche Bewegung einer PTZ-Kamera in Richtung up/down/left/right bzw. dir_X |
"runView live_fw | live_link | live_open [<room>] | lastrec_fw | lastrec_open [<room>]": | startet einen Livestream als eingbettetes Image, IFrame bzw. Link |
"stopView": | stoppt einen Kamera-Livestream |
@@ -4865,72 +5254,22 @@ sub experror {
- - set <name> [on] [off]
-
- Der Befehl "set <name> on" startet eine Aufnahme. Die Standardaufnahmedauer beträgt 15 Sekunden. Sie kann mit dem Attribut "rectime" individuell festgelegt werden.
- Die im Attribut (bzw. im Standard) hinterlegte Aufnahmedauer kann einmalig mit "set <name> on [rectime]" überschrieben werden.
- Die Aufnahme stoppt automatisch nach Ablauf der Zeit "rectime".
-
- Ein Sonderfall ist der Start einer Daueraufnahme mit "set <name> on 0" bzw. dem Attributwert "rectime = 0". In diesem Fall wird eine Daueraufnahme gestartet die
- explizit wieder mit dem Befehl "set <name> off" gestoppt werden muß.
-
- Das Aufnahmeverhalten kann weiterhin mit dem Attribut "recextend" wie folgt beeinflusst werden.
-
- Attribut "recextend = 0" bzw. nicht gesetzt (Standard):
-
- - wird eine Aufnahme mit z.B. rectime=22 gestartet, wird kein weiterer Startbefehl für eine Aufnahme akzeptiert bis diese gestartete Aufnahme nach 22 Sekunden
- beendet ist. Ein Hinweis wird bei verbose=3 im Logfile protokolliert.
-
-
-
- Attribut "recextend = 1" gesetzt:
-
- - eine zuvor gestartete Aufnahme wird bei einem erneuten "set on" -Befehl um die Aufnahmezeit "rectime" verlängert. Das bedeutet, dass der Timer für
- den automatischen Stop auf den Wert "rectime" neu gesetzt wird. Dieser Vorgang wiederholt sich mit jedem Start-Befehl. Dadurch verlängert sich eine laufende
- Aufnahme bis kein Start-Inpuls mehr registriert wird.
-
- - eine zuvor gestartete Endlos-Aufnahme wird mit einem erneuten "set on"-Befehl nach der Aufnahmezeit "rectime" gestoppt (Timerneustart). Ist dies
- nicht gewünscht, ist darauf zu achten dass bei der Verwendung einer Endlos-Aufnahme das Attribut "recextend" nicht verwendet wird.
-
-
+ - set <name> credentials <username> <password>
+
+ Setzt Username / Passwort für den Zugriff auf die Synology Surveillance Station.
+ Siehe Credentials
- Beispiele für einfachen Start/Stop einer Aufnahme:
-
-
-
- set <name> on [rectime] | startet die Aufnahme der Kamera <name>, automatischer Stop der Aufnahme nach Ablauf der Zeit [rectime] (default 15s oder wie im Attribut "rectime" angegeben) |
- set <name> off | stoppt die Aufnahme der Kamera <name> |
-
-
-
-
- - set <name> snap
-
- Ein Schnappschuß kann ausgelöst werden mit:
-
- 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 und der Filename des letzten Snapshots als Wert der Variable "LastSnapId" bzw. "LastSnapFilename" in den Readings der Kamera ausgegeben.
+
+
+ - set <name> createSnapGallery
+
+ Es wird eine Schnappschußgallerie als permanentes (weblink)Device erzeugt. Das Device wird im Raum "SnapGallery" erstellt.
+ Mit den "snapGallery..."-Attributen bzw. den spezifischen Attributen des entstandenen Weblink-Devices
+ können die Eigenschaften der Schnappschußgallerie beeinflusst werden.
+
- set <name> [enable|disable]
@@ -4958,7 +5297,7 @@ sub experror {
attr all_cams_enable room Cams
-
+
- set <name> expmode [day|night|auto]
@@ -4970,100 +5309,17 @@ sub experror {
Die erfolgreiche Ausführung dieser Funktion ist davon abhängig ob die SVS diese Funktionalität der Kamera unterstützt.
Ist in SVS -> IP-Kamera -> Optimierung -> Belichtungsmodus das Feld für den Tag/Nachtmodus grau hinterlegt, ist nicht von einer lauffähigen Unterstützung dieser
Funktion auszugehen.
-
-
- set <name> motdetsc [camera|SVS|disable]
-
- Der Befehl "motdetsc" (steht für motion detection source) schaltet die Bewegungserkennung in den gewünschten Modus.
- Wird die Bewegungserkennung durch die Kamera / SVS ohne weitere Optionen eingestellt, werden die momentan gültigen Bewegungserkennungsparameter der
- Kamera / SVS beibehalten. Die erfolgreiche Ausführung der Operation lässt sich u.a. anhand des Status von SVS -> IP-Kamera -> Ereigniserkennung ->
- Bewegung nachvollziehen.
- Für die Bewegungserkennung durch SVS bzw. durch Kamera können weitere Optionen angegeben werden. Die verfügbaren Optionen bezüglich der Bewegungserkennung
- durch SVS sind "Empfindlichkeit" und "Schwellwert".
-
-
-
- set motdetsc SVS [Empfindlichkeit] [Schwellwert] | # Befehlsmuster |
- set motdetsc SVS 91 30 | # setzt die Empfindlichkeit auf 91 und den Schwellwert auf 30 |
- set motdetsc SVS 0 40 | # behält gesetzten Wert für Empfindlichkeit bei, setzt Schwellwert auf 40 |
- set motdetsc SVS 15 | # setzt die Empfindlichkeit auf 15, Schwellwert bleibt unverändert |
-
-
-
- Wird die Bewegungserkennung durch die Kamera genutzt, stehen die Optionen "Empfindlichkeit", "Objektgröße" und "Prozentsatz für Auslösung" zur Verfügung.
-
-
-
- set motdetsc camera [Empfindlichkeit] [Schwellwert] [Prozentsatz] | # Befehlsmuster |
- set motdetsc camera 89 0 20 | # setzt die Empfindlichkeit auf 89, Prozentsatz auf 20 |
- set motdetsc camera 0 40 10 | # behält gesetzten Wert für Empfindlichkeit bei, setzt Schwellwert auf 40, Prozentsatz auf 10 |
- set motdetsc camera 30 | # setzt die Empfindlichkeit auf 30, andere Werte bleiben unverändert |
-
-
-
- Es ist immer die Reihenfolge der Optionswerte zu beachten. Nicht gewünschte Optionen sind mit "0" zu besetzen sofern danach Optionen folgen
- deren Werte verändert werden sollen (siehe Beispiele oben). Der Zahlenwert der Optionen beträgt 1 - 99 (außer Sonderfall "0").
-
- Die jeweils verfügbaren Optionen unterliegen der Funktion der Kamera und der Unterstützung durch die SVS. Es können jeweils nur die Optionen genutzt werden die in
- SVS -> Kamera bearbeiten -> Ereigniserkennung zur Verfügung stehen. Weitere Infos sind der Online-Hilfe zur SVS zu entnehmen.
-
- Über den Befehl "get ... caminfoall" wird auch das Reading "CamMotDetSc" aktualisiert welches die gegenwärtige Einstellung der Bewegungserkennung dokumentiert.
- Es werden nur die Parameter und Parameterwerte angezeigt, welche die SVS aktiv unterstützt. Die Kamera selbst kann weiterführende Einstellmöglichkeiten besitzen.
-
- Beipiel:
-
- CamMotDetSc SVS, sensitivity: 76, threshold: 55
-
-
-
- - set <name> goPreset <Preset>
+ - set <name> extevent [ 1-10 ]
- Mit diesem Kommando können PTZ-Kameras in eine vordefininierte Position bewegt werden.
- Die Preset-Positionen müssen dazu zunächst in der Synology Surveillance Station angelegt worden sein. Das geschieht in der PTZ-Steuerung im IP-Kamera Setup.
- Die Presets werden über das Kommando "get <name> caminfoall" eingelesen (geschieht bei restart von FHEM automatisch). Der Einlesevorgang kann durch ein Kamerapolling
- regelmäßig wiederholt werden. Ein langes Pollingintervall ist in diesem Fall empfehlenswert, da sich die Presetpositionen nur im Fall der Neuanlage bzw. Änderung verändern werden.
-
-
- Hier ein Beispiel einer PTZ-Steuerung in Abhängigkeit eines IR-Melder Events:
-
-
- define CamFL.Preset.Wandschrank notify MelderTER:on.* set CamFL goPreset Wandschrank, ;; define CamFL.Preset.record at +00:00:10 set CamFL on 5 ;;;; define s3 at +*{3}00:00:05 set CamFL snap ;; define CamFL.Preset.back at +00:00:30 set CamFL goPreset Home
-
-
- Funktionsweise:
- Der IR-Melder "MelderTER" registriert eine Bewegung. Daraufhin wird die Kamera CamFL in die Preset-Position "Wandschrank" gebracht. Eine Aufnahme mit Dauer von 5 Sekunden startet 10 Sekunden
- später. Da die Voraufnahmezeit der Kamera 10s beträgt (vgl. Reading "CamPreRecTime"), startet die effektive Aufnahme wenn der Kameraschwenk beginnt.
- Mit dem Start der Aufnahme werden drei Schnappschüsse im Abstand von 5 Sekunden angefertigt.
- Nach einer Zeit von 30 Sekunden fährt die Kamera wieder zurück in die "Home"-Position.
-
- Ein Auszug aus dem Log verdeutlicht den Ablauf:
-
-
- 2016.02.04 15:02:14 2: CamFL - Camera Flur_Vorderhaus has moved to position "Wandschrank"
- 2016.02.04 15:02:24 2: CamFL - Camera Flur_Vorderhaus Recording with Recordtime 5s started
- 2016.02.04 15:02:29 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
- 2016.02.04 15:02:30 2: CamFL - Camera Flur_Vorderhaus Recording stopped
- 2016.02.04 15:02:34 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
- 2016.02.04 15:02:39 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
- 2016.02.04 15:02:44 2: CamFL - Camera Flur_Vorderhaus has moved to position "Home"
-
-
-
-
-
- - set <name> runPatrol <Patrolname>
-
- Dieses Kommando startet die vordefinierterte Überwachungstour einer PTZ-Kamera.
- Die Überwachungstouren müssen dazu zunächst in der Synology Surveillance Station angelegt worden sein.
- Das geschieht in der PTZ-Steuerung im IP-Kamera Setup -> PTZ-Steuerung -> Überwachung.
- Die Überwachungstouren (Patrols) werden über das Kommando "get <name> caminfoall" eingelesen, welches beim Restart von FHEM automatisch abgearbeitet wird.
- Der Einlesevorgang kann durch ein Kamerapolling regelmäßig wiederholt werden. Ein langes Pollingintervall ist in diesem Fall empfehlenswert, da sich die
- Überwachungstouren nur im Fall der Neuanlage bzw. Änderung verändern werden.
- Nähere Informationen zur Anlage von Überwachungstouren sind in der Hilfe zur Surveillance Station enthalten.
+ Dieses Kommando triggert ein externes Ereignis (1-10) in der SVS.
+ Die Aktionen, die dieses Ereignis auslöst, sind zuvor in dem Aktionsregeleditor der SVS einzustellen. Es stehen die Ereignisse 1-10 zur Verfügung.
+ In der Banchrichtigungs-App der SVS können auch Email, SMS oder Mobil (DS-Cam) Nachrichten ausgegeben werden wenn ein externes Ereignis ausgelöst wurde.
+ Nähere Informationen dazu sind in der Hilfe zum Aktionsregeleditor zu finden.
+ Der verwendete User benötigt Admin-Rechte in einer DSM-Session.
@@ -5102,6 +5358,89 @@ sub experror {
+
+ - set <name> goPreset <Preset>
+
+ Mit diesem Kommando können PTZ-Kameras in eine vordefininierte Position bewegt werden.
+ Die Preset-Positionen müssen dazu zunächst in der Synology Surveillance Station angelegt worden sein. Das geschieht in der PTZ-Steuerung im IP-Kamera Setup.
+ Die Presets werden über das Kommando "get <name> caminfoall" eingelesen (geschieht bei restart von FHEM automatisch). Der Einlesevorgang kann durch ein Kamerapolling
+ regelmäßig wiederholt werden. Ein langes Pollingintervall ist in diesem Fall empfehlenswert, da sich die Presetpositionen nur im Fall der Neuanlage bzw. Änderung verändern werden.
+
+
+ Hier ein Beispiel einer PTZ-Steuerung in Abhängigkeit eines IR-Melder Events:
+
+
+ define CamFL.Preset.Wandschrank notify MelderTER:on.* set CamFL goPreset Wandschrank, ;; define CamFL.Preset.record at +00:00:10 set CamFL on 5 ;;;; define s3 at +*{3}00:00:05 set CamFL snap ;; define CamFL.Preset.back at +00:00:30 set CamFL goPreset Home
+
+
+ Funktionsweise:
+ Der IR-Melder "MelderTER" registriert eine Bewegung. Daraufhin wird die Kamera CamFL in die Preset-Position "Wandschrank" gebracht. Eine Aufnahme mit Dauer von 5 Sekunden startet 10 Sekunden
+ später. Da die Voraufnahmezeit der Kamera 10s beträgt (vgl. Reading "CamPreRecTime"), startet die effektive Aufnahme wenn der Kameraschwenk beginnt.
+ Mit dem Start der Aufnahme werden drei Schnappschüsse im Abstand von 5 Sekunden angefertigt.
+ Nach einer Zeit von 30 Sekunden fährt die Kamera wieder zurück in die "Home"-Position.
+
+ Ein Auszug aus dem Log verdeutlicht den Ablauf:
+
+
+ 2016.02.04 15:02:14 2: CamFL - Camera Flur_Vorderhaus has moved to position "Wandschrank"
+ 2016.02.04 15:02:24 2: CamFL - Camera Flur_Vorderhaus Recording with Recordtime 5s started
+ 2016.02.04 15:02:29 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
+ 2016.02.04 15:02:30 2: CamFL - Camera Flur_Vorderhaus Recording stopped
+ 2016.02.04 15:02:34 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
+ 2016.02.04 15:02:39 2: CamFL - Snapshot of Camera Flur_Vorderhaus has been done successfully
+ 2016.02.04 15:02:44 2: CamFL - Camera Flur_Vorderhaus has moved to position "Home"
+
+
+
+
+
+ - set <name> motdetsc [camera|SVS|disable]
+
+ Der Befehl "motdetsc" (steht für motion detection source) schaltet die Bewegungserkennung in den gewünschten Modus.
+ Wird die Bewegungserkennung durch die Kamera / SVS ohne weitere Optionen eingestellt, werden die momentan gültigen Bewegungserkennungsparameter der
+ Kamera / SVS beibehalten. Die erfolgreiche Ausführung der Operation lässt sich u.a. anhand des Status von SVS -> IP-Kamera -> Ereigniserkennung ->
+ Bewegung nachvollziehen.
+ Für die Bewegungserkennung durch SVS bzw. durch Kamera können weitere Optionen angegeben werden. Die verfügbaren Optionen bezüglich der Bewegungserkennung
+ durch SVS sind "Empfindlichkeit" und "Schwellwert".
+
+
+
+ set motdetsc SVS [Empfindlichkeit] [Schwellwert] | # Befehlsmuster |
+ set motdetsc SVS 91 30 | # setzt die Empfindlichkeit auf 91 und den Schwellwert auf 30 |
+ set motdetsc SVS 0 40 | # behält gesetzten Wert für Empfindlichkeit bei, setzt Schwellwert auf 40 |
+ set motdetsc SVS 15 | # setzt die Empfindlichkeit auf 15, Schwellwert bleibt unverändert |
+
+
+
+
+ Wird die Bewegungserkennung durch die Kamera genutzt, stehen die Optionen "Empfindlichkeit", "Objektgröße" und "Prozentsatz für Auslösung" zur Verfügung.
+
+
+
+ set motdetsc camera [Empfindlichkeit] [Schwellwert] [Prozentsatz] | # Befehlsmuster |
+ set motdetsc camera 89 0 20 | # setzt die Empfindlichkeit auf 89, Prozentsatz auf 20 |
+ set motdetsc camera 0 40 10 | # behält gesetzten Wert für Empfindlichkeit bei, setzt Schwellwert auf 40, Prozentsatz auf 10 |
+ set motdetsc camera 30 | # setzt die Empfindlichkeit auf 30, andere Werte bleiben unverändert |
+
+
+
+
+ Es ist immer die Reihenfolge der Optionswerte zu beachten. Nicht gewünschte Optionen sind mit "0" zu besetzen sofern danach Optionen folgen
+ deren Werte verändert werden sollen (siehe Beispiele oben). Der Zahlenwert der Optionen beträgt 1 - 99 (außer Sonderfall "0").
+
+ Die jeweils verfügbaren Optionen unterliegen der Funktion der Kamera und der Unterstützung durch die SVS. Es können jeweils nur die Optionen genutzt werden die in
+ SVS -> Kamera bearbeiten -> Ereigniserkennung zur Verfügung stehen. Weitere Infos sind der Online-Hilfe zur SVS zu entnehmen.
+
+ Über den Befehl "get ... caminfoall" wird auch das Reading "CamMotDetSc" aktualisiert welches die gegenwärtige Einstellung der Bewegungserkennung dokumentiert.
+ Es werden nur die Parameter und Parameterwerte angezeigt, welche die SVS aktiv unterstützt. Die Kamera selbst kann weiterführende Einstellmöglichkeiten besitzen.
+
+ Beipiel:
+
+ CamMotDetSc SVS, sensitivity: 76, threshold: 55
+
+
+
+
- set <name> move [ up | down | left | right | dir_X ] [Sekunden]
@@ -5125,6 +5464,59 @@ sub experror {
+
+ - set <name> [on | off]
+
+ Der Befehl "set <name> on" startet eine Aufnahme. Die Standardaufnahmedauer beträgt 15 Sekunden. Sie kann mit dem Attribut "rectime" individuell festgelegt werden.
+ Die im Attribut (bzw. im Standard) hinterlegte Aufnahmedauer kann einmalig mit "set <name> on [rectime]" überschrieben werden.
+ Die Aufnahme stoppt automatisch nach Ablauf der Zeit "rectime".
+
+ Ein Sonderfall ist der Start einer Daueraufnahme mit "set <name> on 0" bzw. dem Attributwert "rectime = 0". In diesem Fall wird eine Daueraufnahme gestartet die
+ explizit wieder mit dem Befehl "set <name> off" gestoppt werden muß.
+
+ Das Aufnahmeverhalten kann weiterhin mit dem Attribut "recextend" wie folgt beeinflusst werden.
+
+ Attribut "recextend = 0" bzw. nicht gesetzt (Standard):
+
+ - wird eine Aufnahme mit z.B. rectime=22 gestartet, wird kein weiterer Startbefehl für eine Aufnahme akzeptiert bis diese gestartete Aufnahme nach 22 Sekunden
+ beendet ist. Ein Hinweis wird bei verbose=3 im Logfile protokolliert.
+
+
+
+ Attribut "recextend = 1" gesetzt:
+
+ - eine zuvor gestartete Aufnahme wird bei einem erneuten "set on" -Befehl um die Aufnahmezeit "rectime" verlängert. Das bedeutet, dass der Timer für
+ den automatischen Stop auf den Wert "rectime" neu gesetzt wird. Dieser Vorgang wiederholt sich mit jedem Start-Befehl. Dadurch verlängert sich eine laufende
+ Aufnahme bis kein Start-Inpuls mehr registriert wird.
+
+ - eine zuvor gestartete Endlos-Aufnahme wird mit einem erneuten "set on"-Befehl nach der Aufnahmezeit "rectime" gestoppt (Timerneustart). Ist dies
+ nicht gewünscht, ist darauf zu achten dass bei der Verwendung einer Endlos-Aufnahme das Attribut "recextend" nicht verwendet wird.
+
+
+
+ Beispiele für einfachen Start/Stop einer Aufnahme:
+
+
+
+ set <name> on [rectime] | startet die Aufnahme der Kamera <name>, automatischer Stop der Aufnahme nach Ablauf der Zeit [rectime] (default 15s oder wie im Attribut "rectime" angegeben) |
+ set <name> off | stoppt die Aufnahme der Kamera <name> |
+
+
+
+
+
+ - set <name> runPatrol <Patrolname>
+
+ Dieses Kommando startet die vordefinierterte Überwachungstour einer PTZ-Kamera.
+ Die Überwachungstouren müssen dazu zunächst in der Synology Surveillance Station angelegt worden sein.
+ Das geschieht in der PTZ-Steuerung im IP-Kamera Setup -> PTZ-Steuerung -> Überwachung.
+ Die Überwachungstouren (Patrols) werden über das Kommando "get <name> caminfoall" eingelesen, welches beim Restart von FHEM automatisch abgearbeitet wird.
+ Der Einlesevorgang kann durch ein Kamerapolling regelmäßig wiederholt werden. Ein langes Pollingintervall ist in diesem Fall empfehlenswert, da sich die
+ Überwachungstouren nur im Fall der Neuanlage bzw. Änderung verändern werden.
+ Nähere Informationen zur Anlage von Überwachungstouren sind in der Hilfe zur Surveillance Station enthalten.
+
+
+
- set <name> runView [live_fw | live_link | live_open [<room>] | lastrec_fw | lastrec_open [<room>] | lastsnap_fw]
@@ -5147,8 +5539,7 @@ sub experror {
attr <name> htmlattr width="500" height="375" top="200" left="300"
- Mit diesen Attributwerten öffnet der Link (mit Klick) als weiteres Fenster/Browsertab. Wird der Stream als live_fw gestartet,
- ändert sich die Größe entsprechend der Angaben von Width und Hight.
+ Wird der Stream als live_fw gestartet, ändert sich die Größe entsprechend der Angaben von Width und Hight.
Das Kommando "set <name> runView live_open" startet den Livestreamlink sofort in einem neuen
Browserfenster (longpoll=1 muß für WEB gesetzt sein).
Dabei wird für jede aktive FHEM-Session eine Fensteröffnung initiiert. Soll dieses Verhalten geändert werden, kann
@@ -5168,17 +5559,44 @@ sub experror {
- - set <name> extevent [ 1-10 ]
+ - set <name> snap
- Dieses Kommando triggert ein externes Ereignis (1-10) in der SVS.
- Die Aktionen, die dieses Ereignis auslöst, sind zuvor in dem Aktionsregeleditor der SVS einzustellen. Es stehen die Ereignisse 1-10 zur Verfügung.
- In der Banchrichtigungs-App der SVS können auch Email, SMS oder Mobil (DS-Cam) Nachrichten ausgegeben werden wenn ein externes Ereignis ausgelöst wurde.
- Nähere Informationen dazu sind in der Hilfe zum Aktionsregeleditor zu finden.
- Der verwendete User benötigt Admin-Rechte in einer DSM-Session.
+ Ein Schnappschuß kann ausgelöst werden mit:
+
+ 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 und der Filename des letzten Snapshots als Wert der Variable "LastSnapId" bzw. "LastSnapFilename" in den Readings der Kamera ausgegeben.
+
+
+
+
+ - set <name> snapGallery [1-10]
+
+ Der Befehl ist nur vorhanden wenn das Attribut "snapGalleryBoost=1" gesetzt wurde.
+ Er erzeugt eine Ausgabe der letzten [x] Schnappschüsse ebenso wie "get ... snapGallery". Abweichend von "get" wird mit Attribut
+ Attribut "snapGalleryBoost=1" kein Popup erzeugt, sondern die Schnappschußgalerie als Browserseite
+ dargestellt. Alle weiteren Funktionen und Attribute entsprechen dem "get ... snapGallery" Kommando.
-
+
@@ -5191,6 +5609,7 @@ sub experror {
get <name> eventlist
get <name> scanVirgin
get <name> snapfileinfo
+ get <name> snapGallery
get <name> snapinfo
get <name> stmUrlPath
get <name> svsinfo
@@ -5230,6 +5649,32 @@ sub experror {
+
+ - get <name> snapGallery [1-10]
+
+ Es wird ein Popup mit den letzten [x] Schnapschüssen erzeugt. Ist das Attribut "snapGalleryBoost" gesetzt,
+ werden die letzten Schnappschüsse (default 3) über Polling abgefragt und im Speicher gehalten. Das Verfahren hilft die Ausgabe zu beschleunigen,
+ kann aber möglicherweise nicht den letzten Schnappschuß anzeigen, falls dieser NICHT über das Modul ausgelöst wurde.
+
+ Zur weiteren Steuerung dieser Funktion stehen die Attribute:
+
+
+ - snapGalleryBoost
+ - snapGalleryColumns
+ - snapGalleryHtmlAttr
+ - snapGalleryNumber
+ - snapGallerySize
+
+ zur Verfügung.
+
+
+
+ Hinweis:
+ Abhängig von der Anzahl und Auflösung (Qualität) der Schnappschuß-Images werden entsprechende ausreichende CPU und/oder
+ RAM-Ressourcen benötigt.
+
+
+
- get <name> snapinfo
@@ -5382,9 +5827,39 @@ sub experror {
(Standard). "SurveillanceStation" -> Session-Aufbau erfolgt mit SVS
- simu_SVSversion
- simuliert eine andere SVS-Version. (es ist nur eine niedrigere als die installierte SVS
+ Simuliert eine andere SVS-Version. (es ist nur eine niedrigere als die installierte SVS
Version möglich !)
+
+ - snapGalleryBoost
+ Wenn gesetzt, werden die letzten Schnappschüsse (default 3) über Polling im Speicher gehalten und mit "set/get snapGallery"
+ aufbereitet angezeigt. Dieser Modus bietet sich an wenn viele bzw. Fullsize Images angezeigt werden sollen.
+ Ist das Attribut eingeschaltet, können bei "set/get snapGallery" keine Argumente mehr mitgegeben werden.
+ (siehe Attribut "snapGalleryNumber")
+ - snapGalleryColumns
+ Die Anzahl der Snaps die in einer Reihe im Popup erscheinen sollen (default 3).
+
+ - snapGalleryHtmlAttr
+ hiermit kann die Bilddarstellung beeinflusst werden.
+ Ist das Attribut nicht gesetzt, wird das Attribut "htmlattr" verwendet.
+ Ist auch dieses nicht gesetzt, wird eine Standardvorgabe verwendet (width="500" height="325").
+
+
+ Beispiel:
+ attr <name> snapGalleryHtmlAttr width="325" height="225"
+
+
+
+
+ - snapGalleryNumber
+ Die Anzahl der abzurufenden Schnappschüsse (default 3).
+
+ - snapGallerySize
+ Mit diesem Attribut kann die Qualität der Images eingestellt werden (default "Icon").
+ Im Modus "Full" wird die original vorhandene Auflösung der Images abgerufen. Dies erfordert mehr Ressourcen und kann die
+ Anzeige verlangsamen. Mit "snapGalleryBoost=1" kann die Ausgabe beschleunigt werden, da in diesem Fall die Aufnahmen über
+ Polling abgerufen und nur noch zur Anzeige gebracht werden.
+
- showStmInfoFull
zusaätzliche Streaminformationen wie LiveStreamUrl, StmKeyUnicst, StmKeymjpegHttp werden
ausgegeben
@@ -5489,4 +5964,3 @@ sub experror {
=end html_DE
=cut
-