From 2a2bc2e8122c857e2492face814aefaa8346f483 Mon Sep 17 00:00:00 2001 From: nasseeder1 Date: Fri, 20 Apr 2018 17:25:46 +0000 Subject: [PATCH] 49_SSCam: V3.9.1, PTZ control panel added, please consider attributes "ptzPanel_.*" and command "createPTZcontrol" git-svn-id: https://svn.fhem.de/fhem/trunk@16637 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/FHEM/49_SSCam.pm | 387 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 355 insertions(+), 34 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index d071cdf00..d105ae826 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.9.1, PTZ control panel added, please consider + attributes "ptzPanel_.*" and command "createPTZcontrol" - bugfix: 93_DbRep: V7.17.1, sqlCmd can't use §timestamp_begin§ - feature: 73_GardenaSmartBridge: add set command deleteAccountPassword - change: 88_HMCCU: minor changes diff --git a/fhem/FHEM/49_SSCam.pm b/fhem/FHEM/49_SSCam.pm index d9e481883..8e492a6e5 100644 --- a/fhem/FHEM/49_SSCam.pm +++ b/fhem/FHEM/49_SSCam.pm @@ -27,6 +27,8 @@ ######################################################################################################################### # Versions History: # +# 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 # 3.8.3 05.04.2018 bugfix V3.8.2, $OpMode "Start" changed, composegallery changed # 3.8.2 04.04.2018 $attr replaced by AttrVal, SSCam_wdpollcaminfo redesigned @@ -217,7 +219,7 @@ use Time::HiRes; use HttpUtils; # no if $] >= 5.017011, warnings => 'experimental'; -my $SSCamVersion = "3.8.4"; +my $SSCamVersion = "3.9.1"; # Aufbau Errorcode-Hashes (siehe Surveillance Station Web API) my %SSCam_errauthlist = ( @@ -276,8 +278,8 @@ sub SSCam_Initialize($) { $hash->{GetFn} = "SSCam_Get"; $hash->{AttrFn} = "SSCam_Attr"; # Aufrufe aus FHEMWEB - $hash->{FW_summaryFn} = "SSCam_FWview"; - # $hash->{FW_detailFn} = "SSCam_FWview"; + $hash->{FW_summaryFn} = "SSCam_FWsummaryFn"; + $hash->{FW_detailFn} = "SSCam_FWdetailFn"; $hash->{FW_deviceOverview} = 1; $hash->{AttrList} = @@ -354,7 +356,7 @@ sub SSCam_Define($@) { # Startwerte setzen if(SSCam_IsModelCam($hash)) { - $attr{$name}{webCmd} = "on:off:snap:enable:disable"; # initiale Webkommandos setzen + $attr{$name}{webCmd} = "on:off:snap:enable:disable:runView:stopView"; # initiale Webkommandos setzen } else { $attr{$name}{webCmd} = "homeMode"; $attr{$name}{webCmdLabel} = "HomeMode"; @@ -363,6 +365,7 @@ sub SSCam_Define($@) { $hash->{HELPER}{OLDVALPOLLNOLOGGING} = "0"; # Loggingfunktion für Polling ist an $hash->{HELPER}{OLDVALPOLL} = "0"; $hash->{HELPER}{RECTIME_DEF} = "15"; # Standard für rectime setzen, überschreibbar durch Attribut "rectime" bzw. beim "set .. on-for-time" + $hash->{".ptzhtml"} = ""; readingsBeginUpdate($hash); readingsBulkUpdate($hash,"PollState","Inactive"); # es ist keine Gerätepolling aktiv @@ -416,6 +419,20 @@ sub SSCam_Attr($$$$) { # $name is device name # aName and aVal are Attribute name and value + # dynamisch PTZ-Attribute setzen (wichtig beim Start wenn Reading "DeviceType" nicht gesetzt ist) + if ($cmd eq "set" && ($aName =~ m/ptzPanel_.*/)) { + foreach my $n (0..9) { + $n = sprintf("%2.2d",$n); + addToDevAttrList($name, "ptzPanel_row$n"); + } + addToDevAttrList($name, "ptzPanel_iconPrefix"); + addToDevAttrList($name, "ptzPanel_iconPath"); + } + + if($aName =~ m/ptzPanel_row.*|ptzPanel_Home|ptzPanel_use/) { + InternalTimer(gettimeofday()+0.7, "SSCam_addptzattr", "$name", 0); + } + if ($aName eq "disable") { if($cmd eq "set") { $do = ($aVal) ? 1 : 0; @@ -547,8 +564,7 @@ sub SSCam_Attr($$$$) { if(AttrVal($name,"snapGalleryBoost",0)); } } - - + return undef; } @@ -581,6 +597,7 @@ sub SSCam_Set($@) { "snap:noArg ". (AttrVal($name, "snapGalleryBoost",0)?(AttrVal($name,"snapGalleryNumber",undef) || AttrVal($name,"snapGalleryBoost",0))?"snapGallery:noArg ":"snapGallery:$SSCAM_snum ":" "). "createSnapGallery:noArg ". + ((ReadingsVal("$name", "CapPTZPan", "false") ne "false") ? "createPTZcontrol:noArg ": ""). "enable:noArg ". "disable:noArg ". "optimizeParams ". @@ -672,8 +689,18 @@ 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 new 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\"";} + my $ptzcdev = "SSCam.$name.PTZcontrol"; + my $ret = CommandDefine($hash->{CL},"$ptzcdev weblink htmlCode {SSCam_ptzpanel('$name')}"); + return $ret if($ret); + my $room = AttrVal($name,"room","PTZcontrol"); + $attr{$ptzcdev}{room} = $room; + $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 "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); @@ -714,6 +741,10 @@ sub SSCam_Set($@) { if($success) { SSCam_getcaminfoall($hash,0); + RemoveInternalTimer($hash, "SSCam_getptzlistpreset"); + InternalTimer(gettimeofday()+11, "SSCam_getptzlistpreset", $hash, 0); + RemoveInternalTimer($hash, "SSCam_getptzlistpatrol"); + InternalTimer(gettimeofday()+12, "SSCam_getptzlistpatrol", $hash, 0); return "Username and Password saved successfully"; } else { return "Error while saving Username / Password - see logfile for details"; @@ -1043,19 +1074,19 @@ return $ret; # not generate trigger out of command ###################################################################################### # wird von FW aufgerufen. $FW_wname = aufrufende Webinstanz, $d = aufrufendes # Device (z.B. CamCP1) -sub SSCam_FWview ($$$$) { +sub SSCam_FWsummaryFn ($$$$) { my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn in FHEMWEB - my $hash = $defs{$d}; - my $name = $hash->{NAME}; - my $link = $hash->{HELPER}{LINK}; - my $wltype = $hash->{HELPER}{WLTYPE}; + my $hash = $defs{$d}; + my $name = $hash->{NAME}; + my $link = $hash->{HELPER}{LINK}; + my $wltype = $hash->{HELPER}{WLTYPE}; my $ret; my $alias; return if(!$hash->{HELPER}{LINK} || ReadingsVal("$name", "state", "") =~ /^dis.*/ || IsDisabled($name)); my $attr = AttrVal($d, "htmlattr", " "); - Log3($name, 4, "$name - SSCam_FWview called - FW_wname: $FW_wname, device: $d, room: $room, attributes: $attr"); + Log3($name, 4, "$name - SSCam_FWsummaryFn called - FW_wname: $FW_wname, device: $d, room: $room, attributes: $attr"); if($wltype eq "image") { $ret = "
".weblink_FwDetail($d); @@ -1076,6 +1107,24 @@ sub SSCam_FWview ($$$$) { return $ret; } +###################################################################################### +# PTZ-Steuerpanel in Detailanzeige darstellen +###################################################################################### +sub SSCam_FWdetailFn ($$$$) { + my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn. + my $hash = $defs{$d}; + + return undef if(!AttrVal($d,"ptzPanel_use",1)); + $hash->{".ptzhtml"} = SSCam_ptzpanel($d) if($hash->{".ptzhtml"} eq ""); + + if($hash->{".ptzhtml"} ne "") { + return $hash->{".ptzhtml"}; + } else { + return undef; + } + +} + ###################################################################################### # initiale Startroutinen nach Restart FHEM ###################################################################################### @@ -3552,7 +3601,7 @@ sub SSCam_camop ($) { $url = "http://$serveraddr:$serverport/webapi/$apistmpath?api=$apistm&version=$apistmmaxver&method=EventStream&eventId=$hash->{HELPER}{CAMLASTRECID}×tamp=1&_sid=$sid"; } - # Liveview-Link in Hash speichern -> Anzeige über SSCam_FWview, in Reading setzen für Linkversand + # Liveview-Link in Hash speichern -> Anzeige über SSCam_FWsummaryFn, in Reading setzen für Linkversand $hash->{HELPER}{LINK} = $url; Log3($name, 4, "$name - Set Streaming-URL: $url"); @@ -4622,8 +4671,10 @@ sub SSCam_camop_parse ($) { readingsBulkUpdate($hash,"Errorcode","none"); readingsBulkUpdate($hash,"Error","none"); readingsEndUpdate($hash, 1); - - + + # spezifische Attribute für PTZ-Cams verfügbar machen + SSCam_addptzattr($name); + # Logausgabe Log3($name, $verbose, "$name - PTZ Presets of camera $camname retrieved"); @@ -4991,7 +5042,7 @@ return($hash,$success); } ############################################################################### -# Test ob MODEL=CAM (sonst ist es SVS) +# Test ob MODEL=SVS (sonst ist es eine Cam) ############################################################################### sub SSCam_IsModelCam($){ my ($hash)= @_; @@ -5114,6 +5165,142 @@ sub SSCam_getclhash ($;$$) { return ($ret); } +############################################################################### +# konvertiere alle ptzPanel_rowXX-attribute zu html-Code für +# das generierte Widget und das weblink-Device ptzpanel_$name +############################################################################### +sub SSCam_ptzpanel($) { + my ($name) = @_; + my $hash = $defs{$name}; + my $iconpath = AttrVal("$name","ptzPanel_iconPath","www/images/sscam"); + my $iconprefix = AttrVal("$name","ptzPanel_iconPrefix","black_btn_"); + my $rowisset = 0; + my $ptz_ret; + my $row; + + my @vl = split (/\.|-/,ReadingsVal($name, "SVSversion", "")); + if(@vl) { + my $actvs = $vl[0]; + $actvs .= $vl[1]; + return "" if($actvs <= 71); + } + + $ptz_ret = "
"; + $ptz_ret.= ''; + + foreach my $rownr (0..9) { + $rownr = sprintf("%2.2d",$rownr); + $row = AttrVal("$name","ptzPanel_row$rownr",undef); + next if (!$row); + $rowisset = 1; + $ptz_ret .= "\n"; + my @btn = split (",",$row); # die Anzahl Buttons in einer Reihe + + foreach my $btnnr (0..$#btn) { + $ptz_ret .= '"; + $ptz_ret .= "\n"; + } + $ptz_ret .= "\n"; + } + + $ptz_ret .= "
'; + if ($btn[$btnnr] ne "") { + my $cmd; + my $img; + if ($btn[$btnnr] =~ /(.*?):(.*)/) { # enthält Komando -> : + $cmd = $1; + $img = $2; + } else { # button has format or is empty + $cmd = $btn[$btnnr]; + $img = $btn[$btnnr]; + } + if ($img =~ m/\.svg/) { # Verwendung für SVG's + $img = FW_makeImage($img, $cmd, "rc-button"); + } else { + $img = ""; # $FW_ME = URL-Pfad unter dem der FHEMWEB-Server via HTTP erreichbar ist, z.B. /fhem + } + if ($cmd || $cmd eq "0") { + # $cmd = "cmd.$name=set $name $cmd"; + $cmd = "cmd=set $name $cmd"; + $ptz_ret .= "$img"; # $FW_subdir = Sub-path in URL, used by FLOORPLAN/weblink + } else { + $ptz_ret .= $img; + } + } + $ptz_ret .= "
"; + $ptz_ret .= "
"; + + if ($rowisset) { + return $ptz_ret; + } else { + return ""; + } +} + +############################################################################### +# spezielle Attribute für PTZ-ControlPanel verfügbar machen +############################################################################### +sub SSCam_addptzattr($) { + my ($name) = @_; + my $hash = $defs{$name}; + my $actvs; + + my @vl = split (/\.|-/,ReadingsVal($name, "SVSversion", "")); + if(@vl) { + $actvs = $vl[0]; + $actvs.= $vl[1]; + } + return if(ReadingsVal($name,"DeviceType","Camera") ne "PTZ" || $actvs <= 71); + + foreach my $n (0..9) { + $n = sprintf("%2.2d",$n); + addToDevAttrList($name, "ptzPanel_row$n"); + } + if(ReadingsVal("$name","Presets","") ne "") { + $attr{$name}{userattr} =~ s/ptzPanel_Home:$hash->{HELPER}{OLDPRESETS}//g if($hash->{HELPER}{OLDPRESETS} && ReadingsVal("$name","Presets","") ne $hash->{HELPER}{OLDPRESETS}); + $hash->{HELPER}{OLDPRESETS} = ReadingsVal("$name","Presets",""); + addToDevAttrList($name, "ptzPanel_Home:".ReadingsVal("$name","Presets","")); + } + addToDevAttrList($name, "ptzPanel_iconPrefix"); + addToDevAttrList($name, "ptzPanel_iconPath"); + addToDevAttrList($name, "ptzPanel_use:0,1"); + + # PTZ Panel Widget initial generieren + my $upleftfast = "move upleft"; + my $upfast = "move up"; + my $uprightfast = "move upright"; + my $upleft = "move upleft 0.5"; + my $up = "move up 0.5"; + my $upright = "move upright 0.5"; + my $leftfast = "move left"; + my $left = "move left 0.5"; + my $home = "goPreset ".AttrVal($name,"ptzPanel_Home",ReadingsVal($name,"PresetHome","")); + my $right = "move right 0.5"; + my $rightfast = "move right"; + my $downleft = "move downleft 0.5"; + my $down = "move down 0.5"; + my $downright = "move downright 0.5"; + my $downleftfast = "move downleft"; + my $downfast = "move down"; + my $downrightfast = "move downright"; + + $attr{$name}{ptzPanel_row00} = "$upleftfast:CAMUPLEFTFAST.png,:CAMBLANK.png,$upfast:CAMUPFAST.png,:CAMBLANK.png,$uprightfast:CAMUPRIGHTFAST.png" + if(!AttrVal($name,"ptzPanel_row00",undef)); + $attr{$name}{ptzPanel_row01} = ":CAMBLANK.png,$upleft:CAMUPLEFT.png,$up:CAMUP.png,$upright:CAMUPRIGHT.png" + if(!AttrVal($name,"ptzPanel_row01",undef)); + $attr{$name}{ptzPanel_row02} = "$leftfast:CAMLEFTFAST.png,$left:CAMLEFT.png,$home:CAMHOME.png,$right:CAMRIGHT.png,$rightfast:CAMRIGHTFAST.png" + if(!AttrVal($name,"ptzPanel_row02",undef) || $home ne $hash->{HELPER}{OLDPTZHOME}); + $attr{$name}{ptzPanel_row03} = ":CAMBLANK.png,$downleft:CAMDOWNLEFT.png,$down:CAMDOWN.png,$downright:CAMDOWNRIGHT.png" + if(!AttrVal($name,"ptzPanel_row03",undef)); + $attr{$name}{ptzPanel_row04} = "$downleftfast:CAMDOWNLEFTFAST.png,:CAMBLANK.png,$downfast:CAMDOWNFAST.png,:CAMBLANK.png,$downrightfast:CAMDOWNRIGHTFAST.png" + if(!AttrVal($name,"ptzPanel_row04",undef)); + + $hash->{HELPER}{OLDPTZHOME} = $home; + $hash->{".ptzhtml"} = ""; # SSCam_ptzpanel wird neu durchlaufen + +return; +} + ############################################################################### # Schnappschußgalerie zusammenstellen ############################################################################### @@ -5279,6 +5466,7 @@ sub SSCam_experror {
  • 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)

  • @@ -5312,8 +5500,8 @@ sub SSCam_experror { Credentials

    + + +
    @@ -6362,6 +6614,8 @@ http(s)://<hostname><port>/webapi/entry.cgi?api=SYNO.SurveillanceSta Vorbereitung

    + + Definition Credentials

    +