diff --git a/fhem/CHANGED b/fhem/CHANGED index 685c8b3b3..baec8b562 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: V3.10.0, CreateStreamDev added, new lastrec_fw_MJPEG, + lastrec_fw_MPEG4/H.264 playback MPEG4/H.264 recordings - feature: 93_DbRep: V7.17.3, writeToDB - readingname can be replaced by the value of attribute "readingNameMap" - change: 88_xs1Bridge: documentation | xs1 with password diff --git a/fhem/FHEM/49_SSCam.pm b/fhem/FHEM/49_SSCam.pm index 2a0d69f0c..bea0c6cb5 100644 --- a/fhem/FHEM/49_SSCam.pm +++ b/fhem/FHEM/49_SSCam.pm @@ -27,6 +27,9 @@ ######################################################################################################################### # Versions History: # +# 3.10.0 24.04.2018 CreateStreamDev added, new features lastrec_fw_MJPEG, lastrec_fw_MPEG4/H.264 added to +# playback MPEG4/H.264 videos +# 3.9.2 21.04.2018 minor fixes # 3.9.1 20.04.2018 Attribute ptzPanel_use, initial webcommands in DeviceOverview changed, minor fixes ptzPanel # 3.9.0 17.04.2018 control panel & PTZcontrol weblink device for PTZ cams # 3.8.4 06.04.2018 Internal MODEL changed to SVS or "CamVendor - CamModel" for Cams @@ -219,7 +222,7 @@ use Time::HiRes; use HttpUtils; # no if $] >= 5.017011, warnings => 'experimental'; -my $SSCamVersion = "3.9.1"; +my $SSCamVersion = "3.10.0"; # Aufbau Errorcode-Hashes (siehe Surveillance Station Web API) my %SSCam_errauthlist = ( @@ -339,18 +342,18 @@ sub SSCam_Define($@) { # benötigte API's in $hash einfügen $hash->{HELPER}{APIINFO} = "SYNO.API.Info"; # Info-Seite für alle API's, einzige statische Seite ! - $hash->{HELPER}{APIAUTH} = "SYNO.API.Auth"; + $hash->{HELPER}{APIAUTH} = "SYNO.API.Auth"; # API used to perform session login and logout $hash->{HELPER}{APISVSINFO} = "SYNO.SurveillanceStation.Info"; $hash->{HELPER}{APIEVENT} = "SYNO.SurveillanceStation.Event"; $hash->{HELPER}{APIEXTREC} = "SYNO.SurveillanceStation.ExternalRecording"; $hash->{HELPER}{APIEXTEVT} = "SYNO.SurveillanceStation.ExternalEvent"; - $hash->{HELPER}{APICAM} = "SYNO.SurveillanceStation.Camera"; + $hash->{HELPER}{APICAM} = "SYNO.SurveillanceStation.Camera"; # This API provides a set of methods to acquire camera-related information and to enable/disable cameras $hash->{HELPER}{APISNAPSHOT} = "SYNO.SurveillanceStation.SnapShot"; $hash->{HELPER}{APIPTZ} = "SYNO.SurveillanceStation.PTZ"; $hash->{HELPER}{APIPRESET} = "SYNO.SurveillanceStation.PTZ.Preset"; $hash->{HELPER}{APICAMEVENT} = "SYNO.SurveillanceStation.Camera.Event"; - $hash->{HELPER}{APIVIDEOSTM} = "SYNO.SurveillanceStation.VideoStreaming"; - $hash->{HELPER}{APISTM} = "SYNO.SurveillanceStation.Streaming"; + $hash->{HELPER}{APIVIDEOSTM} = "SYNO.SurveillanceStation.VideoStreaming"; # wird verwendet in Response von "SYNO.SurveillanceStation.Camera: GetLiveViewPath" + $hash->{HELPER}{APISTM} = "SYNO.SurveillanceStation.Streaming"; # This API provides methods to get Live View or Event video stream $hash->{HELPER}{APIHM} = "SYNO.SurveillanceStation.HomeMode"; $hash->{HELPER}{APILOG} = "SYNO.SurveillanceStation.Log"; @@ -598,11 +601,12 @@ sub SSCam_Set($@) { "snap:noArg ". (AttrVal($name, "snapGalleryBoost",0)?(AttrVal($name,"snapGalleryNumber",undef) || AttrVal($name,"snapGalleryBoost",0))?"snapGallery:noArg ":"snapGallery:$SSCAM_snum ":" "). "createSnapGallery:noArg ". + "createStreamDev:mjpeg,switched ". ((ReadingsVal("$name", "CapPTZPan", "false") ne "false") ? "createPTZcontrol:noArg ": ""). "enable:noArg ". "disable:noArg ". "optimizeParams ". - "runView:live_fw,live_link,live_open,lastrec_fw,lastrec_open,lastsnap_fw ". + "runView:live_fw,live_link,live_open,lastrec_fw,lastrec_fw_MJPEG,lastrec_fw_MPEG4/H.264,lastrec_open,lastsnap_fw ". ((ReadingsVal("$name", "CapPTZPan", "false") ne "false") ? "setPreset ": ""). ((ReadingsVal("$name", "CapPTZPan", "false") ne "false") ? "setHome:---currentPosition---,".ReadingsVal("$name","Presets","")." " : ""). "stopView:noArg ". @@ -690,7 +694,7 @@ sub SSCam_Set($@) { 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 !"; + 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 device !"; } elsif ($opt eq "createPTZcontrol" && SSCam_IsModelCam($hash)) { if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";} @@ -702,6 +706,25 @@ sub SSCam_Set($@) { $attr{$ptzcdev}{group} = $name."_PTZcontrol"; return "PTZ control device \"$ptzcdev\" was created successfully. Please have a look to room \"$room\".\nYou can assign \"$ptzcdev\" to another room if you want."; + } elsif ($opt eq "createStreamDev" && SSCam_IsModelCam($hash)) { + if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";} + my ($livedev,$ret); + + if($prop =~ /mjpeg/) { + $livedev = "SSCam.$name.mjpeg"; + $ret = CommandDefine($hash->{CL},"$livedev weblink htmlCode {SSCam_StreamDev('$name','$livedev','mjpeg')}"); + return $ret if($ret); + } + if($prop =~ /switched/) { + $livedev = "SSCam.$name.switched"; + $ret = CommandDefine($hash->{CL},"$livedev weblink htmlCode {SSCam_StreamDev('$name','$livedev','switched')}"); + return $ret if($ret); + } + + my $room = AttrVal($name,"room","PTZcontrol"); + $attr{$livedev}{room} = $room; + return "Livestream device \"$livedev\" was created successfully. Please have a look to room \"$room\".\nYou can assign \"$livedev\" to another room if you want but please don't rename the device."; + } elsif ($opt eq "enable" && SSCam_IsModelCam($hash)) { if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";} SSCam_camenable($hash); @@ -867,11 +890,21 @@ sub SSCam_Set($@) { $hash->{HELPER}{WLTYPE} = "link"; $hash->{HELPER}{ALIAS} = "LastRecording"; $hash->{HELPER}{RUNVIEW} = "lastrec_open"; - } elsif ($prop eq "lastrec_fw") { + } elsif ($prop eq "lastrec_fw") { # Video in iFrame eingebettet $hash->{HELPER}{OPENWINDOW} = 0; $hash->{HELPER}{WLTYPE} = "iframe"; $hash->{HELPER}{ALIAS} = " "; $hash->{HELPER}{RUNVIEW} = "lastrec"; + } elsif ($prop eq "lastrec_fw_MJPEG") { # “video/avi” – MJPEG format event + $hash->{HELPER}{OPENWINDOW} = 0; + $hash->{HELPER}{WLTYPE} = "image"; + $hash->{HELPER}{ALIAS} = " "; + $hash->{HELPER}{RUNVIEW} = "lastrec"; + } elsif ($prop eq "lastrec_fw_MPEG4/H.264") { # “video/mp4” – MPEG4/H.264 format event + $hash->{HELPER}{OPENWINDOW} = 0; + $hash->{HELPER}{WLTYPE} = "video"; + $hash->{HELPER}{ALIAS} = " "; + $hash->{HELPER}{RUNVIEW} = "lastrec"; } elsif ($prop eq "live_fw") { $hash->{HELPER}{OPENWINDOW} = 0; $hash->{HELPER}{WLTYPE} = "image"; @@ -1091,9 +1124,12 @@ sub SSCam_FWsummaryFn ($$$$) { if($wltype eq "image") { $ret = "
".weblink_FwDetail($d); - + } elsif($wltype eq "iframe") { - $ret = "".weblink_FwDetail($d); + $ret = "".weblink_FwDetail($d); + + } elsif($wltype eq "embed") { + $ret = "".weblink_FwDetail($d); } elsif($wltype eq "link") { $alias = $hash->{HELPER}{ALIAS}; @@ -1102,9 +1138,16 @@ sub SSCam_FWsummaryFn ($$$$) { } elsif($wltype eq "base64img") { $alias = $hash->{HELPER}{ALIAS}; $ret = "$alias
"; - } - - # FW_directNotify("FILTER=room=$room", "#FHEMWEB:$FW_wname", "location.reload('true')", "") if($d eq $name); + + } elsif($wltype eq "video") { + $ret = "".weblink_FwDetail($d); + } +#FW_directNotify("FILTER=room=$room", "#FHEMWEB:$FW_wname", "location.reload('true')", "") if($d eq $name); return $ret; } @@ -1969,9 +2012,8 @@ sub SSCam_stopliveview ($) { readingsSingleUpdate($hash,"state","stopview",1); # Aufnahmestatus im state abbilden - my $st; - (ReadingsVal("$name", "Record", "") eq "Start")?$st="on":$st="off"; - readingsSingleUpdate($hash,"state", $st, 1); + my $st = (ReadingsVal("$name", "Record", "Stop") eq "Start")?"on":"off"; + readingsSingleUpdate($hash,"state", $st, 1); $hash->{HELPER}{ACTIVE} = "off"; if (AttrVal($name,"debugactivetoken",0)) { @@ -2012,9 +2054,9 @@ sub SSCam_extevent ($) { # PTZ-Kamera auf Position fahren ############################################################################### sub SSCam_doptzaction ($) { - my ($hash) = @_; - my $camname = $hash->{CAMNAME}; - my $name = $hash->{NAME}; + my ($hash) = @_; + my $camname = $hash->{CAMNAME}; + my $name = $hash->{NAME}; my $errorcode; my $error; @@ -3372,7 +3414,6 @@ sub SSCam_camop ($) { # Preset wird angefahren $apiptzmaxver = ($apiptzmaxver >= 5)?4:$apiptzmaxver; $url = "http://$serveraddr:$serverport/webapi/$apiptzpath?api=\"$apiptz\"&version=\"$apiptzmaxver\"&method=\"GoPreset\"&position=\"$hash->{HELPER}{ALLPRESETS}{$hash->{HELPER}{GOPRESETNAME}}\"&cameraId=\"$camid\"&_sid=\"$sid\""; - readingsSingleUpdate($hash,"state", "moving", 0); } elsif ($OpMode eq "getPresets") { # Liste der Presets abrufen @@ -3413,15 +3454,13 @@ sub SSCam_camop ($) { } elsif ($OpMode eq "runpatrol") { # eine Überwachungstour starten $url = "http://$serveraddr:$serverport/webapi/$apiptzpath?api=\"$apiptz\"&version=\"$apiptzmaxver\"&method=\"RunPatrol\"&patrolId=\"$hash->{HELPER}{ALLPATROLS}{$hash->{HELPER}{GOPATROLNAME}}\"&cameraId=\"$camid\"&_sid=\"$sid\""; - readingsSingleUpdate($hash,"state", "moving", 0); } elsif ($OpMode eq "goabsptz") { $url = "http://$serveraddr:$serverport/webapi/$apiptzpath?api=\"$apiptz\"&version=\"$apiptzmaxver\"&method=\"AbsPtz\"&cameraId=\"$camid\"&posX=\"$hash->{HELPER}{GOPTZPOSX}\"&posY=\"$hash->{HELPER}{GOPTZPOSY}\"&_sid=\"$sid\""; - readingsSingleUpdate($hash,"state", "moving", 0); } elsif ($OpMode eq "movestart") { $url = "http://$serveraddr:$serverport/webapi/$apiptzpath?api=\"$apiptz\"&version=\"$apiptzmaxver\"&method=\"Move\"&cameraId=\"$camid\"&direction=\"$hash->{HELPER}{GOMOVEDIR}\"&speed=\"3\"&moveType=\"Start\"&_sid=\"$sid\""; - + } elsif ($OpMode eq "movestop") { Log3($name, 4, "$name - Stop Camera $hash->{CAMNAME} moving to direction \"$hash->{HELPER}{GOMOVEDIR}\" now"); $url = "http://$serveraddr:$serverport/webapi/$apiptzpath?api=\"$apiptz\"&version=\"$apiptzmaxver\"&method=\"Move\"&cameraId=\"$camid\"&direction=\"$hash->{HELPER}{GOMOVEDIR}\"&moveType=\"Stop\"&_sid=\"$sid\""; @@ -3591,12 +3630,11 @@ sub SSCam_camop ($) { } elsif ($OpMode eq "runliveview" && $hash->{HELPER}{RUNVIEW} !~ /snap/) { if ($hash->{HELPER}{RUNVIEW} =~ m/live/) { # externe URL - $livestream = !AttrVal($name, "livestreamprefix", undef) ? "http://$serveraddr:$serverport" : AttrVal($name, "livestreamprefix", undef); + $livestream = AttrVal($name, "livestreamprefix", "http://$serveraddr:$serverport"); $livestream .= "/webapi/$apivideostmpath?api=$apivideostm&version=$apivideostmmaxver&method=Stream&cameraId=$camid&format=mjpeg&_sid=\"$sid\""; + readingsSingleUpdate($hash,"LiveStreamUrl", $livestream, 1) if(AttrVal($name, "showStmInfoFull", undef)); # interne URL $url = "http://$serveraddr:$serverport/webapi/$apivideostmpath?api=$apivideostm&version=$apivideostmmaxver&method=Stream&cameraId=$camid&format=mjpeg&_sid=\"$sid\""; - - readingsSingleUpdate($hash,"LiveStreamUrl", $livestream, 1) if(AttrVal($name, "showStmInfoFull", undef)); } else { # Abspielen der letzten Aufnahme (EventId) $url = "http://$serveraddr:$serverport/webapi/$apistmpath?api=$apistm&version=$apistmmaxver&method=EventStream&eventId=$hash->{HELPER}{CAMLASTRECID}×tamp=1&_sid=$sid"; @@ -4090,11 +4128,9 @@ sub SSCam_camop_parse ($) { } elsif ($OpMode eq "gopreset") { # eine Presetposition wurde angefahren # 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", "Stop") eq "Start")?"on":"off"; + readingsSingleUpdate($hash,"state", $st, 0); + DoTrigger($name,"move stop"); readingsBeginUpdate($hash); readingsBulkUpdate($hash,"Errorcode","none"); @@ -4107,11 +4143,9 @@ sub SSCam_camop_parse ($) { } elsif ($OpMode eq "runpatrol") { # eine Tour wurde gestartet # 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", "Stop") eq "Start")?"on":"off"; + readingsSingleUpdate($hash,"state", $st, 0); + DoTrigger($name,"patrol started"); readingsBeginUpdate($hash); readingsBulkUpdate($hash,"Errorcode","none"); @@ -4124,11 +4158,9 @@ sub SSCam_camop_parse ($) { } elsif ($OpMode eq "goabsptz") { # eine absolute PTZ-Position wurde angefahren # 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", "Stop") eq "Start")?"on":"off"; + readingsSingleUpdate($hash,"state", $st, 0); + DoTrigger($name,"move stop"); readingsBeginUpdate($hash); readingsBulkUpdate($hash,"Errorcode","none"); @@ -4162,9 +4194,8 @@ sub SSCam_camop_parse ($) { } elsif ($OpMode eq "movestart") { # ein "Move" in eine bestimmte Richtung wird durchgeführt - + readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"state","moving"); readingsBulkUpdate($hash,"Errorcode","none"); readingsBulkUpdate($hash,"Error","none"); readingsEndUpdate($hash, 1); @@ -4178,19 +4209,15 @@ sub SSCam_camop_parse ($) { } elsif ($OpMode eq "movestop") { # ein "Move" in eine bestimmte Richtung wurde durchgeführt # 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", "Stop") eq "Start")?"on":"off"; + readingsSingleUpdate($hash,"state", $st, 0); + DoTrigger($name,"move stop"); readingsBeginUpdate($hash); readingsBulkUpdate($hash,"Errorcode","none"); readingsBulkUpdate($hash,"Error","none"); readingsEndUpdate($hash, 1); - # Logausgabe Log3($name, 3, "$name - Camera $camname stopped move to direction \"$hash->{HELPER}{GOMOVEDIR}\""); } elsif ($OpMode eq "Enable") { @@ -4393,7 +4420,7 @@ sub SSCam_camop_parse ($) { my $rotate = $data->{'data'}->{'cameras'}->[0]->{'video_rotation'}; $rotate = $rotate == 1?"true":"false"; - $exposuremode = $data->{'data'}->{'cameras'}->[0]->{'exposure_mode'}; + $exposuremode = SSCam_jboolmap($data->{'data'}->{'cameras'}->[0]->{'exposure_mode'}); if ($exposuremode == 0) { $exposuremode = "Auto"; } elsif ($exposuremode == 1) { @@ -4406,7 +4433,7 @@ sub SSCam_camop_parse ($) { $exposuremode = "Unknown"; } - $exposurecontrol = $data->{'data'}->{'cameras'}->[0]->{'exposure_control'}; + $exposurecontrol = SSCam_jboolmap($data->{'data'}->{'cameras'}->[0]->{'exposure_control'}); if ($exposurecontrol == 0) { $exposurecontrol = "Auto"; } elsif ($exposurecontrol == 1) { @@ -5302,6 +5329,90 @@ sub SSCam_addptzattr($) { return; } +###################################################################################### +# Stream einer Kamera - Kamera Liveview weblink device +# API: SYNO.SurveillanceStation.VideoStreaming +# Methode: GetLiveViewPath +###################################################################################### +sub SSCam_StreamDev($$$) { + my ($camname,$livdev,$fmt) = @_; + my $hash = $defs{$camname}; + my $wltype = $hash->{HELPER}{WLTYPE}; + my $serveraddr = $hash->{SERVERADDR}; + my $serverport = $hash->{SERVERPORT}; + my $apivideostm = $hash->{HELPER}{APIVIDEOSTM}; + my $apivideostmpath = $hash->{HELPER}{APIVIDEOSTMPATH}; + my $apivideostmmaxver = $hash->{HELPER}{APIVIDEOSTMMAXVER}; + my $camid = $hash->{CAMID}; + my ($cause,$ret,$link,$devWlink,$wlhash,$alias,$wlalias); + + my $ha = AttrVal($camname, "htmlattr", 'width="500" height="325"'); + my $StmKey = ReadingsVal($camname,"StmKey",undef); + + $wlalias = AttrVal($livdev, "alias", $livdev); # Linktext als Aliasname oder Devicename setzen + $devWlink = "$wlalias"; + $wlhash = $defs{$livdev}; + $ha = AttrVal($livdev, "htmlattr", $ha); # htmlattr vom weblink-Device übernehmen oder von Cam + + # Document Division + $ret = sprintf("
$devWlink"); + $ret .= ''; + $ret .= ''; + $ret .= ''; + + if(!$StmKey || ReadingsVal($camname, "Availability", "") ne "enabled" || IsDisabled($camname)) { + # Ausgabe bei Fehler + my $cam = AttrVal($camname, "alias", $camname); + $cause = !$StmKey?"Camera $cam has no Reading \"StmKey\" set !":"Camera $cam is disabled !"; + $ret .= ""; + $ret .= ''; + $ret .= ''; + $ret .= '

$cause

'; + $ret .= '
'; + return $ret; + } + + if($fmt =~ /mjpeg/) { + $link = "http://$serveraddr:$serverport/webapi/$apivideostmpath?api=$apivideostm&version=$apivideostmmaxver&method=Stream&format=mjpeg&cameraId=$camid&StmKey=\"$StmKey\""; + $ret .= " "; + } elsif($fmt =~ /switched/) { + my $wltype = $hash->{HELPER}{WLTYPE}; + $link = $hash->{HELPER}{LINK}; + if($link && $wltype =~ /image|iframe|video|base64img|embed/) { + if($wltype =~ /image/) { + $ret .= " "; + } elsif ($wltype =~ /iframe/) { + $ret .= ""; + } elsif ($wltype =~ /video/) { + $ret .= ""; + } elsif($wltype =~ /base64img/) { + $ret .= ""; + } elsif($wltype =~ /embed/) { + $ret .= ""; + } + } else { + my $cam = AttrVal($camname, "alias", $camname); + $cause = "Camera $cam is switched off"; + $ret .= "
$cause

"; + } + }else { + $cause = "Videoformat not supported"; + $ret .= "
$cause

"; + } + + $ret .= ''; + $ret .= ''; + $ret .= ''; + $ret .= ''; + +return $ret; +} + ############################################################################### # Schnappschußgalerie zusammenstellen ############################################################################### @@ -5395,7 +5506,8 @@ return $htmlCode; } ############################################################################## -# Auflösung Errorcodes bei Login / Logout +# Auflösung Errorcodes bei Login / Logout +############################################################################## sub SSCam_experrorauth { # Übernahmewerte sind $hash, $errorcode my ($hash,@errorcode) = @_; @@ -5450,7 +5562,7 @@ sub SSCam_experror {
  • Deaktivate a Camera in Synology Surveillance Station
  • Activate a Camera in Synology Surveillance Station
  • Control of the exposure modes day, night and automatic
  • -
  • switchover the motion detection by camera, by SVS or to deactivate
  • +
  • switchover the motion detection by camera, by SVS or deactivate it
  • control of motion detection parameters sensitivity, threshold, object size and percentage for release
  • Retrieval of Camera Properties (also by Polling) as well as informations about the installed SVS-package
  • Move to a predefined Preset-position (at PTZ-cameras)
  • @@ -5464,10 +5576,12 @@ sub SSCam_experror {
  • switch the Surveillance Station HomeMode on/off and retrieve the HomeModeState
  • show the stored credentials of a device
  • fetch the Surveillance Station Logs, exploit the newest entry as reading
  • +
  • create a gallery of the last 1-10 snapshots (as Popup or in a discrete device)
  • Start/Stop Object Tracking (only supported PTZ-Cams with this capability)
  • set/delete a Preset (at PTZ-cameras)
  • set a Preset or current position as Home Preset (at PTZ-cameras)
  • provides a panel for camera control (at PTZ-cameras)
  • +
  • create a discrete device for streaming (createStreamDev)

  • @@ -5652,6 +5766,25 @@ sub SSCam_experror { The specified set-commands are available for CAM/SVS-devices or only valid for CAM-devices or rather for SVS-Devices. They can be selected in the drop-down-menu of the particular device.

    + +
    @@ -6790,6 +6934,25 @@ http(s)://<hostname><port>/webapi/entry.cgi?api=SYNO.SurveillanceSta Die aufgeführten set-Befehle sind für CAM/SVS-Devices oder nur für CAM-Devices bzw. nur für SVS-Devices gültig. Sie stehen im Drop-Down-Menü des jeweiligen Devices zur Auswahl zur Verfügung.

    + +