diff --git a/fhem/CHANGED b/fhem/CHANGED
index fb528a202..d3e028475 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII
- SVN
+ - feature: FHEMWEB: module specific summaryFn/detailFn + defineable webCmdFn
- change: ESA2000: adapted device detection , rename readings
- change: stucture triggers on each change, see event-on-change-reading
- feature: PRESENCE: new mode "function" to use own perl functions for
diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm
index f587288fe..6b6984f6c 100755
--- a/fhem/FHEM/01_FHEMWEB.pm
+++ b/fhem/FHEM/01_FHEMWEB.pm
@@ -19,7 +19,6 @@ sub FW_calcWeblink($$);
sub FW_dev2image($);
sub FW_digestCgi($);
sub FW_doDetail($);
-sub FW_dumpFileLog($$$);
sub FW_fatal($);
sub FW_fileList($);
sub FW_htmlEscape($);
@@ -40,7 +39,6 @@ sub FW_select($$$$$@);
sub FW_serveSpecial($$$$);
sub FW_showLog($);
sub FW_showRoom();
-sub FW_showWeblink($$$$);
sub FW_style($$);
sub FW_submit($$@);
sub FW_substcfg($$$$$$);
@@ -59,7 +57,7 @@ use vars qw($FW_gplotdir);# gplot directory for web server: the first
# available from $FW_dir/gplot,$FW_dir
use vars qw($MW_dir); # moddir (./FHEM), needed by edit Files in new
# structure
-use vars qw($FW_ME); # webname (default is fhem), needed by 97_GROUP
+use vars qw($FW_ME); # webname (default is fhem), used by 97_GROUP/weblink
use vars qw($FW_ss); # is smallscreen, needed by 97_GROUP/95_VIEW
use vars qw($FW_tp); # is touchpad (iPad / etc)
use vars qw($FW_sp); # stylesheetPrefix
@@ -68,9 +66,12 @@ use vars qw($FW_sp); # stylesheetPrefix
use vars qw(%FW_types); # device types,
use vars qw($FW_RET); # Returned data (html)
use vars qw($FW_wname); # Web instance
-use vars qw($FW_subdir); # Sub-path in URL for extensions, e.g. 95_FLOORPLAN
+use vars qw($FW_subdir); # Sub-path in URL, used by FLOORPLAN/weblink
use vars qw(%FW_pos); # scroll position
use vars qw($FW_cname); # Current connection name
+use vars qw(%FW_hiddenroom); # hash of hidden rooms, used by weblink
+use vars qw($FW_plotmode);# Global plot mode (WEB attribute), used by weblink
+use vars qw($FW_plotsize);# Global plot size (WEB attribute), used by weblink
my $FW_zlib_checked;
my $FW_use_zlib = 1;
@@ -86,13 +87,10 @@ my $FW_data; # Filecontent from browser when editing a file
my $FW_detail; # currently selected device for detail view
my %FW_devs; # hash of from/to entries per device
my %FW_icons; # List of icons
-my $FW_plotmode; # Global plot mode (WEB attribute)
-my $FW_plotsize; # Global plot size (WEB attribute)
my $FW_RETTYPE; # image/png or the like
my $FW_room; # currently selected room
my %FW_rooms; # hash of all rooms
my %FW_types; # device types, for sorting
-my %FW_hiddenroom; # hash of hidden rooms
my %FW_hiddengroup;# hash of hidden groups
my $FW_inform;
my $FW_XHR; # Data only answer, no HTML
@@ -116,7 +114,7 @@ FHEMWEB_Initialize($)
$hash->{UndefFn} = "FW_Undef";
$hash->{NotifyFn}= "FW_SecurityCheck";
$hash->{AttrList}=
- "loglevel:0,1,2,3,4,5,6 webname fwcompress:0,1 javascripts ".
+ "loglevel:0,1,2,3,4,5,6 webname fwcompress:0,1 ".
"plotmode:gnuplot,gnuplot-scroll,SVG plotsize endPlotToday:1,0 plotfork ".
"stylesheetPrefix touchpad:deprecated smallscreen:deprecated ".
"basicAuth basicAuthMsg hiddenroom hiddengroup HTTPS allowfrom CORS:0,1 ".
@@ -124,10 +122,7 @@ FHEMWEB_Initialize($)
###############
# Initialize internal structures
- addToAttrList("webCmd");
- addToAttrList("icon");
- addToAttrList("devStateIcon");
- addToAttrList("sortby");
+ map { addToAttrList($_) } ( "webCmd", "icon", "devStateIcon", "sortby");
InternalTimer(time()+60, "FW_closeOldClients", 0, 0);
$FW_dir = "$attr{global}{modpath}/www";
@@ -135,6 +130,9 @@ FHEMWEB_Initialize($)
$FW_cssdir = "$FW_dir/pgm2";
$FW_gplotdir = "$FW_dir/gplot";
+ $data{webCmdFn}{slider} = "FW_sliderFn";
+ $data{webCmdFn}{timepicker} = "FW_timepickerFn";
+ $data{webCmdFn}{"~dropdown"}= "FW_dropdownFn"; # Should be the last
}
#####################################
@@ -450,13 +448,13 @@ FW_answerCall($)
# Axels FHEMWEB modules...
if(defined($data{FWEXT})) {
foreach my $k (sort keys %{$data{FWEXT}}) {
- if($arg =~ m/^$k/) {
- no strict "refs";
- #Returns undef if it already sent a HTTP header
- ($FW_RETTYPE, $FW_RET) = &{$data{FWEXT}{$k}{FUNC}}($arg);
- use strict "refs";
- return defined($FW_RETTYPE) ? 0 : -1;
- }
+ my $h = $data{FWEXT}{$k};
+ next if($arg !~ m/^$k/ || $h !~ m/HASH/ || !$h->{FUNC});
+ no strict "refs";
+ #Returns undef if it already sent a HTTP header
+ ($FW_RETTYPE, $FW_RET) = &{$h->{FUNC}}($arg);
+ use strict "refs";
+ return defined($FW_RETTYPE) ? 0 : -1;
}
}
@@ -542,9 +540,6 @@ FW_answerCall($)
my $jsTemplate = '';
FW_pO sprintf($jsTemplate, "$FW_ME/pgm2/svg.js") if($FW_plotmode eq "SVG");
FW_pO sprintf($jsTemplate, "$FW_ME/pgm2/fhemweb.js");
- foreach my $js (split(",", AttrVal($FW_wname, "javascripts", ""))) {
- FW_pO sprintf($jsTemplate, $js);
- }
my $onload = AttrVal($FW_wname, "longpoll", undef) ?
"onload=\"FW_delayedStart()\"" : "";
@@ -564,13 +559,13 @@ FW_answerCall($)
}
FW_pO "";
- }
+ }
FW_roomOverview($cmd);
if($cmd =~ m/^style /) { FW_style($cmd,undef); }
+ elsif($cmd =~ /^logwrapper/) { return FW_logWrapper($cmd); }
elsif($FW_detail) { FW_doDetail($FW_detail); }
elsif($FW_room) { FW_showRoom(); }
- elsif($cmd =~ /^logwrapper/) { return FW_logWrapper($cmd); }
elsif(!$FW_cmdret && AttrVal("global", "motd", "none") ne "none") {
my $motd = AttrVal("global","motd",undef);
$motd =~ s/\n/ /g;
@@ -721,6 +716,7 @@ FW_makeTable($$@)
}
##############################
+# Used only for set or attr lists.
sub
FW_makeSelect($$$$)
{
@@ -787,13 +783,6 @@ FW_doDetail($)
FW_makeSelect($d, "attr", $attrList,"attr");
FW_makeTable($d, $attr{$d}, "deleteattr"); # Attributes
-
- if($t eq "FileLog" ) {
- FW_pO "
";
- FW_dumpFileLog($d, 0, 1);
- FW_pO "
";
- }
-
## dependent objects
my @dob; # dependent objects - triggered by current device
foreach my $dn (sort keys %defs) {
@@ -806,13 +795,14 @@ FW_doDetail($)
}
FW_makeTableFromArray("Probably associated with", @dob);
- FW_pO "";
-
- if($t eq "weblink") {
- FW_showWeblink($d, $defs{$d}{LINK}, $defs{$d}{WLTYPE}, 1);
- FW_pO " ";
+ if($modules{$t}{FW_detailFn}) {
+ no strict "refs";
+ FW_pO &{$modules{$t}{FW_detailFn}}($FW_chash, $d, $FW_room) . " ";
+ use strict "refs";
}
+ FW_pO "";
+
FW_pH "cmd=style iconFor $d", "Select icon";
FW_pH "cmd=style showDSI $d", "Extend devStateIcon";
FW_pH "$FW_ME/docs/commandref.html#${t}", "Device specific help";
@@ -861,8 +851,8 @@ FW_roomOverview($)
$FW_room = AttrVal($FW_detail, "room", undef);
$FW_room = $1 if($FW_room && $FW_room =~ m/^([^,]*),/);
$FW_room = "" if(!$FW_room);
- FW_pHPlain "room=$FW_room",
- "" . FW_makeImage("back") . "
";
+ FW_pO(FW_pHPlain("room=$FW_room",
+ "" . FW_makeImage("back") . "
"));
FW_pO "";
return;
@@ -884,7 +874,7 @@ FW_roomOverview($)
}
########################
- # FW Extensions
+ # Show FW Extensions in the menu
if(defined($data{FWEXT})) {
foreach my $k (sort keys %{$data{FWEXT}}) {
my $h = $data{FWEXT}{$k};
@@ -1020,15 +1010,15 @@ FW_showRoom()
my $rf = ($FW_room ? "&room=$FW_room" : ""); # stay in the room
- # array of all device names in the room (exception weblinks without group attribute)
+ # array of all device names in the room (exception weblinks without group
+ # attribute)
my @devs= grep { ($FW_rooms{$FW_room}{$_}||$FW_room eq "all") &&
!IsIgnored($_) } keys %defs;
-
- my %group;
- my @weblinks;
+ my (%group, @atEnds);
foreach my $dev (@devs) {
- if($defs{$dev}{TYPE} eq "weblink" && !AttrVal($dev, "group", undef)) {
- push @weblinks, $dev;
+ if($modules{$defs{$dev}{TYPE}}{FW_atPageEnd} &&
+ !AttrVal($dev, "group", undef)) {
+ push @atEnds, $dev;
next;
}
foreach my $grp (split(",", AttrVal($dev, "group", $FW_types{$dev}))) {
@@ -1039,6 +1029,7 @@ FW_showRoom()
# row counter
my $row=1;
+ my %extPage = ();
# iterate over the distinct groups
foreach my $g (sort keys %group) {
@@ -1067,95 +1058,38 @@ FW_showRoom()
}
$row++;
- if($type eq "weblink") {
+ if($modules{$type}{FW_summaryFn}) {
FW_pO "";
- FW_showWeblink($d, $defs{$d}{LINK}, $defs{$d}{WLTYPE}, undef);
+ no strict "refs";
+ FW_pO &{$modules{$type}{FW_summaryFn}}($FW_chash, $d, $FW_room, \%extPage);
+ use strict "refs";
FW_pO " ";
next;
}
my ($allSets, $cmdlist, $txt) = FW_devState($d, $rf);
- FW_pO "$txt";
+ FW_pO " $txt ";
######
# Commands, slider, dropdown
- if(!$FW_ss) {
- FW_pO "";
- if($cmdlist) {
- my @cList = split(":", $cmdlist);
- my $firstIdx = 0;
-
- # Special handling (slider, dropdown)
- my $cmd = $cList[0];
+ if(!$FW_ss && $cmdlist) {
+ foreach my $cmd (split(":", $cmdlist)) {
+ my $htmlTxt;
if($allSets && $allSets =~ m/$cmd:([^ ]*)/) {
my $values = $1;
-
- if($values =~ m/^slider,(.*),(.*),(.*)/) { ##### Slider
- my ($min,$stp, $max) = ($1, $2, $3);
- my $srf = $FW_room ? "&room=$FW_room" : "";
- my $cv = ReadingsVal($d, $cmd, Value($d));
- $cmd = "" if($cmd eq "state");
- $cv =~ s/.*?(\d+).*/$1/; # get first number
- $cv = 0 if($cv !~ m/\d/);
- FW_pO "".
- "".
- "".
- " ";
- $firstIdx=1;
-
- } elsif($values =~ m/^time$/) { ##### Time picker
- my $srf = $FW_room ? "&room=$FW_room" : "";
- my $cv = ReadingsVal($d, $cmd, Value($d));
- $cmd = "" if($cmd eq "state");
- my $c = "\"$FW_ME?cmd=set $d $cmd %$srf\"";
- FW_pO "".
- " ".
- " ".
- " ";
- $firstIdx=1;
-
- } else { ##### Dropdown
-
- my @tv = split(",", $values);
- # Hack: eventmap (translation only) should not result in a
- # dropdown. eventMap/webCmd/etc handling must be cleaned up.
- if(@tv > 1) {
- $firstIdx=1;
- if($cmd eq "desired-temp" || $cmd eq "desiredTemperature") {
- $txt = ReadingsVal($d, $cmd, 20);
- $txt =~ s/ .*//; # Cut off Celsius
- $txt = sprintf("%2.1f", int(2*$txt)/2) if($txt =~ m/[0-9.-]/);
- } else {
- $txt = Value($d);
- $txt =~ s/$cmd //;
- }
- FW_pO "".
- FW_hidden("arg.$d", $cmd) .
- FW_hidden("dev.$d", $d) .
- ($FW_room ? FW_hidden("room", $FW_room) : "") .
- FW_select("$d-$cmd","val.$d", \@tv, $txt, "dropdown").
- " ".
- FW_submit("cmd.$d", "set").
- " ";
- }
+ foreach my $fn (sort keys %{$data{webCmdFn}}) {
+ no strict "refs";
+ $htmlTxt = &{$data{webCmdFn}{$fn}}($d,$cmd,$values);
+ use strict "refs";
+ last if($htmlTxt);
}
}
+ if($htmlTxt) {
+ FW_pO $htmlTxt;
- for(my $idx=$firstIdx; $idx < @cList; $idx++) {
- FW_pH "cmd.$d=set $d $cList[$idx]$rf", $cList[$idx], 1,"col3";
+ } else {
+ FW_pH "cmd.$d=set $d $cmd$rf", $cmd, 1, "col3";
}
-
-
- } elsif($type eq "FileLog") {
- $row = FW_dumpFileLog($d, 1, $row);
-
}
}
FW_pO "";
@@ -1165,12 +1099,13 @@ FW_showRoom()
}
FW_pO " ";
- # Now the weblinks
- my $buttons = 1;
+ # Now the "atEnds"
foreach my $d (sort { lc(AttrVal($a, "sortby", AttrVal($a,"alias",$a))) cmp
lc(AttrVal($b, "sortby", AttrVal($b,"alias",$b))) }
- @weblinks) {
- $buttons = FW_showWeblink($d, $defs{$d}{LINK}, $defs{$d}{WLTYPE}, $buttons);
+ @atEnds) {
+ no strict "refs";
+ FW_pO &{$modules{$defs{$d}{TYPE}}{FW_summaryFn}}($FW_chash, $d, $FW_room, \%extPage);
+ use strict "refs";
}
FW_pO "";
FW_pO "";
@@ -1283,7 +1218,8 @@ FW_logWrapper($)
if(defined($type) && $type eq "text") {
$defs{$d}{logfile} =~ m,^(.*)/([^/]*)$,; # Dir and File
my $path = "$1/$file";
- $path =~ s/%L/$attr{global}{logdir}/g if($path =~ m/%/ && $attr{global}{logdir}); # %L present and log directory defined
+ $path =~ s/%L/$attr{global}{logdir}/g
+ if($path =~ m/%/ && $attr{global}{logdir});
$path = AttrVal($d,"archivedir","") . "/$file" if(!-f $path);
FW_pO "";
@@ -1310,10 +1246,10 @@ FW_logWrapper($)
} else {
FW_pO "
";
FW_pO "
";
- FW_zoomLink("cmd=$cmd;zoom=-1", "Zoom-in", "zoom in");
- FW_zoomLink("cmd=$cmd;zoom=1", "Zoom-out","zoom out");
- FW_zoomLink("cmd=$cmd;off=-1", "Prev", "prev");
- FW_zoomLink("cmd=$cmd;off=1", "Next", "next");
+ FW_pO FW_zoomLink("cmd=$cmd;zoom=-1", "Zoom-in", "zoom in");
+ FW_pO FW_zoomLink("cmd=$cmd;zoom=1", "Zoom-out","zoom out");
+ FW_pO FW_zoomLink("cmd=$cmd;off=-1", "Prev", "prev");
+ FW_pO FW_zoomLink("cmd=$cmd;off=1", "Next", "next");
FW_pO "
";
FW_pO " ";
my $logtype = $defs{$d}{TYPE};
@@ -1658,9 +1594,9 @@ FW_zoomLink($$$)
$val = "day" if(!$val);
$val = $FW_zoom{$val};
- return if(!defined($val) || $val+$off < 0 || $val+$off >= int(@FW_zoom) );
+ return "" if(!defined($val) || $val+$off < 0 || $val+$off >= int(@FW_zoom));
$val = $FW_zoom[$val+$off];
- return if(!$val);
+ return "" if(!$val);
# Approximation of the next offset.
my $w_off = $FW_pos{off};
@@ -1683,7 +1619,7 @@ FW_zoomLink($$$)
} else {
- return if((!$val && $off > 0) || ($val && $val+$off > 0)); # no future
+ return "" if((!$val && $off > 0) || ($val && $val+$off > 0)); # no future
$off=($val ? $val+$off : $off);
my $zoom=$FW_pos{zoom};
$zoom = 0 if(!$zoom);
@@ -1691,8 +1627,7 @@ FW_zoomLink($$$)
}
- FW_pO " ";
- FW_pHPlain "$cmd", FW_makeImage($img, $alt);
+ return " ".FW_pHPlain("$cmd", FW_makeImage($img, $alt));
}
##################
@@ -2010,36 +1945,43 @@ FW_pO(@)
sub
FW_pH(@)
{
- my ($link, $txt, $td, $class) = @_;
+ my ($link, $txt, $td, $class, $doRet) = @_;
+ my $ret = "";
- FW_pO " " if($td);
- $link = ($link =~ m,^/,) ? $link : "$FW_ME$FW_subdir?$link";
- $class = "" if(!defined($class));
- $class = " class=\"$class\"" if($class);
+ $ret .= " " if($td);
+ $link = ($link =~ m,^/,) ? $link : "$FW_ME$FW_subdir?$link";
+ $class = "" if(!defined($class));
+ $class = " class=\"$class\"" if($class);
- # Using onclick, as href starts safari in a webapp.
- # Known issue: the pointer won't change
- if($FW_ss || $FW_tp) {
- FW_pO "$txt
";
+ # Using onclick, as href starts safari in a webapp.
+ # Known issue: the pointer won't change
+ if($FW_ss || $FW_tp) {
+ $ret .= "$txt
";
- } else {
- FW_pO "$txt
";
- }
- FW_pO " " if($td);
+ } else {
+ $ret .= "$txt
";
+ }
+ $ret .= "" if($td);
+ return $ret if($doRet);
+ FW_pO $ret;
}
+#################
+# href without class/div, returned as a string
sub
FW_pHPlain(@)
{
- my ($link, $txt, $td) = @_;
+ my ($link, $txt, $td) = @_;
- FW_pO "" if($td);
- if($FW_ss || $FW_tp) {
- FW_pO "$txt ";
- } else {
- FW_pO "$txt ";
- }
- FW_pO " " if($td);
+ my $ret = "";
+ $ret .= "" if($td);
+ if($FW_ss || $FW_tp) {
+ $ret .= "$txt ";
+ } else {
+ $ret .= "$txt ";
+ }
+ $ret .= " " if($td);
+ return $ret;
}
@@ -2084,92 +2026,6 @@ FW_fC($@)
return $ret;
}
-##################
-sub
-FW_showWeblinkDetail($)
-{
- my ($d)= @_;
- my $alias= AttrVal($d, "alias", $d);
-
- FW_pO " ";
- FW_pHPlain("detail=$d", $alias) if(!$FW_subdir);
- FW_pO " ";
-}
-
-sub
-FW_showWeblink($$$$)
-{
- my ($d, $v, $t, $buttons) = @_;
-
- my $attr = AttrVal($d, "htmlattr", "");
-
- if($t eq "htmlCode") {
- $v = AnalyzePerlCommand($FW_chash, $v) if($v =~ m/^{(.*)}$/);
- FW_pO $v;
-
- } elsif($t eq "link") {
- FW_pO "$d "; # no FW_pH, want to open extra browser
-
- } elsif($t eq "image") {
- FW_pO " ";
- FW_showWeblinkDetail($d);
-
- } elsif($t eq "iframe") {
- FW_pO "";
- FW_showWeblinkDetail($d);
-
- } elsif($t eq "fileplot" || $t eq "dbplot" ) {
-
- # plots navigation buttons
- if($buttons &&
- ($defs{$d}{WLTYPE} eq "fileplot" || $defs{$d}{WLTYPE} eq "dbplot") &&
- AttrVal($d, "fixedrange", "x") !~ m/^[ 0-9:-]*$/) {
-
- FW_zoomLink("zoom=-1", "Zoom-in", "zoom in");
- FW_zoomLink("zoom=1", "Zoom-out","zoom out");
- FW_zoomLink("off=-1", "Prev", "prev");
- FW_zoomLink("off=1", "Next", "next");
- $buttons = 0;
- FW_pO " ";
- }
-
- my @va = split(":", $v, 3);
- if($defs{$d}{WLTYPE} eq "fileplot" &&
- (@va != 3 || !$defs{$va[0]} || !$defs{$va[0]}{currentlogfile})) {
- FW_pO "Broken definition for fileplot $d: $v ";
-
- } elsif ($defs{$d}{WLTYPE} eq "dbplot" && (@va != 2 || !$defs{$va[0]})) {
- FW_pO "Broken definition for dbplot $d: $v ";
-
- } else {
- if(defined($va[2]) && $va[2] eq "CURRENT") {
- $defs{$va[0]}{currentlogfile} =~ m,([^/]*)$,;
- $va[2] = $1;
- }
-
- if ($defs{$d}{WLTYPE} eq "dbplot") {
- $va[2] = "-";
- }
-
- my $wl = "&pos=" . join(";", map {"$_=$FW_pos{$_}"} keys %FW_pos);
-
- my $arg="$FW_ME?cmd=showlog $d $va[0] $va[1] $va[2]$wl";
- if(AttrVal($d,"plotmode",$FW_plotmode) eq "SVG") {
- my ($w, $h) = split(",", AttrVal($d,"plotsize",$FW_plotsize));
- FW_pO "\n";
-
- } else {
- FW_pO " ";
- }
-
- FW_showWeblinkDetail($d) if(!$FW_hiddenroom{detail});
-
- }
- }
- return $buttons;
-}
-
sub
FW_Attr(@)
{
@@ -2355,40 +2211,6 @@ FW_makeEdit($$$)
FW_pO "";
}
-sub
-FW_dumpFileLog($$$)
-{
- my ($d, $oneRow,$row) = @_;
-
- foreach my $f (FW_fileList($defs{$d}{logfile})) {
- my $nr;
-
- if($oneRow) {
- FW_pF "", ($row&1)?"odd":"even";
- FW_pO "$f
";
- }
- foreach my $ln (split(",", AttrVal($d, "logtype", "text"))) {
- my ($lt, $name) = split(":", $ln);
- $name = $lt if(!$name);
- if(!$oneRow) {
- FW_pF " ", ($row&1)?"odd":"even";
- FW_pF "%s
", ($nr ? "" : $f);
- }
- FW_pH "cmd=logwrapper $d $lt $f",
- "$name
", 1, "dval";
- if(!$oneRow) {
- FW_pO " ";
- $row++;
- }
- $nr++;
- }
- if($oneRow) {
- FW_pO " ";
- $row++;
- }
- }
- return $row;
-}
sub
FW_roomStatesForInform($)
@@ -2626,6 +2448,74 @@ FW_htmlEscape($)
return $txt;
}
+sub
+FW_sliderFn($$$)
+{
+ my ($d,$cmd,$values) = @_;
+
+ return undef if($values !~ m/^slider,(.*),(.*),(.*)$/);
+ my ($min,$stp, $max) = ($1, $2, $3);
+ my $srf = $FW_room ? "&room=$FW_room" : "";
+ my $cv = ReadingsVal($d, $cmd, Value($d));
+ $cmd = "" if($cmd eq "state");
+ my $id = ($cmd eq "state") ? "" : "-$cmd";
+ $cv =~ s/.*?(\d+).*/$1/; # get first number
+ $cv = 0 if($cv !~ m/\d/);
+ return "".
+ "".
+ "".
+ " ";
+}
+
+sub
+FW_timepickerFn()
+{
+ my ($d,$cmd,$values) = @_;
+
+ return undef if($values ne "time");
+ my $srf = $FW_room ? "&room=$FW_room" : "";
+ my $cv = ReadingsVal($d, $cmd, Value($d));
+ $cmd = "" if($cmd eq "state");
+ my $c = "\"$FW_ME?cmd=set $d $cmd %$srf\"";
+ return "".
+ " ".
+ " ".
+ " ";
+}
+
+sub
+FW_dropdownFn()
+{
+ my ($d,$cmd,$values) = @_;
+
+ my @tv = split(",", $values);
+ # Hack: eventmap (translation only) should not result in a
+ # dropdown. eventMap/webCmd/etc handling must be cleaned up.
+ if(@tv > 1) {
+ my $txt;
+ if($cmd eq "desired-temp" || $cmd eq "desiredTemperature") {
+ $txt = ReadingsVal($d, $cmd, 20);
+ $txt =~ s/ .*//; # Cut off Celsius
+ $txt = sprintf("%2.1f", int(2*$txt)/2) if($txt =~ m/[0-9.-]/);
+ } else {
+ $txt = Value($d);
+ $txt =~ s/$cmd //;
+ }
+ return " ";
+ }
+ return undef;
+}
+
1;
=pod
diff --git a/fhem/FHEM/92_FileLog.pm b/fhem/FHEM/92_FileLog.pm
index 7ba3ce8f9..326ced67b 100755
--- a/fhem/FHEM/92_FileLog.pm
+++ b/fhem/FHEM/92_FileLog.pm
@@ -6,6 +6,7 @@ use strict;
use warnings;
use IO::File;
#use Devel::Size qw(size total_size);
+use vars qw($FW_ss); # is smallscreen
sub seekTo($$$$);
@@ -23,6 +24,9 @@ FileLog_Initialize($)
$hash->{AttrFn} = "FileLog_Attr";
# logtype is used by the frontend
$hash->{AttrList} = "disable:0,1 logtype nrarchive archivedir archivecmd";
+
+ $hash->{FW_summaryFn} = "FW_dumpFileLog";
+ $hash->{FW_detailFn} = "FW_dumpFileLog";
}
@@ -94,6 +98,7 @@ FileLog_Log($$)
my $ln = $log->{NAME};
return if($attr{$ln} && $attr{$ln}{disable});
+ return if(!$dev || !defined($dev->{CHANGED}));
my $n = $dev->{NAME};
my $re = $log->{REGEXP};
@@ -161,6 +166,38 @@ FileLog_Set($@)
return undef;
}
+#########################
+sub
+FW_dumpFileLog($$$$)
+{
+ my ($FW_chash, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
+
+ return "$defs{$d}{STATE}
"
+ if($FW_ss && $pageHash);
+
+ my $row = 0;
+ my $ret = sprintf("", $pageHash ? "" : "block ");
+ foreach my $f (FW_fileList($defs{$d}{logfile})) {
+ my $class = (!$pageHash ? (($row++&1)?"odd":"even") : "");
+ $ret .= "";
+ $ret .= "$f
";
+ my $idx = 0;
+ foreach my $ln (split(",", AttrVal($d, "logtype", "text"))) {
+ if($FW_ss && $idx++) {
+ $ret .= " ";
+ }
+ my ($lt, $name) = split(":", $ln);
+ $name = $lt if(!$name);
+ $ret .= FW_pH("cmd=logwrapper $d $lt $f",
+ "$name
", 1, "dval", 1);
+ }
+ $ret .= " ";
+ }
+ $ret .= "
";
+ return $ret;
+}
+
+
###################################
# We use this function to be able to scroll/zoom in the plots created from the
# logfile. When outfile is specified, it is used with gnuplot post-processing,
diff --git a/fhem/FHEM/98_weblink.pm b/fhem/FHEM/98_weblink.pm
index 037713a04..68f690aa8 100755
--- a/fhem/FHEM/98_weblink.pm
+++ b/fhem/FHEM/98_weblink.pm
@@ -4,6 +4,11 @@ package main;
use strict;
use warnings;
+use vars qw($FW_subdir); # Sub-path in URL for extensions, e.g. 95_FLOORPLAN
+use vars qw($FW_ME); # webname (default is fhem), needed by 97_GROUP
+use vars qw(%FW_hiddenroom); # hash of hidden rooms, used by weblink
+use vars qw($FW_plotmode);# Global plot mode (WEB attribute), used by weblink
+use vars qw($FW_plotsize);# Global plot size (WEB attribute), used by weblink
#####################################
sub
@@ -12,7 +17,11 @@ weblink_Initialize($)
my ($hash) = @_;
$hash->{DefFn} = "weblink_Define";
- $hash->{AttrList}= "fixedrange plotmode plotsize label title htmlattr plotfunction";
+ $hash->{AttrList} = "fixedrange plotmode plotsize label ".
+ "title htmlattr plotfunction";
+ $hash->{FW_summaryFn} = "weblink_FwFn";
+ $hash->{FW_detailFn} = "weblink_FwFn";
+ $hash->{FW_atPageEnd} = 1;
}
@@ -34,6 +43,110 @@ weblink_Define($$)
return undef;
}
+#####################################
+# FLOORPLAN compat
+sub
+FW_showWeblink($$$$)
+{
+ my ($d,undef,undef,$buttons) = @_;
+
+ if($buttons !~ m/HASH/) {
+ my %h = (); $buttons = \%h;
+ }
+ FW_pO weblink_FwFn(undef, $d, "", $buttons);
+ return $buttons;
+}
+
+
+##################
+sub
+weblink_FwDetail($)
+{
+ my ($d)= @_;
+ my $alias= AttrVal($d, "alias", $d);
+
+ my $ret = " ";
+ $ret .= FW_pHPlain("detail=$d", $alias) if(!$FW_subdir);
+ FW_pO " ";
+ return $ret;
+}
+
+sub
+weblink_FwFn($$$$)
+{
+ my ($FW_chash, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
+ my $hash = $defs{$d};
+ my $link = $hash->{LINK};
+ my $wltype = $hash->{WLTYPE};
+ my $ret = "";
+
+ my $attr = AttrVal($d, "htmlattr", "");
+ if($wltype eq "htmlCode") {
+ $link = AnalyzePerlCommand(undef, $link) if($link =~ m/^{(.*)}$/);
+ $ret = $link;
+
+ } elsif($wltype eq "link") {
+ $ret = "$d "; # no FW_pH, open extra browser
+
+ } elsif($wltype eq "image") {
+ $ret = " " .
+ weblink_FwDetail($d);
+
+ } elsif($wltype eq "iframe") {
+ $ret = "" .
+ weblink_FwDetail($d);
+
+ } elsif($wltype eq "fileplot" || $wltype eq "dbplot" ) {
+
+ # plots navigation buttons
+ if((!$pageHash || !$pageHash->{buttons}) &&
+ ($wltype eq "fileplot" || $wltype eq "dbplot") &&
+ AttrVal($d, "fixedrange", "x") !~ m/^[ 0-9:-]*$/) {
+
+ $ret .= FW_zoomLink("zoom=-1", "Zoom-in", "zoom in");
+ $ret .= FW_zoomLink("zoom=1", "Zoom-out","zoom out");
+ $ret .= FW_zoomLink("off=-1", "Prev", "prev");
+ $ret .= FW_zoomLink("off=1", "Next", "next");
+ $pageHash->{buttons} = 1 if($pageHash);
+ $ret .= " ";
+ }
+
+ my @va = split(":", $link, 3);
+ if($wltype eq "fileplot" &&
+ (@va != 3 || !$defs{$va[0]} || !$defs{$va[0]}{currentlogfile})) {
+ $ret .= "Broken definition for fileplot $d: $link ";
+
+ } elsif ($wltype eq "dbplot" && (@va != 2 || !$defs{$va[0]})) {
+ $ret .= "Broken definition for dbplot $d: $link ";
+
+ } else {
+ if(defined($va[2]) && $va[2] eq "CURRENT") {
+ $defs{$va[0]}{currentlogfile} =~ m,([^/]*)$,;
+ $va[2] = $1;
+ }
+
+ if ($wltype eq "dbplot") {
+ $va[2] = "-";
+ }
+
+ my $wl = "&pos=" . join(";", map {"$_=$FW_pos{$_}"} keys %FW_pos);
+
+ my $arg="$FW_ME?cmd=showlog $d $va[0] $va[1] $va[2]$wl";
+ if(AttrVal($d,"plotmode",$FW_plotmode) eq "SVG") {
+ my ($w, $h) = split(",", AttrVal($d,"plotsize",$FW_plotsize));
+ $ret .= "\n";
+
+ } else {
+ $ret .= " ";
+ }
+
+ $ret .= weblink_FwDetail($d) if(!$FW_hiddenroom{detail} && $pageHash);
+ }
+ }
+ return $ret;
+}
+
1;
=pod