2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 16:56:54 +00:00

module dependent summaryFn and detailFn for FHEMWEB

Defineable webCmdFn for FHEMWEB


git-svn-id: https://svn.fhem.de/fhem/trunk@3102 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2013-04-22 18:27:46 +00:00
parent 66ce0f6e72
commit 7c1d2eab9e
4 changed files with 316 additions and 275 deletions

View File

@ -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

View File

@ -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 = '<script type="text/javascript" src="%s"></script>';
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()\"" : "";
@ -568,9 +563,9 @@ FW_answerCall($)
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/<br>/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 "<table class=\"block wide\">";
FW_dumpFileLog($d, 0, 1);
FW_pO "</table>";
}
## 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 "</td></tr></table>";
if($t eq "weblink") {
FW_showWeblink($d, $defs{$d}{LINK}, $defs{$d}{WLTYPE}, 1);
FW_pO "<br><br>";
if($modules{$t}{FW_detailFn}) {
no strict "refs";
FW_pO &{$modules{$t}{FW_detailFn}}($FW_chash, $d, $FW_room) . "<br>";
use strict "refs";
}
FW_pO "</td></tr></table>";
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",
"<div id=\"back\">" . FW_makeImage("back") . "</div>";
FW_pO(FW_pHPlain("room=$FW_room",
"<div id=\"back\">" . FW_makeImage("back") . "</div>"));
FW_pO "<div id=\"menu\">$FW_detail details</div>";
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 ? "&amp;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 "<td>";
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 "</td>";
next;
}
my ($allSets, $cmdlist, $txt) = FW_devState($d, $rf);
FW_pO "<td id=\"$d\">$txt";
FW_pO "<td id=\"$d\">$txt</td>";
######
# Commands, slider, dropdown
if(!$FW_ss) {
FW_pO "</td>";
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 "<td colspan='2'>".
"<div class='slider' id='slider.$d' ".
"min='$min' stp='$stp' max='$max' ".
"cmd='$FW_ME?cmd=set $d $cmd %$srf'>".
"<div class='handle'>$min</div></div>".
"<script type=\"text/javascript\">" .
"Slider(document.getElementById('slider.$d'),'$cv')".
"</script>".
"</td>";
$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 "<td colspan='2'>".
"<input name='time.$d' value='$cv' type='text'".
" readonly size='5'>".
"<input type='button' value='+'".
" onclick='addTime(this,$c)'>".
"</td>";
$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 "<td>".
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").
"</td><td>".
FW_submit("cmd.$d", "set").
"</td>";
}
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 "</tr>";
@ -1165,12 +1099,13 @@ FW_showRoom()
}
FW_pO "</table><br>";
# 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 "</div>";
FW_pO "</form>";
@ -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 "<div id=\"content\">";
@ -1310,10 +1246,10 @@ FW_logWrapper($)
} else {
FW_pO "<div id=\"content\">";
FW_pO "<br>";
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 "<table><tr><td>";
FW_pO "<td>";
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 "&nbsp;&nbsp;";
FW_pHPlain "$cmd", FW_makeImage($img, $alt);
return "&nbsp;&nbsp;".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 "<td>" if($td);
$link = ($link =~ m,^/,) ? $link : "$FW_ME$FW_subdir?$link";
$class = "" if(!defined($class));
$class = " class=\"$class\"" if($class);
$ret .= "<td>" 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 "<a onClick=\"location.href='$link'\"><div$class>$txt</div></a>";
# Using onclick, as href starts safari in a webapp.
# Known issue: the pointer won't change
if($FW_ss || $FW_tp) {
$ret .= "<a onClick=\"location.href='$link'\"><div$class>$txt</div></a>";
} else {
FW_pO "<a href=\"$link\"><div$class>$txt</div></a>";
}
FW_pO "</td>" if($td);
} else {
$ret .= "<a href=\"$link\"><div$class>$txt</div></a>";
}
$ret .= "</td>" 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 "<td>" if($td);
if($FW_ss || $FW_tp) {
FW_pO "<a onClick=\"location.href='$FW_ME$FW_subdir?$link'\">$txt</a>";
} else {
FW_pO "<a href=\"$FW_ME$FW_subdir?$link\">$txt</a>";
}
FW_pO "</td>" if($td);
my $ret = "";
$ret .= "<td>" if($td);
if($FW_ss || $FW_tp) {
$ret .= "<a onClick=\"location.href='$FW_ME$FW_subdir?$link'\">$txt</a>";
} else {
$ret .= "<a href=\"$FW_ME$FW_subdir?$link\">$txt</a>";
}
$ret .= "</td>" 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 "<br>";
FW_pHPlain("detail=$d", $alias) if(!$FW_subdir);
FW_pO "<br>";
}
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 "<a href=\"$v\" $attr>$d</a>"; # no FW_pH, want to open extra browser
} elsif($t eq "image") {
FW_pO "<img src=\"$v\" $attr><br>";
FW_showWeblinkDetail($d);
} elsif($t eq "iframe") {
FW_pO "<iframe src=\"$v\" $attr>Iframes disabled</iframe>";
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 "<br>";
}
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<br>";
} elsif ($defs{$d}{WLTYPE} eq "dbplot" && (@va != 2 || !$defs{$va[0]})) {
FW_pO "Broken definition for dbplot $d: $v<br>";
} 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 = "&amp;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 "<embed src=\"$arg\" type=\"image/svg+xml\" " .
"width=\"$w\" height=\"$h\" name=\"$d\"/>\n";
} else {
FW_pO "<img src=\"$arg\"/>";
}
FW_showWeblinkDetail($d) if(!$FW_hiddenroom{detail});
}
}
return $buttons;
}
sub
FW_Attr(@)
{
@ -2355,40 +2211,6 @@ FW_makeEdit($$$)
FW_pO "</td>";
}
sub
FW_dumpFileLog($$$)
{
my ($d, $oneRow,$row) = @_;
foreach my $f (FW_fileList($defs{$d}{logfile})) {
my $nr;
if($oneRow) {
FW_pF "<tr class=\"%s\">", ($row&1)?"odd":"even";
FW_pO "<td><div class=\"dname\">$f</div></td>";
}
foreach my $ln (split(",", AttrVal($d, "logtype", "text"))) {
my ($lt, $name) = split(":", $ln);
$name = $lt if(!$name);
if(!$oneRow) {
FW_pF "<tr class=\"%s\">", ($row&1)?"odd":"even";
FW_pF "<td><div class=\"dname\">%s</div></td>", ($nr ? "" : $f);
}
FW_pH "cmd=logwrapper $d $lt $f",
"<div class=\"dval\">$name</div>", 1, "dval";
if(!$oneRow) {
FW_pO "</tr>";
$row++;
}
$nr++;
}
if($oneRow) {
FW_pO "</tr>";
$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 "<td colspan='2'>".
"<div class='slider' id='slider.$d$id' ".
"min='$min' stp='$stp' max='$max' ".
"cmd='$FW_ME?cmd=set $d $cmd %$srf'>".
"<div class='handle'>$min</div></div>".
"<script type=\"text/javascript\">" .
"Slider(document.getElementById('slider.$d$id'),'$cv')</script>".
"</td>";
}
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 "<td colspan='2'>".
"<input name='time.$d' value='$cv' type='text' readonly size='5'>".
"<input type='button' value='+' onclick='addTime(this,$c)'>".
"</td>";
}
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 "<td colspan='2'><form>".
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").
"</form></td>";
}
return undef;
}
1;
=pod

View File

@ -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 "<div id=\"$d\" align=\"center\" class=\"col2\">$defs{$d}{STATE}</div>"
if($FW_ss && $pageHash);
my $row = 0;
my $ret = sprintf("<table class=\"%swide\">", $pageHash ? "" : "block ");
foreach my $f (FW_fileList($defs{$d}{logfile})) {
my $class = (!$pageHash ? (($row++&1)?"odd":"even") : "");
$ret .= "<tr class=\"$class\">";
$ret .= "<td><div class=\"dname\">$f</div></td>";
my $idx = 0;
foreach my $ln (split(",", AttrVal($d, "logtype", "text"))) {
if($FW_ss && $idx++) {
$ret .= "</tr><tr class=\"".(($row++&1)?"odd":"even")."\"><td>";
}
my ($lt, $name) = split(":", $ln);
$name = $lt if(!$name);
$ret .= FW_pH("cmd=logwrapper $d $lt $f",
"<div class=\"dval\">$name</div>", 1, "dval", 1);
}
$ret .= "</tr>";
}
$ret .= "</table>";
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,

View File

@ -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 = "<br>";
$ret .= FW_pHPlain("detail=$d", $alias) if(!$FW_subdir);
FW_pO "<br>";
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 = "<a href=\"$link\" $attr>$d</a>"; # no FW_pH, open extra browser
} elsif($wltype eq "image") {
$ret = "<img src=\"$link\" $attr><br>" .
weblink_FwDetail($d);
} elsif($wltype eq "iframe") {
$ret = "<iframe src=\"$link\" $attr>Iframes disabled</iframe>" .
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 .= "<br>";
}
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<br>";
} elsif ($wltype eq "dbplot" && (@va != 2 || !$defs{$va[0]})) {
$ret .= "Broken definition for dbplot $d: $link<br>";
} 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 = "&amp;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 .= "<embed src=\"$arg\" type=\"image/svg+xml\" " .
"width=\"$w\" height=\"$h\" name=\"$d\"/>\n";
} else {
$ret .= "<img src=\"$arg\"/>";
}
$ret .= weblink_FwDetail($d) if(!$FW_hiddenroom{detail} && $pageHash);
}
}
return $ret;
}
1;
=pod