diff --git a/fhem/CHANGED b/fhem/CHANGED index d96cc4451..30573383d 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: support of FTUI Widget with SSCamSTRM, new attributes + in SSCamSTRM, some fixes - feature: 71_YAMAHA_NP: Added undocumented reverse-engineered sound functionality :-) (balance, enhancer, equalizer) diff --git a/fhem/FHEM/49_SSCam.pm b/fhem/FHEM/49_SSCam.pm index 468fe1afe..6ecee5ab4 100644 --- a/fhem/FHEM/49_SSCam.pm +++ b/fhem/FHEM/49_SSCam.pm @@ -48,6 +48,11 @@ eval "use FHEM::Meta;1" or my $modMetaAbsent = 1; # Versions History intern our %SSCam_vNotesIntern = ( + "8.16.0" => "14.07.2019 change detail link generation from SSCamSTRM to SSCam ", + "8.15.2" => "14.07.2019 fix order of snaps in snapgallery when adding new snaps, fix english date formating in composegallery, ". + "align center of FTUI table, set compatibility to 8.2.5 ", + "8.15.1" => "11.07.2019 enhancement and bugfixes for refresh of SSCamSTRM devices (integrate FUUID) ", + "8.15.0" => "09.07.2019 support of SSCamSTRM get function and FTUI widget ", "8.14.2" => "28.06.2019 increase get SID timeout to at least 60 s, set compatibility to SVS 8.2.4, improve disable/enable behavior ", "8.14.1" => "23.06.2019 Presets and Patrols containing spaces in its names are replaced by \"_\", deletion of Presets corrected ". "bugfix userattr when changing Prests ", @@ -153,6 +158,7 @@ our %SSCam_vNotesIntern = ( # Versions History extern our %SSCam_vNotesExtern = ( + "8.15.0" => "09.07.2019 support of integrating Streaming-Devices in a SSCam FTUI widget ", "8.14.0" => "01.06.2019 In detailview are buttons provided to open the camera native setup screen or Synology Surveillance Station and the Synology Surveillance Station online help. ", "8.12.0" => "25.03.2019 Delay FHEM shutdown as long as sessions are not terminated, but not longer than global attribute \"maxShutdownDelay\". ", "8.11.0" => "25.02.2019 compatibility set to SVS version 8.2.3, Popup possible for streaming devices of type \"generic\", ". @@ -266,7 +272,7 @@ our %SSCam_vNotesExtern = ( ); # getestete SVS-Version -my $compstat = "8.2.4"; +my $compstat = "8.2.5"; # Aufbau Errorcode-Hashes (siehe Surveillance Station Web API) my %SSCam_errauthlist = ( @@ -326,7 +332,7 @@ our %SSCam_ttips_en = ( ttcmdstop => "Stopp playback of camera "§NAME§"", tthlsreact => "Reactivate HTTP Livestreaming Interface of camera "§NAME§".
The camera is enforced to restart HLS transmission.", ttmjpegrun => "Playback the MJPEG Livestream of camera "§NAME§".", - tthlsrun => "Playback the native HTTP Livestream of camera "§NAME§".", + tthlsrun => "Playback the native HTTP Livestream of camera "§NAME§". The browser must have native support for HLS streaming.", ttlrrun => "Playback of last recording of camera "§NAME§" in an iFrame.
Both MJPEG and H.264 recordings are rendered.", tth264run => "Playback of last H.264 recording of camera "§NAME§".
It only starts if the recording is type H.264", ttlmjpegrun => "Playback of last MJPEG recording of camera "§NAME§".
It only starts if the recording is type MJPEG", @@ -344,7 +350,7 @@ our %SSCam_ttips_de = ( ttcmdstop => "Stopp Wiedergabe von Kamera "§NAME§"", tthlsreact => "Reaktiviert das HTTP Livestreaming Interface von Kamera "§NAME§".
Die Kamera wird aufgefordert die HLS Übertragung zu restarten.", ttmjpegrun => "Wiedergabe des MJPEG Livestreams von Kamera "§NAME§"", - tthlsrun => "Wiedergabe des HTTP Livestreams von Kamera "§NAME§".
Es wird die HLS Funktion der Synology Surveillance Station verwendet.", + tthlsrun => "Wiedergabe des HTTP Livestreams von Kamera "§NAME§".
Es wird die HLS Funktion der Synology Surveillance Station verwendet. (der Browser muss HLS nativ unterstützen)", ttlrrun => "Wiedergabe der letzten Aufnahme von Kamera "§NAME§" in einem iFrame.
Es werden sowohl MJPEG als auch H.264 Aufnahmen wiedergegeben.", tth264run => "Wiedergabe der letzten H.264 Aufnahme von Kamera "§NAME§".
Die Wiedergabe startet nur wenn die Aufnahme vom Typ H.264 ist.", ttlmjpegrun => "Wiedergabe der letzten MJPEG Aufnahme von Kamera "§NAME§".
Die Wiedergabe startet nur wenn die Aufnahme vom Typ MJPEG ist.", @@ -882,11 +888,16 @@ sub SSCam_Set($@) { if (defined($prop) && $prop =~ /^\d+$/) { $hash->{HELPER}{RECTIME_TEMP} = $prop; } + + my $spec = join(" ",@a); + if($spec =~ /STRM:/) { + $spec =~ m/.*STRM:(.*).*/i; # Aufnahme durch SSCamSTRM-Device + $hash->{HELPER}{INFORM} = $1; + } my $emtxt = AttrVal($name, "recEmailTxt", ""); - my $at = join(" ",@a); - if($at =~ /recEmailTxt:/) { - $at =~ m/.*recEmailTxt:"(.*)".*/i; + if($spec =~ /recEmailTxt:/) { + $spec =~ m/.*recEmailTxt:"(.*)".*/i; $emtxt = $1; } @@ -898,9 +909,8 @@ sub SSCam_Set($@) { } my $teletxt = AttrVal($name, "recTelegramTxt", ""); - my $bt = join(" ",@a); - if($bt =~ /recTelegramTxt:/) { - $bt =~ m/.*recTelegramTxt:"(.*)".*/i; + if($spec =~ /recTelegramTxt:/) { + $spec =~ m/.*recTelegramTxt:"(.*)".*/i; $teletxt = $1; } @@ -916,6 +926,13 @@ sub SSCam_Set($@) { if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";} my $emtxt = $hash->{HELPER}{SMTPRECMSG}?delete $hash->{HELPER}{SMTPRECMSG}:""; my $teletxt = $hash->{HELPER}{TELERECMSG}?delete $hash->{HELPER}{TELERECMSG}:""; + + my $spec = join(" ",@a); + if($spec =~ /STRM:/) { + $spec =~ m/.*STRM:(.*).*/i; # Aufnahmestop durch SSCamSTRM-Device + $hash->{HELPER}{INFORM} = $1; + } + SSCam_camstoprec("$name!_!$emtxt!_!$teletxt"); } elsif ($opt eq "snap" && SSCam_IsModelCam($hash)) { @@ -930,13 +947,18 @@ sub SSCam_Set($@) { $lag = $prop1; } - Log3($name, 4, "$name - Trigger snapshots - Number: $num, Lag: $lag"); - $hash->{HELPER}{SNAPBYSTRMDEV} = 1 if ($prop2 && $prop2 =~ /STRM/); # $prop wird mitgegeben durch Snap by SSCamSTRM-Device + Log3($name, 4, "$name - Trigger snapshots - Number: $num, Lag: $lag"); + + my $spec = join(" ",@a); + if($spec =~ /STRM:/) { + $spec =~ m/.*STRM:(.*).*/i; # Snap by SSCamSTRM-Device + $hash->{HELPER}{INFORM} = $1; + $hash->{HELPER}{SNAPBYSTRMDEV} = 1; + } my $emtxt = AttrVal($name, "snapEmailTxt", ""); - my $at = join(" ",@a); - if($at =~ /snapEmailTxt:/) { - $at =~ m/.*snapEmailTxt:"(.*)".*/i; + if($spec =~ /snapEmailTxt:/) { + $spec =~ m/.*snapEmailTxt:"(.*)".*/i; $emtxt = $1; } @@ -948,9 +970,8 @@ sub SSCam_Set($@) { } my $teletxt = AttrVal($name, "snapTelegramTxt", ""); - my $bt = join(" ",@a); - if($bt =~ /snapTelegramTxt:/) { - $bt =~ m/.*snapTelegramTxt:"(.*)".*/i; + if($spec =~ /snapTelegramTxt:/) { + $spec =~ m/.*snapTelegramTxt:"(.*)".*/i; $teletxt = $1; } @@ -1355,65 +1376,72 @@ sub SSCam_Set($@) { } elsif ($opt eq "runView" && 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\"";} - if ($prop eq "live_open") { + + my $spec = join(" ",@a); + if($spec =~ /STRM:/) { + $spec =~ m/.*STRM:(.*).*/i; # Call by SSCamSTRM-Device + $hash->{HELPER}{INFORM} = $1; + } + + 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"; - $hash->{HELPER}{ACTSTRM} = ""; # sprechender Name des laufenden Streamtyps für SSCamSTRM + $hash->{HELPER}{ACTSTRM} = ""; # sprechender Name des laufenden Streamtyps für SSCamSTRM } elsif ($prop eq "live_link") { $hash->{HELPER}{OPENWINDOW} = 0; $hash->{HELPER}{WLTYPE} = "link"; $hash->{HELPER}{ALIAS} = "LiveView"; $hash->{HELPER}{RUNVIEW} = "live_link"; - $hash->{HELPER}{ACTSTRM} = ""; # sprechender Name des laufenden Streamtyps für SSCamSTRM + $hash->{HELPER}{ACTSTRM} = ""; # sprechender Name des laufenden Streamtyps für SSCamSTRM } 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"; - $hash->{HELPER}{ACTSTRM} = ""; # sprechender Name des laufenden Streamtyps für SSCamSTRM - } elsif ($prop eq "lastrec_fw") { # Video in iFrame eingebettet + $hash->{HELPER}{ACTSTRM} = ""; # sprechender Name des laufenden Streamtyps für SSCamSTRM + } elsif ($prop eq "lastrec_fw") { # Video in iFrame eingebettet $hash->{HELPER}{OPENWINDOW} = 0; $hash->{HELPER}{WLTYPE} = "iframe"; $hash->{HELPER}{ALIAS} = " "; $hash->{HELPER}{RUNVIEW} = "lastrec"; - $hash->{HELPER}{ACTSTRM} = "last Recording"; # sprechender Name des laufenden Streamtyps für SSCamSTRM - } elsif ($prop eq "lastrec_fw_MJPEG") { # “video/avi” – MJPEG format event + $hash->{HELPER}{ACTSTRM} = "last Recording"; # sprechender Name des laufenden Streamtyps für SSCamSTRM + } 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"; - $hash->{HELPER}{ACTSTRM} = "last Recording"; # sprechender Name des laufenden Streamtyps für SSCamSTRM - } elsif ($prop eq "lastrec_fw_MPEG4/H.264") { # “video/mp4” – MPEG4/H.264 format event + $hash->{HELPER}{ACTSTRM} = "last Recording"; # sprechender Name des laufenden Streamtyps für SSCamSTRM + } 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"; - $hash->{HELPER}{ACTSTRM} = "last Recording"; # sprechender Name des laufenden Streamtyps für SSCamSTRM + $hash->{HELPER}{ACTSTRM} = "last Recording"; # sprechender Name des laufenden Streamtyps für SSCamSTRM } elsif ($prop eq "live_fw") { $hash->{HELPER}{OPENWINDOW} = 0; $hash->{HELPER}{WLTYPE} = "image"; $hash->{HELPER}{ALIAS} = " "; $hash->{HELPER}{RUNVIEW} = "live_fw"; - $hash->{HELPER}{ACTSTRM} = "MJPEG Livestream"; # sprechender Name des laufenden Streamtyps für SSCamSTRM + $hash->{HELPER}{ACTSTRM} = "MJPEG Livestream"; # sprechender Name des laufenden Streamtyps für SSCamSTRM } elsif ($prop eq "live_fw_hls") { return "API \"SYNO.SurveillanceStation.VideoStream\" is not available or Reading \"CamStreamFormat\" is not \"HLS\". May be your API version is 2.8 or higher." if(!SSCam_IsHLSCap($hash)); $hash->{HELPER}{OPENWINDOW} = 0; $hash->{HELPER}{WLTYPE} = "hls"; $hash->{HELPER}{ALIAS} = "View only on compatible browsers"; $hash->{HELPER}{RUNVIEW} = "live_fw_hls"; - $hash->{HELPER}{ACTSTRM} = "HLS Livestream"; # sprechender Name des laufenden Streamtyps für SSCamSTRM + $hash->{HELPER}{ACTSTRM} = "HLS Livestream"; # sprechender Name des laufenden Streamtyps für SSCamSTRM } elsif ($prop eq "lastsnap_fw") { - $hash->{HELPER}{LSNAPBYSTRMDEV} = 1 if($prop1); # Anzeige durch SSCamSTRM-Device ausgelöst - $hash->{HELPER}{LSNAPBYDEV} = 1 if(!$prop1); # Anzeige durch SSCam ausgelöst - $hash->{HELPER}{OPENWINDOW} = 0; - $hash->{HELPER}{WLTYPE} = "base64img"; - $hash->{HELPER}{ALIAS} = " "; - $hash->{HELPER}{RUNVIEW} = "lastsnap_fw"; - $hash->{HELPER}{ACTSTRM} = "last Snapshot"; # sprechender Name des laufenden Streamtyps für SSCamSTRM + $hash->{HELPER}{LSNAPBYSTRMDEV} = 1 if($prop1); # Anzeige durch SSCamSTRM-Device ausgelöst + $hash->{HELPER}{LSNAPBYDEV} = 1 if(!$prop1); # Anzeige durch SSCam ausgelöst + $hash->{HELPER}{OPENWINDOW} = 0; + $hash->{HELPER}{WLTYPE} = "base64img"; + $hash->{HELPER}{ALIAS} = " "; + $hash->{HELPER}{RUNVIEW} = "lastsnap_fw"; + $hash->{HELPER}{ACTSTRM} = "last Snapshot"; # sprechender Name des laufenden Streamtyps für SSCamSTRM } 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"; } @@ -1427,13 +1455,21 @@ sub SSCam_Set($@) { } elsif ($opt eq "hlsactivate" && SSCam_IsModelCam($hash)) { # ohne SET-Menüeintrag if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";} - SSCam_hlsactivate($hash); + + my $spec = join(" ",@a); + if($spec =~ /STRM:/) { + $spec =~ m/.*STRM:(.*).*/i; # Call by SSCamSTRM-Device + $hash->{HELPER}{INFORM} = $1; + } + SSCam_hlsactivate($hash); } elsif ($opt eq "refresh" && SSCam_IsModelCam($hash)) { # ohne SET-Menüeintrag - if($prop =~ /STRM/) { - # Event in allen SSCamSTRM-Devices erzeugen um Contentwiedergabe aufzufrischen - SSCam_refresh($hash,0,0,1); # kein Room-Refresh, kein SSCam-state-Event, SSCamSTRM-Event + my $spec = join(" ",@a); + if($spec =~ /STRM:/) { + $spec =~ m/.*STRM:(.*).*/i; # Refresh by SSCamSTRM-Device + $hash->{HELPER}{INFORM} = $1; + SSCam_refresh($hash,0,0,1); # kein Room-Refresh, kein SSCam-state-Event, SSCamSTRM-Event } } elsif ($opt eq "extevent" && !SSCam_IsModelCam($hash)) { @@ -1443,6 +1479,12 @@ sub SSCam_Set($@) { } elsif ($opt eq "stopView" && 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 $spec = join(" ",@a); + if($spec =~ /STRM:/) { + $spec =~ m/.*STRM:(.*).*/i; # Stop by SSCamSTRM-Device + $hash->{HELPER}{INFORM} = $1; + } SSCam_stopliveview($hash); } elsif ($opt eq "setPreset" && SSCam_IsModelCam($hash)) { @@ -1906,7 +1948,6 @@ sub SSCam_FWdetailFn ($$$$) { $ret .= $hash->{".setup"}; } - # return undef if(!AttrVal($d,"ptzPanel_use",1)); $hash->{".ptzhtml"} = SSCam_ptzpanel($d) if($hash->{".ptzhtml"} eq ""); if($hash->{".ptzhtml"} ne "" && AttrVal($d,"ptzPanel_use",1)) { @@ -5089,7 +5130,7 @@ sub SSCam_camop_parse ($) { $sendrecs{$sn}{createdTm} = $createdTm; $sendrecs{$sn}{fileName} = $fileName; $sendrecs{$sn}{".imageData"} = $myjson; - Log3($name,4, "$name - Snap '$sn' added to send recording hash: ID => $recid, File => $fileName, Created => $createdTm"); + Log3($name,4, "$name - Recording '$sn' added to send recording hash: ID => $recid, File => $fileName, Created => $createdTm"); # prüfen ob Recording als Email / Telegram versendet werden soll SSCam_prepareSendData ($hash, $OpMode, \%sendrecs); @@ -5442,7 +5483,11 @@ sub SSCam_camop_parse ($) { my $i = 0; my $sn = 0; my %sendsnaps = (); # Schnappschuss Hash zum Versand wird leer erstellt - + + if($hash->{HELPER}{".SNAPHASH"}) { + $hash->{HELPER}{".SNAPHASHOLD"} = delete($hash->{HELPER}{".SNAPHASH"}); + } + while ($data->{'data'}{'data'}[$i]) { if(!$data->{'data'}{'data'}[$i]{'camName'} || $data->{'data'}{'data'}[$i]{'camName'} ne $camname) { # Forum:#97706 $i += 1; @@ -5467,19 +5512,32 @@ sub SSCam_camop_parse ($) { $sendsnaps{$sn}{".imageData"} = $imageData; Log3($name,4, "$name - Snap '$sn' added to send gallery hash: ID => $snapid, File => $fileName, Created => $createdTm"); - # Snaphash um die neuen Snaps ergänzen wenn existent - if($hash->{HELPER}{".SNAPHASH"}{$sn}) { - $hash->{HELPER}{".SNAPHASH"}{$sn}{snapid} = $snapid; - $hash->{HELPER}{".SNAPHASH"}{$sn}{createdTm} = $createdTm; - $hash->{HELPER}{".SNAPHASH"}{$sn}{fileName} = $fileName; - $hash->{HELPER}{".SNAPHASH"}{$sn}{imageData} = $imageData; - Log3($name,4, "$name - Snap '$sn' added to gallery hash: ID => $snapid, File => $fileName, Created => $createdTm"); - } + # Snaphash erstellen + $hash->{HELPER}{".SNAPHASH"}{$sn}{snapid} = $snapid; + $hash->{HELPER}{".SNAPHASH"}{$sn}{createdTm} = $createdTm; + $hash->{HELPER}{".SNAPHASH"}{$sn}{fileName} = $fileName; + $hash->{HELPER}{".SNAPHASH"}{$sn}{imageData} = $imageData; + Log3($name,4, "$name - Snap '$sn' added to gallery hash: ID => $snapid, File => $fileName, Created => $createdTm"); $sn += 1; $i += 1; } + my $sgn = AttrVal($name,"snapGalleryNumber",3); + my $ss = $sn; + $sn = 0; + + if($hash->{HELPER}{".SNAPHASHOLD"} && $sgn > $ss) { + for my $kn ($ss..($sgn-1)) { + $hash->{HELPER}{".SNAPHASH"}{$kn}{snapid} = $hash->{HELPER}{".SNAPHASHOLD"}{$sn}{snapid}; + $hash->{HELPER}{".SNAPHASH"}{$kn}{createdTm} = $hash->{HELPER}{".SNAPHASHOLD"}{$sn}{createdTm}; + $hash->{HELPER}{".SNAPHASH"}{$kn}{fileName} = $hash->{HELPER}{".SNAPHASHOLD"}{$sn}{fileName}; + $hash->{HELPER}{".SNAPHASH"}{$kn}{imageData} = $hash->{HELPER}{".SNAPHASHOLD"}{$sn}{imageData}; + $sn += 1; + } + delete $hash->{HELPER}{".SNAPHASHOLD"}; + } + # prüfen ob Schnappschuß versendet werden soll SSCam_prepareSendData ($hash, $OpMode, \%sendsnaps); @@ -5491,6 +5549,10 @@ sub SSCam_camop_parse ($) { $hash->{HELPER}{TOTALCNT} = $data->{data}{total}; # total Anzahl Schnappschüsse + if($hash->{HELPER}{".SNAPHASH"}) { + $hash->{HELPER}{".SNAPHASHOLD"} = delete($hash->{HELPER}{".SNAPHASH"}); + } + while ($data->{'data'}{'data'}[$i]) { if(!$data->{'data'}{'data'}[$i]{'camName'} || $data->{'data'}{'data'}[$i]{'camName'} ne $camname) { # Forum:#97706 $i += 1; @@ -5508,15 +5570,32 @@ sub SSCam_camop_parse ($) { } else { $createdTm = "$d[0]-$d[1]-$d[2] / $t[1]"; } + + # Snaphash erstellen $hash->{HELPER}{".SNAPHASH"}{$sn}{snapid} = $snapid; $hash->{HELPER}{".SNAPHASH"}{$sn}{createdTm} = $createdTm; $hash->{HELPER}{".SNAPHASH"}{$sn}{fileName} = $fileName; $hash->{HELPER}{".SNAPHASH"}{$sn}{imageData} = $imageData; Log3($name,4, "$name - Snap '$sn' added to gallery hash: ID => $hash->{HELPER}{\".SNAPHASH\"}{$sn}{snapid}, File => $hash->{HELPER}{\".SNAPHASH\"}{$sn}{fileName}, Created => $hash->{HELPER}{\".SNAPHASH\"}{$sn}{createdTm}"); + $sn += 1; $i += 1; } + my $sgn = AttrVal($name,"snapGalleryNumber",3); + my $ss = $sn; + $sn = 0; + if($hash->{HELPER}{".SNAPHASHOLD"} && $sgn > $ss) { + for my $kn ($ss..($sgn-1)) { + $hash->{HELPER}{".SNAPHASH"}{$kn}{snapid} = $hash->{HELPER}{".SNAPHASHOLD"}{$sn}{snapid}; + $hash->{HELPER}{".SNAPHASH"}{$kn}{createdTm} = $hash->{HELPER}{".SNAPHASHOLD"}{$sn}{createdTm}; + $hash->{HELPER}{".SNAPHASH"}{$kn}{fileName} = $hash->{HELPER}{".SNAPHASHOLD"}{$sn}{fileName}; + $hash->{HELPER}{".SNAPHASH"}{$kn}{imageData} = $hash->{HELPER}{".SNAPHASHOLD"}{$sn}{imageData}; + $sn += 1; + } + delete $hash->{HELPER}{".SNAPHASHOLD"}; + } + # Direktausgabe Snaphash wenn nicht gepollt wird if(!AttrVal($name, "snapGalleryBoost",0)) { my $htmlCode = SSCam_composegallery($name); @@ -5539,10 +5618,9 @@ sub SSCam_camop_parse ($) { delete($hash->{HELPER}{GETSNAPGALLERY}); # Steuerbit getsnapgallery statt getsnapinfo ######## fallabhängige Eventgenerierung ######## - if ($hash->{HELPER}{SNAPBYSTRMDEV} || $hash->{HELPER}{LSNAPBYSTRMDEV}) { + if ($hash->{HELPER}{INFORM} || $hash->{HELPER}{LSNAPBYSTRMDEV}) { # Snap durch SSCamSTRM-Device ausgelöst SSCam_refresh($hash,0,0,1); # kein Room-Refresh, kein SSCam-state-Event, SSCamSTRM-Event - delete $hash->{HELPER}{SNAPBYSTRMDEV}; delete $hash->{HELPER}{LSNAPBYSTRMDEV}; } elsif ($hash->{HELPER}{LSNAPBYDEV}) { SSCam_refresh($hash,0,1,0); # kein Room-Refresh, SSCam-state-Event, kein SSCamSTRM-Event @@ -5550,26 +5628,6 @@ sub SSCam_camop_parse ($) { } else { SSCam_refresh($hash,0,0,0); # kein Room-Refresh, SSCam-state-Event, SSCamSTRM-Event } - # longpoll für alle Streamingdevices v. Typ "lastsnap" - my @lsnapstrms = devspec2array("TYPE=SSCamSTRM:FILTER=PARENT=$name:FILTER=MODEL=lastsnap"); - if(scalar(@lsnapstrms) >= 1) { - foreach (@lsnapstrms) { - if($defs{$_}) { - $hash->{HELPER}{STRMDEV} = $_; - SSCam_refresh($hash,0,0,1); # kein Room-Refresh, kein SSCam-state-Event, SSCamSTRM-Event - } - } - } - # longpoll für alle Streamingdevices v. Typ "snapgallery" - @lsnapstrms = devspec2array("TYPE=SSCamSTRM:FILTER=PARENT=$name:FILTER=MODEL=snapgallery"); - if(scalar(@lsnapstrms) >= 1) { - foreach (@lsnapstrms) { - if($defs{$_}) { - $hash->{HELPER}{STRMDEV} = $_; - SSCam_refresh($hash,0,0,1); # kein Room-Refresh, kein SSCam-state-Event, SSCamSTRM-Event - } - } - } } elsif ($OpMode eq "runliveview" && $hash->{HELPER}{RUNVIEW} =~ m/^live_.*hls$/) { # HLS Streaming wurde aktiviert @@ -6653,13 +6711,11 @@ return($hash,$success,$myjson); ###################################################################################################### # Refresh eines Raumes aus $hash->{HELPER}{STRMROOM} -# bzw. Longpoll von SSCam bzw. eines SSCamSTRM Devices wenn -# $hash->{HELPER}{STRMDEV} gefüllt # $hash, $pload (1=Page reload), SSCam-state-Event(1=Event), SSCamSTRM-Event (1=Event) ###################################################################################################### sub SSCam_refresh($$$$) { my ($hash,$pload,$lpoll_scm,$lpoll_strm) = @_; - my $name; + my ($name,$st); if (ref $hash ne "HASH") { ($name,$pload,$lpoll_scm,$lpoll_strm) = split ",",$hash; @@ -6669,48 +6725,53 @@ sub SSCam_refresh($$$$) { } my $fpr = 0; - # Kontext des SSCamSTRM-Devices speichern für Refresh - my $sd = $hash->{HELPER}{STRMDEV}?$hash->{HELPER}{STRMDEV}:"\"n.a.\""; # Name des aufrufenden SSCamSTRM-Devices - my $sr = $hash->{HELPER}{STRMROOM}?$hash->{HELPER}{STRMROOM}:"\"n.a.\""; # Raum aus dem das SSCamSTRM-Device die Funktion aufrief - my $sl = $hash->{HELPER}{STRMDETAIL}?$hash->{HELPER}{STRMDETAIL}:"\"n.a.\""; # Name des SSCamSTRM-Devices (wenn Detailansicht) - $fpr = AttrVal($hash->{HELPER}{STRMDEV},"forcePageRefresh",0) if($hash->{HELPER}{STRMDEV}); - Log3($name, 4, "$name - SSCam_refresh - caller: $sd, callerroom: $sr, detail: $sl, pload: $pload, forcePageRefresh: $fpr, event_STRMdev: $lpoll_strm"); - - # Page-Reload - if($pload && $hash->{HELPER}{STRMROOM} && $hash->{HELPER}{STRMDETAIL}) { - if($hash->{HELPER}{STRMROOM} && !$hash->{HELPER}{STRMDETAIL} && !$fpr) { - Log3($name, 4, "$name - SSCam_refresh jetzt"); - # trifft zu wenn in einer Raumansicht - my @rooms = split(",",$hash->{HELPER}{STRMROOM}); - foreach (@rooms) { - my $room = $_; - { map { FW_directNotify("FILTER=room=$room", "#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") } - } - } elsif ( !$hash->{HELPER}{STRMROOM} || $hash->{HELPER}{STRMDETAIL} || $fpr ) { - # trifft zu bei Detailansicht oder im FLOORPLAN bzw. Dashboard oder wenn Seitenrefresh mit dem - # SSCamSTRM-Attribut "forcePageRefresh" erzwungen wird - { map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") } - } - } elsif ($fpr) { - # Seitenrefresh durch SSCamSTRM-Attribut "forcePageRefresh" erzwungen - { map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") } + # SSCamSTRM-Device mit hinterlegter FUUID ($hash->{HELPER}{INFORM}) selektieren + my @spgs = devspec2array("TYPE=SSCamSTRM"); + my $room = ""; + foreach(@spgs) { + if($defs{$_}{PARENT} eq $name) { + next if(IsDisabled($defs{$_}{NAME}) || !$hash->{HELPER}{INFORM} || $hash->{HELPER}{INFORM} ne $defs{$_}{FUUID}); + $fpr = AttrVal($defs{$_}{NAME},"forcePageRefresh",0); + $room = AttrVal($defs{$_}{NAME},"room",""); + Log3($name, 4, "$name - SSCam_refresh - pagerefresh: $defs{$_}{NAME}") if($fpr); + } } + # Page-Reload + if($pload && $room) { + if(!$fpr) { + # nur Räume mit dem SSCamSTRM-Device reloaden + my @rooms = split(",",$room); + foreach (@rooms) { + my $r = $_; + { map { FW_directNotify("FILTER=room=$r", "#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") } + } + } + } elsif ($pload || $fpr) { + # trifft zu bei Detailansicht oder im FLOORPLAN bzw. Dashboard oder wenn Seitenrefresh mit dem + # SSCamSTRM-Attribut "forcePageRefresh" erzwungen wird + { map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") } + } + # Aufnahmestatus/Disabledstatus in state abbilden & SSCam-Device state setzen (mit/ohne Event) - my $st = (ReadingsVal($name, "Availability", "enabled") eq "disabled")?"disabled":(ReadingsVal($name, "Record", "") eq "Start")?"on":"off"; + $st = (ReadingsVal($name, "Availability", "enabled") eq "disabled")?"disabled":(ReadingsVal($name, "Record", "") eq "Start")?"on":"off"; if($lpoll_scm) { readingsSingleUpdate($hash,"state", $st, 1); } else { readingsSingleUpdate($hash,"state", $st, 0); } - # parentState des SSCamSTRM-Device mit Opmode updaten (mit/ohne Event) - if($hash->{HELPER}{STRMDEV}) { - my $strmhash = $defs{$hash->{HELPER}{STRMDEV}}; - if($lpoll_strm) { - readingsSingleUpdate($strmhash,"parentState", $hash->{OPMODE}, 1); - } else { - readingsSingleUpdate($strmhash,"parentState", $hash->{OPMODE}, 0); + # parentState des SSCamSTRM-Device updaten + $st = ReadingsVal($name, "state", "initialized"); + foreach(@spgs) { + if($defs{$_}{PARENT} eq $name) { + next if(IsDisabled($defs{$_}{NAME}) || !$hash->{HELPER}{INFORM} || $hash->{HELPER}{INFORM} ne $defs{$_}{FUUID}); + readingsBeginUpdate($defs{$_}); + readingsBulkUpdate($defs{$_},"parentState", $st); + readingsBulkUpdate($defs{$_},"state", "updated"); + readingsEndUpdate($defs{$_}, 1); + Log3($name, 4, "$name - SSCam_refresh - caller: $_, FUUID: $hash->{HELPER}{INFORM}"); + delete $hash->{HELPER}{INFORM}; } } @@ -6887,11 +6948,13 @@ 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,$ptzcdev,$ptzcontrol) = @_; +sub SSCam_ptzpanel(@) { + my ($name,$ptzcdev,$ptzcontrol,$ftui) = @_; my $hash = $defs{$name}; my $iconpath = AttrVal("$name","ptzPanel_iconPath","www/images/sscam"); my $iconprefix = AttrVal("$name","ptzPanel_iconPrefix","black_btn_"); + my $pbs = AttrVal("$ptzcdev","ptzButtonSize", 100); # Größe der Druckbuttons in % + my $pbsf = AttrVal("$ptzcdev","ptzButtonSizeFTUI", 100); # Größe der Druckbuttons im FTUI in % my $valPresets = ReadingsVal("$name","Presets",""); my $valPatrols = ReadingsVal("$name","Patrols",""); my $rowisset = 0; @@ -6899,9 +6962,10 @@ sub SSCam_ptzpanel($;$$) { my $row; return "" if(SSCam_myVersion($hash) <= 71); - - $ptz_ret = "
"; - $ptz_ret.= ''; + + $ptz_ret = ""; + $ptz_ret .= ""; + $ptz_ret .= '
'; foreach my $rownr (0..9) { $rownr = sprintf("%2.2d",$rownr); @@ -6912,25 +6976,30 @@ sub SSCam_ptzpanel($;$$) { my @btn = split (",",$row); # die Anzahl Buttons in einer Reihe foreach my $btnnr (0..$#btn) { - $ptz_ret .= '
'; + $ptz_ret .= ''; if ($btn[$btnnr] ne "") { my $cmd; my $img; - if ($btn[$btnnr] =~ /(.*?):(.*)/) { # enthält Komando -> : + if ($btn[$btnnr] =~ /(.*?):(.*)/) { # enthält Komando -> : $cmd = $1; $img = $2; - } else { # button has format or is empty + } else { # button has format or is empty $cmd = $btn[$btnnr]; $img = $btn[$btnnr]; } - if ($img =~ m/\.svg/) { # Verwendung für SVG's + 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 - } + } else { # $FW_ME = URL-Pfad unter dem der FHEMWEB-Server via HTTP erreichbar ist, z.B. /fhem + if($ftui) { + $img = ""; + } else { + $img = ""; + } + } if ($cmd || $cmd eq "0") { - $cmd = "cmd=set $name $cmd"; - $ptz_ret .= "$img"; # $FW_subdir = Sub-path in URL, used by FLOORPLAN/weblink + my $cmd1 = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name $cmd')"; # $FW_subdir = Sub-path in URL, used by FLOORPLAN/weblink + $cmd1 = "ftui.setFhemStatus('set $name $cmd')" if($ftui); + $ptz_ret .= "$img"; } else { $ptz_ret .= $img; } @@ -6942,62 +7011,61 @@ sub SSCam_ptzpanel($;$$) { } $ptz_ret .= "
"; - $ptz_ret .= "
"; ######################## # add Preset & Patrols - - my ($Presets,$Patrols,$fn); - my $cmdPreset = "goPreset"; - my $cmdPatrol = "runPatrol"; - - foreach $fn (sort keys %{$data{webCmdFn}}) { - no strict "refs"; - $Presets = &{$data{webCmdFn}{$fn}}($FW_wname,$name,"",$cmdPreset,$valPresets); - use strict "refs"; - last if(defined($Presets)); - } - if($Presets) { - $Presets =~ s,^]*>(.*)$,$1,; - # Log3($name, 1, "$name - commandArgs: $Presets"); - } else { - $Presets = FW_pH "cmd.$name=set $name $cmdPreset", $cmdPreset, 0, "", 1, 1; - } + if(!$ftui) { + my ($Presets,$Patrols,$fn); + my $cmdPreset = "goPreset"; + my $cmdPatrol = "runPatrol"; + + foreach $fn (sort keys %{$data{webCmdFn}}) { + no strict "refs"; + $Presets = &{$data{webCmdFn}{$fn}}($FW_wname,$name,"",$cmdPreset,$valPresets); + use strict "refs"; + last if(defined($Presets)); + } + if($Presets) { + $Presets =~ s,^]*>(.*)$,$1,; + # Log3($name, 1, "$name - commandArgs: $Presets"); + } else { + $Presets = FW_pH "cmd.$name=set $name $cmdPreset", $cmdPreset, 0, "", 1, 1; + } - foreach $fn (sort keys %{$data{webCmdFn}}) { - no strict "refs"; - $Patrols = &{$data{webCmdFn}{$fn}}($FW_wname,$name,"",$cmdPatrol,$valPatrols); - use strict "refs"; - last if(defined($Patrols)); - } - - - # Rahmenklasse - $ptz_ret .= "
"; - $ptz_ret .= ""; - $ptz_ret .= ""; - $ptz_ret .= '"; - $ptz_ret .= ""; - $ptz_ret .= "
'; - - # Dropdown Klasse - $ptz_ret .= ""; - $ptz_ret .= ""; - $ptz_ret .= ""; - $ptz_ret .= ""; - $ptz_ret .= "
Preset:
$Presets
"; - - $ptz_ret .= ""; - $ptz_ret .= ""; - $ptz_ret .= ""; - $ptz_ret .= ""; - $ptz_ret .= "
Patrol:
$Patrols
"; - - # Rahmenklasse end - $ptz_ret .= "
"; - $ptz_ret .= "
"; - - ##################### + foreach $fn (sort keys %{$data{webCmdFn}}) { + no strict "refs"; + $Patrols = &{$data{webCmdFn}{$fn}}($FW_wname,$name,"",$cmdPatrol,$valPatrols); + use strict "refs"; + last if(defined($Patrols)); + } + + # Rahmenklasse + $ptz_ret .= "
"; + $ptz_ret .= ""; + $ptz_ret .= ""; + $ptz_ret .= '"; + $ptz_ret .= ""; + $ptz_ret .= "
'; + + # Dropdown Klasse + $ptz_ret .= ""; + $ptz_ret .= ""; + $ptz_ret .= ""; + $ptz_ret .= ""; + $ptz_ret .= "
Preset:
$Presets
"; + + $ptz_ret .= ""; + $ptz_ret .= ""; + $ptz_ret .= ""; + $ptz_ret .= ""; + $ptz_ret .= "
Patrol:
$Patrols
"; + + # Rahmenklasse end + $ptz_ret .= "
"; + $ptz_ret .= "
"; + + ##################### + } if ($rowisset) { return $ptz_ret; @@ -7088,8 +7156,8 @@ return; # $fmt = Streaming Format # ###################################################################################### -sub SSCam_StreamDev($$$) { - my ($camname,$strmdev,$fmt) = @_; +sub SSCam_StreamDev($$$;$) { + my ($camname,$strmdev,$fmt,$ftui) = @_; my $hash = $defs{$camname}; my $wltype = $hash->{HELPER}{WLTYPE}; my $serveraddr = $hash->{SERVERADDR}; @@ -7106,47 +7174,77 @@ sub SSCam_StreamDev($$$) { my $camid = $hash->{CAMID}; my $sid = $hash->{HELPER}{SID}; my $proto = $hash->{PROTOCOL}; - my ($cause,$ret,$link,$audiolink,$devWlink,$wlhash,$alias,$wlalias); + $ftui = ($ftui && $ftui eq "ftui")?1:0; + my $hdrAlign = "center"; + my ($cause,$ret,$link,$audiolink,$devWlink,$wlhash,$wlalias); # Kontext des SSCamSTRM-Devices speichern für SSCam_refresh $hash->{HELPER}{STRMDEV} = $strmdev; # Name des aufrufenden SSCamSTRM-Devices $hash->{HELPER}{STRMROOM} = $FW_room?$FW_room:""; # Raum aus dem das SSCamSTRM-Device die Funktion aufrief $hash->{HELPER}{STRMDETAIL} = $FW_detail?$FW_detail:""; # Name des SSCamSTRM-Devices (wenn Detailansicht) my $streamHash = $defs{$strmdev}; # Hash des SSCamSTRM-Devices + my $uuid = $streamHash->{FUUID}; # eindeutige UUID des Streamingdevices delete $streamHash->{HELPER}{STREAM}; delete $streamHash->{HELPER}{STREAMACTIVE}; # Statusbit ob ein Stream aktiviert ist # Definition Tasten - my $imgblank = ""; # nicht sichtbare Leertaste - my $cmdstop = "cmd=set $camname stopView"; # Stream deaktivieren + my $imgblank = ""; # nicht sichtbare Leertaste + my $cmdstop = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname stopView STRM:$uuid')"; # Stream deaktivieren my $imgstop = ""; - my $cmdhlsreact = "cmd=set $camname hlsreactivate"; # HLS Stream reaktivieren + my $cmdhlsreact = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname hlsreactivate')"; # HLS Stream reaktivieren my $imghlsreact = ""; - my $cmdmjpegrun = "cmd=set $camname runView live_fw"; # MJPEG Stream aktivieren + my $cmdmjpegrun = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname runView live_fw STRM:$uuid')"; # MJPEG Stream aktivieren my $imgmjpegrun = ""; - my $cmdhlsrun = "cmd=set $camname runView live_fw_hls"; # HLS Stream aktivieren + my $cmdhlsrun = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname runView live_fw_hls STRM:$uuid')"; # HLS Stream aktivieren my $imghlsrun = ""; - my $cmdlrirun = "cmd=set $camname runView lastrec_fw"; # Last Record IFrame + my $cmdlrirun = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname runView lastrec_fw STRM:$uuid')"; # Last Record IFrame my $imglrirun = ""; - my $cmdlh264run = "cmd=set $camname runView lastrec_fw_MPEG4/H.264"; # Last Record H.264 + my $cmdlh264run = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname runView lastrec_fw_MPEG4/H.264 STRM:$uuid')"; # Last Record H.264 my $imglh264run = ""; - my $cmdlmjpegrun = "cmd=set $camname runView lastrec_fw_MJPEG"; # Last Record MJPEG + my $cmdlmjpegrun = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname runView lastrec_fw_MJPEG STRM:$uuid')"; # Last Record MJPEG my $imglmjpegrun = ""; - my $cmdlsnaprun = "cmd=set $camname runView lastsnap_fw STRM"; # Last SNAP + my $cmdlsnaprun = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname runView lastsnap_fw STRM:$uuid')"; # Last SNAP my $imglsnaprun = ""; - my $cmdrecendless = "cmd=set $camname on 0"; # Endlosaufnahme Start + my $cmdrecendless = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname on 0 STRM:$uuid')"; # Endlosaufnahme Start my $imgrecendless = ""; - my $cmdrecstop = "cmd=set $camname off"; # Aufnahme Stop + my $cmdrecstop = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname off STRM:$uuid')"; # Aufnahme Stop my $imgrecstop = ""; - my $cmddosnap = "cmd=set $camname snap 1 2 STRM"; # Snapshot auslösen mit Kennzeichnung "by STRM-Device" + my $cmddosnap = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname snap 1 2 STRM:$uuid')"; # Snapshot auslösen mit Kennzeichnung "by STRM-Device" my $imgdosnap = ""; - my $cmdrefresh = "cmd=set $camname refresh STRM"; # Refresh in SSCamSTRM-Devices + my $cmdrefresh = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $camname refresh STRM:$uuid')"; # Refresh in SSCamSTRM-Devices my $imgrefresh = ""; + # bei Aufruf durch FTUI Kommandosyntax anpassen + if ($ftui) { + $cmddosnap = "ftui.setFhemStatus('set $camname snap 1 2 STRM:$uuid')"; + $cmdstop = "ftui.setFhemStatus('set $camname stopView STRM:$uuid')"; + $cmdhlsreact = "ftui.setFhemStatus('set $camname hlsreactivate STRM:$uuid')"; + $cmdmjpegrun = "ftui.setFhemStatus('set $camname runView live_fw STRM:$uuid')"; + $cmdhlsrun = "ftui.setFhemStatus('set $camname runView live_fw_hls STRM:$uuid')"; + $cmdlrirun = "ftui.setFhemStatus('set $camname runView lastrec_fw STRM:$uuid')"; + $cmdlh264run = "ftui.setFhemStatus('set $camname runView lastrec_fw_MPEG4/H.264 STRM:$uuid')"; + $cmdlmjpegrun = "ftui.setFhemStatus('set $camname runView lastrec_fw_MJPEG STRM:$uuid')"; + $cmdlsnaprun = "ftui.setFhemStatus('set $camname runView lastsnap_fw STRM STRM:$uuid')"; + $cmdrecendless = "ftui.setFhemStatus('set $camname on 0 STRM:$uuid')"; + $cmdrecstop = "ftui.setFhemStatus('set $camname off STRM:$uuid')"; + $cmdrefresh = "ftui.setFhemStatus('set $camname refresh STRM:$uuid')"; + } + my $ha = AttrVal($camname, "htmlattr", 'width="500" height="325"'); # HTML Attribute der Cam - $ha = AttrVal($strmdev, "htmlattr", $ha); # htmlattr mit htmattr Streaming-Device übersteuern + $ha = AttrVal($strmdev, "htmlattr", $ha); # htmlattr mit htmlattr Streaming-Device übersteuern + if($ftui) { + $ha = AttrVal($strmdev, "htmlattrFTUI", $ha); # wenn aus FTUI aufgerufen divers setzen + } + my $pws = AttrVal($strmdev, "popupWindowSize", ""); # Größe eines Popups $pws =~ s/"//g if($pws); + + my $show = $defs{$streamHash->{PARENT}}->{HELPER}{ACTSTRM} if($streamHash->{MODEL} =~ /switched/); + $show = $show?"($show)":""; + + my $alias = AttrVal($strmdev, "alias", $strmdev); # Linktext als Aliasname oder Devicename setzen + my $dlink = "$alias"; + my $StmKey = ReadingsVal($camname,"StmKey",undef); # Javascript Bibliothek für Tooltips (http://www.walterzorn.de/tooltip/tooltip.htm#download) und Texte @@ -7182,21 +7280,26 @@ sub SSCam_StreamDev($$$) { } $ret = ""; - $ret .= ""; - $ret .= ''; + $ret .= ""; + $ret .= '
'; + if($ftui) { + $ret .= "$dlink $show
" if(!AttrVal($strmdev,"hideDisplayNameFTUI",0)); + } else { + $ret .= "$dlink $show
" if(!AttrVal($strmdev,"hideDisplayName",0)); + } $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 !":"Cam \"$cam\" is disabled"; - $cause = "Camera \"$cam\" is disabled" if(IsDisabled($camname)); - $ret .= ""; - $ret .= ''; - $ret .= ''; - $ret .= '

$cause

'; - $ret .= ''; + my $cam = AttrVal($camname, "alias", $camname); # Linktext als Aliasname oder Devicename setzen + $cause = !$StmKey?"Camera $cam has no Reading \"StmKey\" set !":"Cam \"$cam\" is disabled"; + $cause = "Camera \"$cam\" is disabled" if(IsDisabled($camname)); + $ret .= "
$cause

"; + $ret .= ''; + $ret .= ''; + $ret .= ''; + $ret .= ''; return $ret; } @@ -7212,22 +7315,26 @@ sub SSCam_StreamDev($$$) { if($apiaudiostmmaxver) { $audiolink = "$proto://$serveraddr:$serverport/webapi/$apiaudiostmpath?api=$apiaudiostm&version=$apiaudiostmmaxver&method=Stream&cameraId=$camid&_sid=$sid"; } - $ret .= "')\">
"; - $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + if(!$ftui) { + $ret .= "')\">
"; + } else { + $ret .= "
"; + } + $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist } if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; + $ret .= "$imgrecendless "; } else { # Aufnahmebutton Stop - $ret .= "$imgrecstop "; + $ret .= "$imgrecstop "; } - $ret .= "$imgdosnap "; + $ret .= "$imgdosnap "; $ret .= ""; if(AttrVal($camname,"ptzPanel_use",1)) { - my $ptz_ret = SSCam_ptzpanel($camname); + my $ptz_ret = SSCam_ptzpanel($camname,$strmdev,'',$ftui); if($ptz_ret) { $ret .= "$ptz_ret"; } @@ -7246,8 +7353,12 @@ sub SSCam_StreamDev($$$) { $link = $hash->{HELPER}{".LASTSNAP"}; my $gattr = (AttrVal($camname,"snapGallerySize","Icon") eq "Full")?$ha:""; if($link) { - $ret .= "')\">
"; - $ret .= "$imgdosnap "; + if(!$ftui) { + $ret .= "')\">
"; + } else { + $ret .= "
"; + } + $ret .= "$imgdosnap "; $ret .= ""; $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist @@ -7289,19 +7400,19 @@ sub SSCam_StreamDev($$$) { } $ret .= "
"; Log3($strmdev, 4, "$strmdev - generic Stream params:\n$htag"); - $ret .= "$imgrefresh "; + $ret .= "$imgrefresh "; $ret .= $imgblank; if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; + $ret .= "$imgrecendless "; } else { # Aufnahmebutton Stop - $ret .= "$imgrecstop "; + $ret .= "$imgrecstop "; } - $ret .= "$imgdosnap "; + $ret .= "$imgdosnap "; $ret .= ""; if(AttrVal($camname,"ptzPanel_use",1)) { - my $ptz_ret = SSCam_ptzpanel($camname); + my $ptz_ret = SSCam_ptzpanel($camname,$strmdev,'',$ftui); if($ptz_ret) { $ret .= "$ptz_ret"; } @@ -7335,19 +7446,19 @@ sub SSCam_StreamDev($$$) { $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern $streamHash->{HELPER}{STREAMACTIVE} = 1; # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgrefresh "; + $ret .= "$imgrefresh "; $ret .= $imgblank; if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; + $ret .= "$imgrecendless "; } else { # Aufnahmebutton Stop - $ret .= "$imgrecstop "; + $ret .= "$imgrecstop "; } - $ret .= "$imgdosnap "; + $ret .= "$imgdosnap "; $ret .= ""; if(AttrVal($camname,"ptzPanel_use",1)) { - my $ptz_ret = SSCam_ptzpanel($camname); + my $ptz_ret = SSCam_ptzpanel($camname,$strmdev,'',$ftui); if($ptz_ret) { $ret .= "$ptz_ret"; } @@ -7362,25 +7473,29 @@ sub SSCam_StreamDev($$$) { if(ReadingsVal($camname, "SVSversion", "8.2.3-5828") eq "8.2.3-5828" && ReadingsVal($camname, "CamVideoType", "") !~ /MJPEG/) { $ret .= "
Because SVS version 8.2.3-5828 is running you cannot see the MJPEG-Stream. Please upgrade to a higher SVS version !

"; } else { - $ret .= "')\">
" if($link); + if(!$ftui) { + $ret .= "')\">
" if($link); + } else { + $ret .= "
" if($link); + } $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist } - $ret .= "$imgstop "; + $ret .= "$imgstop "; $ret .= $imgblank; if($hash->{HELPER}{RUNVIEW} =~ /live_fw/) { if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; + $ret .= "$imgrecendless "; } else { # Aufnahmebutton Stop - $ret .= "$imgrecstop "; + $ret .= "$imgrecstop "; } - $ret .= "$imgdosnap "; + $ret .= "$imgdosnap "; } $ret .= ""; if(AttrVal($camname,"ptzPanel_use",1) && $hash->{HELPER}{RUNVIEW} =~ /live_fw/) { - my $ptz_ret = SSCam_ptzpanel($camname); + my $ptz_ret = SSCam_ptzpanel($camname,$strmdev,'',$ftui); if($ptz_ret) { $ret .= "$ptz_ret"; } @@ -7396,15 +7511,21 @@ sub SSCam_StreamDev($$$) { } } elsif ($wltype =~ /iframe/) { - $ret .= "
" if($link); + if(!$ftui) { + $ret .= "
" if($link); + } else { + $ret .= "
" if($link); + } $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgstop "; - $ret .= "$imgrefresh "; + $ret .= "$imgstop "; + $ret .= "$imgrefresh "; $ret .= ""; if($hash->{HELPER}{AUDIOLINK} && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/) { $ret .= ''; @@ -7430,7 +7551,7 @@ sub SSCam_StreamDev($$$) { "Your browser does not support the video tag". ""; # Stream für "set popupStream" speichern $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgstop "; + $ret .= "$imgstop "; $ret .= ""; if($hash->{HELPER}{AUDIOLINK} && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/) { $ret .= ''; @@ -7442,16 +7563,24 @@ sub SSCam_StreamDev($$$) { $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); } } elsif($wltype =~ /base64img/) { - $ret .= "')\">
" if($link); - $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgstop "; + if(!$ftui) { + $ret .= "')\">
" if($link); + } else { + $ret .= "
" if($link); + } + $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + $ret .= "$imgstop "; $ret .= $imgblank; - $ret .= "$imgdosnap "; + $ret .= "$imgdosnap "; $ret .= ""; } elsif($wltype =~ /embed/) { - $ret .= "')\">" if($link); + if(!$ftui) { + $ret .= "')\">" if($link); + } else { + $ret .= "" if($link); + } $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist @@ -7467,21 +7596,21 @@ sub SSCam_StreamDev($$$) { "Your browser does not support the video tag". ""; # Stream für "set popupStream" speichern $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgstop "; - $ret .= "$imgrefresh "; - $ret .= "$imghlsreact "; + $ret .= "$imgstop "; + $ret .= "$imgrefresh "; + $ret .= "$imghlsreact "; $ret .= $imgblank; if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; + $ret .= "$imgrecendless "; } else { # Aufnahmebutton Stop - $ret .= "$imgrecstop "; + $ret .= "$imgrecstop "; } - $ret .= "$imgdosnap "; + $ret .= "$imgdosnap "; $ret .= ""; if(AttrVal($camname,"ptzPanel_use",1)) { - my $ptz_ret = SSCam_ptzpanel($camname); + my $ptz_ret = SSCam_ptzpanel($camname,$strmdev,'',$ftui); if($ptz_ret) { $ret .= "$ptz_ret"; } @@ -7493,12 +7622,12 @@ sub SSCam_StreamDev($$$) { my $cam = AttrVal($camname, "alias", $camname); $cause = "Playback cam \"$cam\" switched off"; $ret .= "
$cause

"; - $ret .= "$imgmjpegrun "; - $ret .= "$imghlsrun " if(SSCam_IsHLSCap($hash)); - $ret .= "$imglrirun "; - $ret .= "$imglh264run "; - $ret .= "$imglmjpegrun "; - $ret .= "$imglsnaprun "; + $ret .= "$imgmjpegrun "; + $ret .= "$imghlsrun " if(SSCam_IsHLSCap($hash)); + $ret .= "$imglrirun "; + $ret .= "$imglh264run "; + $ret .= "$imglmjpegrun "; + $ret .= "$imglsnaprun "; $ret .= ""; } } else { @@ -7564,42 +7693,58 @@ return $ret; # Schnappschußgalerie zusammenstellen # Verwendung durch SSCamSTRM-Devices ############################################################################### -sub SSCam_composegallery ($;$$) { - my ($name,$strmdev,$model) = @_; +sub SSCam_composegallery ($;$$$) { + my ($name,$strmdev,$model,$ftui) = @_; 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 $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 + $ftui = ($ftui && $ftui eq "ftui")?1:0; + my $uuid = ""; + my $hdrAlign = "center"; my $lupt = ((ReadingsTimestamp($name,"LastSnapTime"," ") gt ReadingsTimestamp($name,"LastUpdateTime"," ")) ? ReadingsTimestamp($name,"LastSnapTime"," ") : ReadingsTimestamp($name,"LastUpdateTime"," ")); # letzte Aktualisierung $lupt =~ s/ / \/ /; # Kontext des SSCamSTRM-Devices speichern für SSCam_refresh - $hash->{HELPER}{STRMDEV} = $strmdev; # Name des aufrufenden SSCamSTRM-Devices - $hash->{HELPER}{STRMROOM} = $FW_room?$FW_room:""; # Raum aus dem das SSCamSTRM-Device die Funktion aufrief - $hash->{HELPER}{STRMDETAIL} = $FW_detail?$FW_detail:""; # Name des SSCamSTRM-Devices (wenn Detailansicht) - my $streamHash = $defs{$strmdev} if($strmdev); # Hash des SSCamSTRM-Devices - delete $streamHash->{HELPER}{STREAM}; + $hash->{HELPER}{STRMDEV} = $strmdev; # Name des aufrufenden SSCamSTRM-Devices + $hash->{HELPER}{STRMROOM} = $FW_room?$FW_room:""; # Raum aus dem das SSCamSTRM-Device die Funktion aufrief + $hash->{HELPER}{STRMDETAIL} = $FW_detail?$FW_detail:""; # Name des SSCamSTRM-Devices (wenn Detailansicht) - my $cmddosnap = "cmd=set $name snap 1 2 STRM"; # Snapshot auslösen mit Kennzeichnung "by STRM-Device" + if($strmdev) { + my $streamHash = $defs{$strmdev}; # Hash des SSCamSTRM-Devices + $uuid = $streamHash->{FUUID}; # eindeutige UUID des Streamingdevices + delete $streamHash->{HELPER}{STREAM}; + } + + my $cmddosnap = "FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name snap 1 2 STRM:$uuid')"; # Snapshot auslösen mit Kennzeichnung "by STRM-Device" my $imgdosnap = ""; + + # bei Aufruf durch FTUI Kommandosyntax anpassen + if($ftui) { + $cmddosnap = "ftui.setFhemStatus('set $name snap 1 2 STRM:$uuid')"; + } - my $ha = AttrVal($name, "snapGalleryHtmlAttr", AttrVal($name, "htmlattr", 'width="500" height="325"')); + my $ha = AttrVal($name, "snapGalleryHtmlAttr", AttrVal($name, "htmlattr", 'width="500" height="325"')); + + my $alias = AttrVal($strmdev, "alias", $strmdev); # Linktext als Aliasname oder Devicename setzen + my $dlink = "$alias"; # falls "SSCam_composegallery" durch ein SSCamSTRM-Device aufgerufen wird - my $devWlink = ""; my $pws = ""; if ($strmdev) { - $pws = AttrVal($strmdev, "popupWindowSize", ""); # Größe eines Popups (umgelegt: Forum:https://forum.fhem.de/index.php/topic,45671.msg927912.html#msg927912) - $pws =~ s/"//g if($pws); - my $wlha = AttrVal($strmdev, "htmlattr", undef); - $ha = (defined($wlha))?$wlha:$ha; # htmlattr vom SSCamSTRM-Device übernehmen falls von SSCamSTRM-Device aufgerufen und gesetzt + $pws = AttrVal($strmdev, "popupWindowSize", ""); # Größe eines Popups (umgelegt: Forum:https://forum.fhem.de/index.php/topic,45671.msg927912.html#msg927912) + $pws =~ s/"//g if($pws); + $ha = AttrVal($strmdev, "htmlattr", $ha); # htmlattr vom SSCamSTRM-Device übernehmen falls von SSCamSTRM-Device aufgerufen und gesetzt + if($ftui) { + $ha = AttrVal($strmdev, "htmlattrFTUI", $ha); # wenn aus FTUI aufgerufen divers setzen + } } # wenn SSCamSTRM-device genutzt wird und attr "snapGalleryBoost" nicht gesetzt ist -> Warnung in Gallerie ausgeben @@ -7611,19 +7756,26 @@ sub SSCam_composegallery ($;$$) { # Javascript Bibliothek für Tooltips (http://www.walterzorn.de/tooltip/tooltip.htm#download) und Texte my $ttjs = "/fhem/pgm2/sscam_tooltip.js"; - my ($ttsnap); - if(AttrVal("global","language","EN") =~ /EN/) { - $ttsnap = $SSCam_ttips_en{"ttsnap"}; $ttsnap =~ s/§NAME§/$camname/g; - } else { - $ttsnap = $SSCam_ttips_de{"ttsnap"}; $ttsnap =~ s/§NAME§/$camname/g; + + my $ttsnap = $SSCam_ttips_en{"ttsnap"}; $ttsnap =~ s/§NAME§/$camname/g; + if(AttrVal("global","language","EN") =~ /DE/) { + $ttsnap = $SSCam_ttips_de{"ttsnap"}; $ttsnap =~ s/§NAME§/$camname/g; } - my $header; + # Header Generierung + my $header; + if($ftui) { + $header .= "$dlink
" if(!AttrVal($strmdev,"hideDisplayNameFTUI",0)); + } else { + $header .= "$dlink
" if(!AttrVal($strmdev,"hideDisplayName",0)); + } if ($lang eq "EN") { - $header = "Snapshots ($limit/$totalcnt) of camera $camname - newest Snapshot: $lss
"; + $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 .= "Schnappschüsse ($limit/$totalcnt) von Kamera $camname - neueste Aufnahme: $lss
"; + $lupt =~ /(\d+)-(\d\d)-(\d\d)\s+(.*)/; + $lupt = "$3.$2.$1 $4"; $header .= " (Eventuell sind neuere Aufnahmen verfügbar. Letzter Abruf: $lupt)
" if(AttrVal($name,"snapGalleryBoost",0)); } $header .= $sgbnote; @@ -7635,8 +7787,8 @@ sub SSCam_composegallery ($;$$) { my ($htmlCode,$ct); $htmlCode = ""; $htmlCode .= ""; - $htmlCode .= sprintf("$devWlink
$header
"); - $htmlCode .= ""; + $htmlCode .= "
$header
"; + $htmlCode .= '
'; $htmlCode .= ""; $htmlCode .= ""; my $cell = 1; @@ -7644,8 +7796,10 @@ sub SSCam_composegallery ($;$$) { foreach my $key (@as) { $ct = $allsnaps->{$key}{createdTm}; my $idata = ""; - $idata = "onClick=\"FW_okDialog('{$key}{imageData} $pws>')\"" if(AttrVal($name,"snapGalleryBoost",0)); - my $html = sprintf("" ); + if(!$ftui) { + $idata = "onClick=\"FW_okDialog('{$key}{imageData} $pws>')\"" if(AttrVal($name,"snapGalleryBoost",0)); + } + my $html = sprintf("" ); $cell++; if ( $cell == $sgc+1 ) { @@ -7666,7 +7820,7 @@ sub SSCam_composegallery ($;$$) { $htmlCode .= ""; $htmlCode .= "
$ct
{$key}{imageData}\" $gattr $idata>
$ct
{$key}{imageData}\" $gattr $idata>
"; $htmlCode .= "
"; - $htmlCode .= "$imgdosnap " if($strmdev); + $htmlCode .= "$imgdosnap " if($strmdev); $htmlCode .= ""; return $htmlCode; @@ -9155,9 +9309,16 @@ return; For example the recordings are stored for a defined time in Surveillance Station and will be deleted after that period.

If you like to discuss or help to improve this module please use FHEM-Forum with link:
- 49_SSCam: Fragen, Hinweise, Neuigkeiten und mehr rund um dieses Modul.

+ 49_SSCam: Fragen, Hinweise, Neuigkeiten und mehr rund um dieses Modul. +

+ + Integration into FHEM TabletUI:

+ There is a widget provided for integration of SSCam-Streaming devices (Type SSCamSTRM) into FTUI. For further information please be informed by the + (german) FHEM Wiki article:
+ FTUI Widget für SSCam Streaming Devices (SSCamSTRM). +


- Prerequisites

+ Prerequisites

    This module uses the Perl-modules JSON and MIME::Lite which are usually have to be installed in addition.
    On Debian-Linux based systems these modules can be installed by:

    @@ -9202,7 +9363,7 @@ return; command in a previously defined SVS device.

    - A camera is defined by:

    + A camera device is defined by:

      define <Name> SSCAM <camera name in SVS> <ServerAddr> [Port] [Protocol]

    @@ -9266,7 +9427,8 @@ return; panel can be affected by attributes "ptzPanel_.*".
    Please see also command "set <name> createPTZcontrol" in this context.


    -
+ + Credentials

@@ -10910,7 +11072,14 @@ attr <name> genericStrmHtmlTag <img $HTMLATTR 49_SSCam: Fragen, Hinweise, Neuigkeiten und mehr rund um dieses Modul.

Weitere Infomationen zum Modul sind im FHEM-Wiki zu finden:
- SSCAM - Steuerung von Kameras in Synology Surveillance Station.

+ SSCAM - Steuerung von Kameras in Synology Surveillance Station. +

+ + Integration in FHEM TabletUI:

+ Zur Integration von SSCam Streaming Devices (Typ SSCamSTRM) wird ein Widget bereitgestellt. + Für weitere Information dazu bitte den Artikel im Wiki durchlesen:
+ FTUI Widget für SSCam Streaming Devices (SSCamSTRM). +


Vorbereitung

diff --git a/fhem/FHEM/49_SSCamSTRM.pm b/fhem/FHEM/49_SSCamSTRM.pm index 6eedb2c37..333d92d55 100644 --- a/fhem/FHEM/49_SSCamSTRM.pm +++ b/fhem/FHEM/49_SSCamSTRM.pm @@ -35,6 +35,8 @@ eval "use FHEM::Meta;1" or my $modMetaAbsent = 1; # Versions History intern our %SSCamSTRM_vNotesIntern = ( + "2.7.0" => "15.07.2019 FTUI support, new attributes htmlattrFTUI, hideDisplayNameFTUI, ptzButtonSize, ptzButtonSizeFTUI ", + "2.6.0" => "21.06.2019 GetFn -> get html ", "2.5.0" => "27.03.2019 add Meta.pm support ", "2.4.0" => "24.02.2019 support for \"genericStrmHtmlTag\" in streaming device MODEL generic ", "2.3.0" => "04.02.2019 SSCamSTRM_Rename / SSCamSTRM_Copy added, Streaming device can now be renamed or copied ", @@ -61,12 +63,10 @@ our %SSCamSTRM_vNotesIntern = ( ); # Standardvariablen und Forward-Declaration -sub SSCam_ptzpanel($;$$); -sub SSCam_StreamDev($$$); +sub SSCam_ptzpanel(@); +sub SSCam_StreamDev($$$;$); sub SSCam_getclhash($;$$); -# my $hlsjs = "hls.js"; # hls.js Release von Seite https://github.com/video-dev/hls.js/releases - ################################################################ sub SSCamSTRM_Initialize($) { my ($hash) = @_; @@ -75,16 +75,21 @@ sub SSCamSTRM_Initialize($) { $hash->{DefFn} = "SSCamSTRM_Define"; $hash->{SetFn} = "SSCamSTRM_Set"; + $hash->{GetFn} = "SSCamSTRM_Get"; $hash->{AttrList} = "autoRefresh:selectnumbers,120,0.2,1800,0,log10 ". "autoRefreshFW:$fwd ". "disable:1,0 ". "forcePageRefresh:1,0 ". "genericStrmHtmlTag ". "htmlattr ". + "htmlattrFTUI ". "hideDisplayName:1,0 ". + "hideDisplayNameFTUI:1,0 ". "popupWindowSize ". "popupStreamFW:$fwd ". "popupStreamTo:OK,1,2,3,4,5,6,7,8,9,10,15,20,25,30,40,50,60 ". + "ptzButtonSize:selectnumbers,50,5,100,0,lin ". + "ptzButtonSizeFTUI:selectnumbers,50,5,100,0,lin ". $readingFnAttributes; $hash->{RenameFn} = "SSCamSTRM_Rename"; $hash->{CopyFn} = "SSCamSTRM_Copy"; @@ -134,7 +139,10 @@ sub SSCamSTRM_Rename($$) { return; } -################################################################ +############################################################### +# SSCamSTRM Copy +# passt die Deviceparameter bei kopierten Device an +############################################################### sub SSCamSTRM_Copy($$) { my ($old_name,$new_name) = @_; my $hash = $defs{$new_name}; @@ -145,6 +153,27 @@ sub SSCamSTRM_Copy($$) { return; } +############################################################### +# SSCamSTRM Get +############################################################### +sub SSCamSTRM_Get($@) { + my ($hash, @a) = @_; + return "\"get X\" needs at least an argument" if ( @a < 2 ); + my $name = shift @a; + my $cmd = shift @a; + + if ($cmd eq "html") { + return SSCamSTRM_AsHtml($hash); + } + + if ($cmd eq "ftui") { + return SSCamSTRM_AsHtml($hash,"ftui"); + } + +return undef; +return "Unknown argument $cmd, choose one of html:noArg"; +} + ################################################################ sub SSCamSTRM_Set($@) { my ($hash, @a) = @_; @@ -243,15 +272,9 @@ sub SSCamSTRM_FwFn($;$$$) { RemoveInternalTimer($hash); $hash->{HELPER}{FW} = $FW_wname; - $link = AnalyzePerlCommand(undef, $link) if($link =~ m/^{(.*)}$/s); - my $show = $defs{$hash->{PARENT}}->{HELPER}{ACTSTRM} if($hash->{MODEL} =~ /switched/); - $show = $show?"($show)":""; - - my $alias = AttrVal($d, "alias", $d); # Linktext als Aliasname oder Devicename setzen - my $dlink = "$alias"; + $link = AnalyzePerlCommand(undef, $link) if($link =~ m/^{(.*)}$/s); my $ret = ""; - $ret .= "$dlink $show
" if(!AttrVal($d,"hideDisplayName",0)); if(IsDisabled($d)) { if(AttrVal($d,"hideDisplayName",0)) { $ret .= "Stream-device $d is disabled"; @@ -327,6 +350,39 @@ sub SSCamSTRM_setVersionInfo($) { return; } +################################################################ +# Grafik als HTML zurück liefern (z.B. für Widget) +################################################################ +sub SSCamSTRM_AsHtml($;$) { + my ($hash,$ftui) = @_; + my $name = $hash->{NAME}; + my $link = $hash->{LINK}; + + if ($ftui && $ftui eq "ftui") { + # Aufruf aus TabletUI -> FW_cmd ersetzen gemäß FTUI Syntax + my $s = substr($link,0,length($link)-2); + $link = $s.",'$ftui')}"; + } + + $link = AnalyzePerlCommand(undef, $link) if($link =~ m/^{(.*)}$/s); + + my $ret = ""; + if(IsDisabled($name)) { + if(AttrVal($name,"hideDisplayName",0)) { + $ret .= "Stream-device $name is disabled"; + } else { + $ret .= "Stream-device is disabled"; + } + + } else { + $ret .= $link; + } + + $ret .= ""; + +return $ret; +} + 1; =pod @@ -337,27 +393,35 @@ return;

SSCamSTRM


-The module SSCamSTRM is a special device module synchronized to the SSCam module. It is used for definition of -Streaming-Devices.
-Dependend of the Streaming-Device state, different buttons are provided to start actions: -
    - - - - - - - - - - - - - - -
    Switch off - stops a running playback
    Refresh - refresh a view (no page reload)
    Restart - restart a running content (e.g. a HLS-Stream)
    MJPEG - starts a MJPEG Livestream
    HLS - starts HLS (HTTP Live Stream)
    Last Record - playback the last recording as iFrame
    Last Rec H.264 - playback the last recording if available as H.264
    Last Rec MJPEG - playback the last recording if available as MJPEG
    Last SNAP - show the last snapshot
    Start Recording - starts an endless recording
    Stop Recording - stopps the recording
    Take Snapshot - take a snapshot
    -
-
+
    + The module SSCamSTRM is a special device module synchronized to the SSCam module. It is used for definition of + Streaming-Devices.
    + Dependend of the Streaming-Device state, different buttons are provided to start actions: +
      + + + + + + + + + + + + + + +
      Switch off - stops a running playback
      Refresh - refresh a view (no page reload)
      Restart - restart a running content (e.g. a HLS-Stream)
      MJPEG - starts a MJPEG Livestream
      HLS - starts HLS (HTTP Live Stream)
      Last Record - playback the last recording as iFrame
      Last Rec H.264 - playback the last recording if available as H.264
      Last Rec MJPEG - playback the last recording if available as MJPEG
      Last SNAP - show the last snapshot
      Start Recording - starts an endless recording
      Stop Recording - stopps the recording
      Take Snapshot - take a snapshot
      +
    +
    + + Integration into FHEM TabletUI:

    + There is a widget provided for integration of SSCam-Streaming devices into FTUI. For further information please be informed by the + (german) FHEM Wiki article:
    + FTUI Widget für SSCam Streaming Devices (SSCamSTRM). +

    +
    @@ -390,7 +454,17 @@ Dependend of the Streaming-Device state, different buttons are provided to start
    - Get
      N/A

    + Get +
      +
      +
        +
      • get <name> html
      • + The stream object (camera live view, snapshots or replay) is fetched as HTML-code and depicted. +
      +
      + +
      +
    Attributes @@ -459,13 +533,30 @@ attr <name> genericStrmHtmlTag <img $HTMLATTR
    + +
  • hideDisplayNameFTUI
    + Hide the device/alias name (link to detail view) in FHEM TabletUI. +
  • +
    +
  • htmlattr
    Additional HTML tags to manipulate the streaming device.

      Example:
      - attr <name> htmlattr width="480" height="560"
      + attr <name> htmlattr width="580" height="460"
      +
    +
  • +
    + + +
  • htmlattrFTUI
    + Additional HTML tags to manipulate the streaming device in TabletUI. +

    +
      + Example:
      + attr <name> htmlattr width="580" height="460"

  • @@ -502,6 +593,18 @@ attr <name> genericStrmHtmlTag <img $HTMLATTR attr <name> popupWindowSize width="600" height="425"
+
+ + +
  • ptzButtonSize
    + Specifies the PTZ-panel button size (in %). +
  • +
    + + +
  • ptzButtonSizeFTUI
    + Specifies the PTZ-panel button size used in a Tablet UI (in %). +
  • @@ -513,28 +616,35 @@ attr <name> genericStrmHtmlTag <img $HTMLATTR

    SSCamSTRM

    - -
    -Das Modul SSCamSTRM ist ein mit SSCam abgestimmtes Gerätemodul zur Definition von Streaming-Devices.
    -Abhängig vom Zustand des Streaming-Devices werden zum Start von Aktionen unterschiedliche Drucktasten angeboten: -
      - - - - - - - - - - - - - - -
      Switch off - stoppt eine laufende Wiedergabe
      Refresh - auffrischen einer Ansicht (kein Browser Seiten-Reload)
      Restart - neu starten eines laufenden Contents (z.B. eines HLS-Streams)
      MJPEG - Startet MJPEG Livestream
      HLS - Startet HLS (HTTP Live Stream)
      Last Record - spielt die letzte Aufnahme als iFrame
      Last Rec H.264 - spielt die letzte Aufnahme wenn als H.264 vorliegend
      Last Rec MJPEG - spielt die letzte Aufnahme wenn als MJPEG vorliegend
      Last SNAP - zeigt den letzten Snapshot
      Start Recording - startet eine Endlosaufnahme
      Stop Recording - stoppt eine Aufnahme
      Take Snapshot - löst einen Schnappschuß aus
      -
    -
    +
      +
      + Das Modul SSCamSTRM ist ein mit SSCam abgestimmtes Gerätemodul zur Definition von Streaming-Devices.
      + Abhängig vom Zustand des Streaming-Devices werden zum Start von Aktionen unterschiedliche Drucktasten angeboten: +
        + + + + + + + + + + + + + + +
        Switch off - stoppt eine laufende Wiedergabe
        Refresh - auffrischen einer Ansicht (kein Browser Seiten-Reload)
        Restart - neu starten eines laufenden Contents (z.B. eines HLS-Streams)
        MJPEG - Startet MJPEG Livestream
        HLS - Startet HLS (HTTP Live Stream)
        Last Record - spielt die letzte Aufnahme als iFrame
        Last Rec H.264 - spielt die letzte Aufnahme wenn als H.264 vorliegend
        Last Rec MJPEG - spielt die letzte Aufnahme wenn als MJPEG vorliegend
        Last SNAP - zeigt den letzten Snapshot
        Start Recording - startet eine Endlosaufnahme
        Stop Recording - stoppt eine Aufnahme
        Take Snapshot - löst einen Schnappschuß aus
        +
      +
      + + Integration in FHEM TabletUI:

      + Zur Integration von SSCam Streaming Devices (Typ SSCamSTRM) wird ein Widget bereitgestellt. + Für weitere Information dazu bitte den Artikel im Wiki durchlesen:
      + FTUI Widget für SSCam Streaming Devices (SSCamSTRM). +


      +
      @@ -568,7 +678,18 @@ Abhängig vom Zustand des Streaming-Devices werden zum Start von Aktionen unters
      - Get
        N/A

      + Get +
        +
        +
          +
        • get <name> html
        • + Das eingebundene Streamobjekt (Kamera Live View, Schnappschüsse oder Wiedergabe einer Aufnahme) wird als HTML-code + abgerufen und dargestellt. +
        +
        + +
        +
      Attribute @@ -637,13 +758,30 @@ attr <name> genericStrmHtmlTag <img $HTMLATTR
      + +
    • hideDisplayNameFTUI
      + Verbirgt den Device/Alias-Namen (Link zur Detailansicht) im TabletUI. +
    • +
      +
    • htmlattr
      - Zusätzliche HTML Tags zur Darstellungsänderung im Streaming Device. + Zusätzliche HTML Tags zur Darstellung im Streaming Device.

        Beispiel:
        - attr <name> htmlattr width="480" height="560"
        + attr <name> htmlattr width="580" height="460"
        +
      +
    • +
      + + +
    • htmlattrFTUI
      + Zusätzliche HTML Tags zur Darstellung des Streaming Device im TabletUI. +

      +
        + Beispiel:
        + attr <name> htmlattr width="580" height="460"

    • @@ -679,6 +817,18 @@ attr <name> genericStrmHtmlTag <img $HTMLATTR attr <name> popupWindowSize width="600" height="425"
    +
    + + +
  • ptzButtonSize
    + Legt die Größe der Drucktasten des PTZ Paneels fest (in %). +
  • +
    + + +
  • ptzButtonSizeFTUI
    + Legt die Größe der Drucktasten des PTZ Paneels in einem Tablet UI fest (in %). +