From 7c1d2eab9edf8c5eaa9d62ce99b6671ba07e80c3 Mon Sep 17 00:00:00 2001 From: rudolfkoenig <> Date: Mon, 22 Apr 2013 18:27:46 +0000 Subject: [PATCH] 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 --- fhem/CHANGED | 1 + fhem/FHEM/01_FHEMWEB.pm | 438 +++++++++++++++------------------------- fhem/FHEM/92_FileLog.pm | 37 ++++ fhem/FHEM/98_weblink.pm | 115 ++++++++++- 4 files changed, 316 insertions(+), 275 deletions(-) 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 "
$FW_detail details
"; 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 "". - "
". - "
$min
". - "". - ""; - $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 "" 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); + my $ret = ""; + $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 ""; - } - 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 "", ($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("
"; 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); - if($FW_ss || $FW_tp) { - FW_pO "$txt"; - } else { - FW_pO "$txt"; - } - FW_pO "" if($td); + if($FW_ss || $FW_tp) { + $ret .= "$txt"; + } else { + $ret .= "$txt"; + } + $ret .= "
$f
%s
". + "
". + "
$min
". + "". + "
". + "". + "". + "
". + 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"). + "
", $pageHash ? "" : "block "); + foreach my $f (FW_fileList($defs{$d}{logfile})) { + my $class = (!$pageHash ? (($row++&1)?"odd":"even") : ""); + $ret .= ""; + $ret .= ""; + my $idx = 0; + foreach my $ln (split(",", AttrVal($d, "logtype", "text"))) { + if($FW_ss && $idx++) { + $ret .= ""; + } + $ret .= "
$f
"; + } + my ($lt, $name) = split(":", $ln); + $name = $lt if(!$name); + $ret .= FW_pH("cmd=logwrapper $d $lt $f", + "
$name
", 1, "dval", 1); + } + $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