diff --git a/fhem/CHANGED b/fhem/CHANGED
index 59824f85e..ebda548b1 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,6 @@
# 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: functions for cam-livestream added
- bugfix: 73_km200.pm: Bugfix InternalTimer; Improvement Log Level
- bugfix: pre-coomit-hook test
- bugfix: 98_weekprofile: detect channel of HM-CC-TC as correct thermostat
diff --git a/fhem/FHEM/49_SSCam.pm b/fhem/FHEM/49_SSCam.pm
index a42777379..e6a12f68e 100644
--- a/fhem/FHEM/49_SSCam.pm
+++ b/fhem/FHEM/49_SSCam.pm
@@ -27,6 +27,7 @@
##########################################################################################################
# Versions History:
#
+# 1.19 25.02.2016 functions for cam-livestream added
# 1.18.1 21.02.2016 fixed a problem that the state is "disable" instead of
# "disabled" if a camera is disabled and FHEM will be restarted
# 1.18 20.02.2016 function "get ... eventlist" added,
@@ -110,16 +111,20 @@ use HttpUtils;
sub SSCam_Initialize($) {
# die Namen der Funktionen, die das Modul implementiert und die fhem.pl aufrufen soll
my ($hash) = @_;
- $hash->{DefFn} = "SSCam_Define";
- $hash->{UndefFn} = "SSCam_Undef";
- $hash->{DeleteFn} = "SSCam_Delete";
- $hash->{SetFn} = "SSCam_Set";
- $hash->{GetFn} = "SSCam_Get";
- $hash->{AttrFn} = "SSCam_Attr";
-
+ $hash->{DefFn} = "SSCam_Define";
+ $hash->{UndefFn} = "SSCam_Undef";
+ $hash->{DeleteFn} = "SSCam_Delete";
+ $hash->{SetFn} = "SSCam_Set";
+ $hash->{GetFn} = "SSCam_Get";
+ $hash->{AttrFn} = "SSCam_Attr";
+ # Aufrufe aus FHEMWEB
+ $hash->{FW_summaryFn} = "SSCam_liveview";
+ $hash->{FW_detailFn} = "SSCam_liveview";
$hash->{AttrList} =
"httptimeout ".
+ "htmlattr ".
+ "livestreamprefix ".
"pollcaminfoall ".
"pollnologging:1,0 ".
"debugactivetoken:1 ".
@@ -171,8 +176,13 @@ sub SSCam_Define {
$hash->{HELPER}{ACTIVE} = "off"; # Funktionstoken "off", Funktionen können sofort starten
$hash->{HELPER}{OLDVALPOLLNOLOGGING} = "0"; # Loggingfunktion für Polling ist an
$hash->{HELPER}{RECTIME_DEF} = "15"; # Standard für rectime setzen, überschreibbar durch Attribut "rectime" bzw. beim "set .. on-for-time"
- readingsSingleUpdate($hash,"Availability", "", 0); # Verfügbarkeit ist unbekannt
- readingsSingleUpdate($hash,"PollState","Inactive",0); # es ist keine Gerätepolling aktiv
+
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"Availability", ""); # Verfügbarkeit ist unbekannt
+ readingsBulkUpdate($hash,"PollState","Inactive"); # es ist keine Gerätepolling aktiv
+ readingsBulkUpdate($hash,"LiveStreamUrl", ""); # LiveStream URL zurücksetzen
+ readingsEndUpdate($hash,1);
+
getcredentials($hash,1); # Credentials lesen und in RAM laden ($boot=1)
RemoveInternalTimer($hash); # alle Timer löschen
@@ -252,7 +262,8 @@ sub SSCam_Set {
"snap ".
"enable ".
"disable ".
- # "runLiveview ".
+ "runView:image,link ".
+ "stopView:noArg ".
((ReadingsVal("$name", "DeviceType", "Camera") eq "PTZ") ? "runPatrol:".ReadingsVal("$name", "Patrols", "")." " : "").
((ReadingsVal("$name", "DeviceType", "Camera") eq "PTZ") ? "goPreset:".ReadingsVal("$name", "Presets", "")." " : "").
((ReadingsVal("$name", "CapPTZAbs", "false")) ? "goAbsPTZ"." " : "").
@@ -382,11 +393,16 @@ sub SSCam_Set {
$hash->{HELPER}{PTZACTION} = "movestart";
doptzaction($hash);
}
- elsif ($opt eq "runLiveview")
+ elsif ($opt eq "runView")
{
if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
+ $hash->{HELPER}{WLTYPE} = $prop;
runliveview($hash);
}
+ elsif ($opt eq "stopView")
+ {
+ stopliveview($hash);
+ }
else
{
return $setlist;
@@ -419,7 +435,6 @@ sub SSCam_Get {
# sind die Credentials gesetzt ?
if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
- # hier die Verarbeitung starten
if ($opt eq "caminfoall")
{
# "1" ist Statusbit für manuelle Abfrage, kein Einstieg in Pollingroutine
@@ -443,6 +458,37 @@ sub SSCam_Get {
return undef;
}
+######################################################################################
+### Kamera Liveview Anzeige in FHEMWEB
+
+sub SSCam_liveview ($$$$) {
+
+ my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash für summaryFn in FHEMWEB
+ 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.*/);
+
+ my $attr = AttrVal($d, "htmlattr", "");
+
+ if($wltype eq "image") {
+ $ret = "
";
+
+ } elsif($wltype eq "iframe") {
+ $ret = "";
+
+ } elsif($wltype eq "link") {
+ # $alias = AttrVal($d, "alias", $d)."_liveview";
+ $alias = "LiveCam";
+ $ret = "$alias
"; # wenn attr target=_blank neuer Browsertab
+ }
+
+return $ret;
+}
######################################################################################
### initiale Startroutinen nach Restart FHEM
@@ -486,6 +532,8 @@ sub initonboot ($) {
return undef;
}
+
+
######################################################################################
### Username / Paßwort speichern
@@ -984,6 +1032,8 @@ sub runliveview ($) {
&printlog($hash,$logstr,"3");
}
+ readingsSingleUpdate($hash,"state","startview",1);
+
&getapisites_nonbl($hash);
}
else
@@ -992,6 +1042,60 @@ sub runliveview ($) {
}
}
+###############################################################################
+### Kamera Liveview stoppen
+
+sub stopliveview ($) {
+ my ($hash) = @_;
+ my $camname = $hash->{CAMNAME};
+ my $name = $hash->{NAME};
+ my $logstr;
+ my $errorcode;
+ my $error;
+
+ if ($hash->{HELPER}{ACTIVE} eq "off") {
+
+ return if (!$hash->{HELPER}{SID_STRM}); # runView ist nicht ausgeführt
+
+ # kurzer state-switch -> Browser aktualisieren
+ readingsSingleUpdate($hash,"state","stopview",1);
+
+ # Liveview stoppen
+ $logstr = "Stop Liveview of Camera $camname now";
+ &printlog($hash,$logstr,"4");
+
+ $hash->{OPMODE} = "stopliveview";
+ $hash->{HELPER}{ACTIVE} = "on";
+
+ if ($attr{$name}{debugactivetoken}) {
+ $logstr = "Active-Token was set by OPMODE: $hash->{OPMODE}" ;
+ &printlog($hash,$logstr,"3");
+ }
+
+ $hash->{HELPER}{SID} = $hash->{HELPER}{SID_STRM};
+
+ # Liveview-SID und Link aus Helper-hash löschen
+ delete $hash->{HELPER}{SID_STRM};
+ delete $hash->{HELPER}{LINK};
+
+ readingsSingleUpdate($hash,"LiveStreamUrl", "", 1);
+
+ if (ReadingsVal("$name", "Record", "") eq "Start") {
+ readingsSingleUpdate( $hash,"state", "on", 1);
+ }
+ else
+ {
+ readingsSingleUpdate($hash,"state", "off", 1);
+ }
+
+ logout_nonbl($hash);
+ }
+ else
+ {
+ InternalTimer(gettimeofday()+0.23, "stopliveview", $hash, 0);
+ }
+}
+
###############################################################################
### Filename zu Schappschuß ermitteln
@@ -2316,7 +2420,34 @@ sub camop_nonbl ($) {
}
elsif ($OpMode eq "runliveview")
{
- $url = "http://$serveraddr:$serverport/webapi/$apivideostmpath?api=\"$apivideostm\"&version=\"$apivideostmmaxver\"&method=\"Stream\"&cameraId=\"$camid\"&format=\"mjpeg\"&_sid=\"$sid\"";
+ # SID nach SID_STRM sichern und nutzen (für stopLiveview-Routine)
+ $hash->{HELPER}{SID_STRM} = $sid;
+ # externe URL
+ my $livestream = !AttrVal($name, "livestreamprefix", undef) ? "http://$serveraddr:$serverport" : AttrVal($name, "livestreamprefix", undef);
+ $livestream .= "/webapi/$apivideostmpath?api=$apivideostm&version=$apivideostmmaxver&method=Stream&cameraId=$camid&format=mjpeg&_sid=\"$sid\"";
+ # interne URL
+ $url = "http://$serveraddr:$serverport/webapi/$apivideostmpath?api=$apivideostm&version=$apivideostmmaxver&method=Stream&cameraId=$camid&format=mjpeg&_sid=\"$sid\"";
+
+ # Liveview-Link in Hash speichern -> Anzeige über SSCam_liveview, in Reading setzen für Linkversand
+ $hash->{HELPER}{LINK} = $url;
+ readingsSingleUpdate($hash,"LiveStreamUrl", $livestream, 1);
+
+ $logstr = "Set Livestream-URL: $url";
+ &printlog($hash,$logstr,"4");
+
+ $logstr = "--- End Function cam: $OpMode nonblocking ---";
+ &printlog($hash,$logstr,"4");
+
+ if (ReadingsVal("$name", "Record", "") eq "Start") {
+ readingsSingleUpdate( $hash,"state", "on", 1);
+ }
+ else
+ {
+ readingsSingleUpdate($hash,"state", "off", 1);
+ }
+
+ $hash->{HELPER}{ACTIVE} = "off";
+ return;
}
$logstr = "Call-Out now: $url";
@@ -2474,20 +2605,6 @@ sub camret_nonbl ($) {
$logstr = "--- End Function cam: $OpMode nonblocking ---";
&printlog($hash,$logstr,"4");
}
- elsif ($OpMode eq "runliveview")
- {
- # Setreading
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash,"Errorcode","none");
- readingsBulkUpdate($hash,"Error","none");
- readingsEndUpdate($hash, 1);
-
- # Logausgabe
- $logstr = "Camera $camname liveview was started successfully";
- &printlog($hash,$logstr,"3");
- $logstr = "--- End Function cam: $OpMode nonblocking ---";
- &printlog($hash,$logstr,"4");
- }
elsif ($OpMode eq "MotDetSc")
{
# Setreading
@@ -3460,7 +3577,8 @@ return;
+ attr <name> htmlattr target=_blank width="500" height="375" ++ + With these attribute values a streaming link will be opened in a new browser tab. If the stream will be started as an image, the size changes appropriately the + values of width and hight.
+ attr <name> livestreamprefix https://<Servername>:<Port> ++ + The livestream will be stopped again using command "set <name> stopView" . +
set <name> move up 0.5 : bewegt PTZ 0,5 Sek. (zzgl. Prozesszeit) nach oben
@@ -4336,6 +4492,30 @@ return;
set <name> move dir_20 0.7 : bewegt PTZ 1,5 Sek. (zzgl. Prozesszeit) nach links-unten ("CapPTZDirections = 32)"
+ + attr <name> htmlattr target=_blank width="500" height="375" ++ + Mit diesen Attributwerten öffnet der Link als weiteres Fenster/Browsertab. Wird der Stream als Image gestartet, ändert sich die Größe entsprechend der + Angaben von Width und Hight.
+ attr <name> livestreamprefix https://<Servername>:<Port> ++ + Der Livestream wird über das Kommando "set <name> stopView" wieder beendet. +