From 4e83bd22f075aed9f9a4c5923b099f56a84f532c Mon Sep 17 00:00:00 2001 From: rudolfkoenig Date: Mon, 29 Apr 2013 13:35:49 +0000 Subject: [PATCH] .gplot editor added to the weblink details screen git-svn-id: svn://svn.code.sf.net/p/fhem/code/trunk@3130 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/01_FHEMWEB.pm | 27 ++-- fhem/FHEM/92_FileLog.pm | 14 +- fhem/FHEM/98_SVG.pm | 123 ++++++++++------- fhem/FHEM/98_weblink.pm | 248 +++++++++++++++++++++++++++++++++- fhem/www/gplot/template.gplot | 23 ++++ 6 files changed, 369 insertions(+), 67 deletions(-) create mode 100644 fhem/www/gplot/template.gplot diff --git a/fhem/CHANGED b/fhem/CHANGED index f823c38fb..05f89d77c 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: weblink details screen can be used to edit .gplot files - feature: eventTypes module added, to help with FileLog details screen - feature: FB_CALLMONITOR: new reverse search provider dasschnelle.at for reverse search of austrian telephone numbers diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm index 07997e69c..d4d4949e9 100755 --- a/fhem/FHEM/01_FHEMWEB.pm +++ b/fhem/FHEM/01_FHEMWEB.pm @@ -72,6 +72,7 @@ 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 +use vars qw(%FW_webArgs); # all arguments specified in the GET my $FW_zlib_checked; my $FW_use_zlib = 1; @@ -81,7 +82,6 @@ my $FW_use_zlib = 1; # Note: for delivering SVG plots we fork my @FW_httpheader; # HTTP header, line by line my @FW_enc; # Accepted encodings (browser header) -my %FW_webArgs; # all arguments specified in the GET my $FW_cmdret; # Returned data by the fhem call my $FW_data; # Filecontent from browser when editing a file my $FW_detail; # currently selected device for detail view @@ -454,6 +454,7 @@ FW_answerCall($) #Returns undef if it already sent a HTTP header ($FW_RETTYPE, $FW_RET) = &{$h->{FUNC}}($arg); use strict "refs"; + last if(!$FW_RET); return defined($FW_RETTYPE) ? 0 : -1; } } @@ -623,6 +624,7 @@ FW_digestCgi($) $cmd.=" $arg{$c}" if(defined($arg{$c}) && ($arg{$c} ne "state" || $cmd !~ m/^set/)); $cmd.=" $val{$c}" if(defined($val{$c})); +#Log 1, "GOT:$arg -> CMD:$cmd"; return ($cmd, $c); } @@ -751,8 +753,6 @@ FW_doDetail($) { my ($d) = @_; - FW_pO "
"; - FW_pO FW_hidden("detail", $d); my $h = $defs{$d}; my $t = $h->{TYPE}; @@ -772,6 +772,16 @@ FW_doDetail($) } } FW_pO "
"; + + if($modules{$t}{FW_detailFn}) { + no strict "refs"; + FW_pO &{$modules{$t}{FW_detailFn}}($FW_wname, $d, $FW_room) . "
"; + use strict "refs"; + } + + FW_pO ""; + FW_pO FW_hidden("detail", $d); + FW_makeSelect($d, "set", getAllSets($d), "set"); FW_makeTable($d, $h); # Internal values FW_pO "Readings" if($h->{READINGS}); @@ -794,14 +804,9 @@ FW_doDetail($) push(@dob, $dn); } } + FW_pO ""; FW_makeTableFromArray("Probably associated with", @dob); - if($modules{$t}{FW_detailFn}) { - no strict "refs"; - FW_pO &{$modules{$t}{FW_detailFn}}($FW_wname, $d, $FW_room) . "
"; - use strict "refs"; - } - FW_pO "
"; FW_pH "cmd=style iconFor $d", "Select icon"; @@ -809,7 +814,6 @@ FW_doDetail($) FW_pH "$FW_ME/docs/commandref.html#${t}", "Device specific help"; FW_pO "

"; FW_pO ""; - FW_pO ""; } @@ -819,7 +823,7 @@ FW_makeTableFromArray($@) { my ($txt,@obj) = @_; if (@obj>0) { my $row=1; - FW_pO "
" if($FW_RET !~ m/
$/); + FW_pO "

"; FW_pO "$txt"; FW_pO ''; foreach (sort @obj) { @@ -1533,7 +1537,6 @@ FW_select($$$$$@) $jSelFn = ($jSelFn ? "onchange=\"$jSelFn\"" : ""); $id = ($id ? "id=\"$id\"" : ""); my $s = ""; + $ret .= ""; } - $ret .= "
"; + $ret .= "
"; $ret .= FW_hidden("detail", $d); $ret .= FW_hidden("dev.$d", "$d addRegexpPart"); $ret .= FW_submit("cmd.$d", "set", "set"); @@ -328,8 +329,17 @@ FileLog_fhemwebFn($$$$) "FW_selChange('$al[0]','$list','val.$d')"; $ret .= "
"; + + my $newIdx=1; + while($defs{"wl_${d}_$newIdx"}) { + $newIdx++; + } + my $name = "wl_${d}_$newIdx"; + $ret .= FW_pH("cmd=define $name weblink fileplot $d:template:CURRENT;". + "set $name copyGplotFile&detail=$name", + "
Create new SVG plot
", 0, "dval", 1); + return $ret; } diff --git a/fhem/FHEM/98_SVG.pm b/fhem/FHEM/98_SVG.pm index 083ee427f..b3ceca456 100755 --- a/fhem/FHEM/98_SVG.pm +++ b/fhem/FHEM/98_SVG.pm @@ -28,6 +28,52 @@ SVG_Initialize($) } +###################### +# Convert the configuration to a "readable" form -> array to hash +sub +SVG_digestConf($$) +{ + my ($confp,$plot) = @_; + + my %conf; + map { chomp; my @a=split(" ",$_, 3); + if($a[0] && $a[0] eq "set") { $conf{lc($a[1])} = $a[2]; } + } @{$confp}; + + $conf{title} = "" if(!defined($conf{title})); + $conf{title} =~ s/'//g; + + ###################### + # Digest grid + my $t = ($conf{grid} ? $conf{grid} : ""); + #$conf{hasxgrid} = ( $t =~ /.*xtics.*/ ? 1 : 0); # Unused + $conf{hasygrid} = ( $t =~ /.*ytics.*/ ? 1 : 0); + $conf{hasy2grid}= ( $t =~ /.*y2tics.*/ ? 1 : 0); + + # Digest axes/title/etc from $plot (gnuplot) and draw the line-titles + my (@lAxis,@lTitle,@lType,@lStyle,@lWidth); + my ($i, $pTemp); + $pTemp = $plot; $i = 0; $pTemp =~ s/ axes (\w+)/$lAxis[$i++]=$1/gse; + $pTemp = $plot; $i = 0; $pTemp =~ s/ title '([^']*)'/$lTitle[$i++]=$1/gse; + $pTemp = $plot; $i = 0; $pTemp =~ s/ with (\w+)/$lType[$i++]=$1/gse; + $pTemp = $plot; $i = 0; $pTemp =~ s/ ls (\w+)/$lStyle[$i++]=$1/gse; + $pTemp = $plot; $i = 0; $pTemp =~ s/ lw (\w+)/$lWidth[$i++]=$1/gse; + + for my $i (0..int(@lType)-1) { # lAxis is optional + $lAxis[$i] = "x1y2" if(!$lAxis[$i]); + $lStyle[$i] = "class=\"". (defined($lStyle[$i]) ? $lStyle[$i] : "l$i")."\""; + $lWidth[$i] = (defined($lWidth[$i]) ? + "style=\"stroke-width:$lWidth[$i]\"" :""); + } + + $conf{lAxis} = \@lAxis; + $conf{lTitle} = \@lTitle; + $conf{lType} = \@lType; + $conf{lStyle} = \@lStyle; + $conf{lWidth} = \@lWidth; + return %conf; +} + ##################################### sub SVG_render($$$$$$$$) @@ -50,15 +96,10 @@ SVG_render($$$$$$$$) ###################### # Convert the configuration to a "readable" form -> array to hash - my %conf; # gnuplot file settings - map { chomp; my @a=split(" ",$_, 3); - if($a[0] && $a[0] eq "set") { $conf{lc($a[1])} = $a[2]; } } @{$confp}; + my %conf = SVG_digestConf($confp, $plot); my $ps = "800,400"; $ps = $1 if($conf{terminal} =~ m/.*size[ ]*([^ ]*)/); - $conf{title} = "" if(!defined($conf{title})); - $conf{title} =~ s/'//g; - my ($ow,$oh) = split(",", $ps); # Original width my ($w, $h) = ($ow-2*$x, $oh-2*$y); # Rect size @@ -113,16 +154,9 @@ SVG_render($$$$$$$$) "onclick=\"parent.svg_copy(evt)\" " . "class=\"copy\" text-anchor=\"end\"> "; - ###################### - # Digest grid - my $t = ($conf{grid} ? $conf{grid} : ""); - my $hasxgrid = ( $t =~ /.*xtics.*/ ? 1 : 0); - my $hasygrid = ( $t =~ /.*ytics.*/ ? 1 : 0); - my $hasy2grid = ( $t =~ /.*y2tics.*/ ? 1 : 0); - ###################### # Left label = ylabel and right label = y2label - $t = ($conf{ylabel} ? $conf{ylabel} : ""); + my $t = ($conf{ylabel} ? $conf{ylabel} : ""); $t =~ s/"//g; if(!$SVG_ss) { ($off1,$off2) = (3*$th/4, $oh/2); @@ -137,29 +171,14 @@ SVG_render($$$$$$$$) } ###################### - # Digest axes/title/etc from $plot (gnuplot) and draw the line-titles - my (@lAxis,@lTitle,@lType,@lStyle,@lWidth); - my ($i, $pTemp); - $pTemp = $plot; $i = 0; $pTemp =~ s/ axes (\w+)/$lAxis[$i++]=$1/gse; - $pTemp = $plot; $i = 0; $pTemp =~ s/ title '([^']*)'/$lTitle[$i++]=$1/gse; - $pTemp = $plot; $i = 0; $pTemp =~ s/ with (\w+)/$lType[$i++]=$1/gse; - $pTemp = $plot; $i = 0; $pTemp =~ s/ ls (\w+)/$lStyle[$i++]=$1/gse; - $pTemp = $plot; $i = 0; $pTemp =~ s/ lw (\w+)/$lWidth[$i++]=$1/gse; - - for my $i (0..int(@lType)-1) { # lAxis is optional - $lAxis[$i] = "x1y2" if(!$lAxis[$i]); - $lStyle[$i] = "class=\"". (defined($lStyle[$i]) ? $lStyle[$i] : "l$i") . "\""; - $lWidth[$i] = (defined($lWidth[$i]) ? "style=\"stroke-width:$lWidth[$i]\"" :""); - } - ($off1,$off2) = ($ow-$x-$th, $y+$th); ###################### # Plot caption (title) - for my $i (0..int(@lTitle)-1) { + for my $i (0..int(@{$conf{lTitle}})-1) { my $j = $i+1; - my $t = $lTitle[$i]; + my $t = $conf{lTitle}[$i]; my $desc = ""; if(defined($data{"min$j"}) && $data{"min$j"} ne "undef") { $desc = sprintf("%s: Min:%g Max:%g Last:%g", @@ -167,7 +186,8 @@ SVG_render($$$$$$$$) } SVG_pO "$t"; + "x=\"$off1\" y=\"$off2\" text-anchor=\"end\" ". + "$conf{lStyle}[$i]>$t"; $off2 += $th; } @@ -195,7 +215,7 @@ SVG_render($$$$$$$$) } $dpoff = $ndpoff+1; if($l =~ m/^#/) { - my $a = $lAxis[$idx]; + my $a = $conf{lAxis}[$idx]; if(defined($a)) { $hmin{$a} = $min if(!defined($hmin{$a}) || $hmin{$a} > $min); $hmax{$a} = $max if(!defined($hmax{$a}) || $hmax{$a} < $max); @@ -338,7 +358,7 @@ SVG_render($$$$$$$$) $step = $l/10; last; } - if($step == 0.001 && $hmax{$a} == $hmin{$a}) { # Don't want 0.001 range for nil + if($step==0.001 && $hmax{$a}==$hmin{$a}) { # Don't want 0.001 range for nil $step = 1; $ma = $mi + $step; } @@ -403,7 +423,7 @@ SVG_render($$$$$$$$) #-- tics handling my $tic = $htics{$a}; #-- tics as in the config-file - if($tic && $tic !~ m/mirror/) { + if($tic && $tic !~ m/mirror/) { $tic =~ s/^\((.*)\)$/$1/; # Strip () foreach my $onetic (split(",", $tic)) { $onetic =~ s/^ *(.*) *$/$1/; @@ -416,12 +436,12 @@ SVG_render($$$$$$$$) SVG_pO ""; #--grids my $off6 = $x+$w; - if( ($a eq "x1y1") && $hasygrid ) { + if( ($a eq "x1y1") && $conf{hasygrid} ) { + SVG_pO "" + if($tvalue > $hmin{$a} && $tvalue < $hmax{$a}); + }elsif( ($a eq "x1y2") && $conf{hasy2grid} ) { SVG_pO " " - if($i > $hmin{$a} && $i < $hmax{$a}); - }elsif( ($a eq "x1y2") && $hasy2grid ) { - SVG_pO " " - if($i > $hmin{$a} && $i < $hmax{$a}); + if($tvalue > $hmin{$a} && $tvalue < $hmax{$a}); } $off2 += $th/4; #-- text @@ -435,11 +455,11 @@ SVG_render($$$$$$$$) SVG_pO " "; #--grids my $off6 = $x+$w; - if( ($a eq "x1y1") && $hasygrid ) { + if( ($a eq "x1y1") && $conf{hasygrid} ) { my $off6 = $x+$w; SVG_pO " " if($i > $hmin{$a} && $i < $hmax{$a}); - }elsif( ($a eq "x1y2") && $hasy2grid ) { + }elsif( ($a eq "x1y2") && $conf{hasy2grid} ) { SVG_pO " " if($i > $hmin{$a} && $i < $hmax{$a}); } @@ -456,7 +476,7 @@ SVG_render($$$$$$$$) ###################### # Second loop over the data: draw the measured points for(my $idx=$#hdx; $idx >= 0; $idx--) { - my $a = $lAxis[$idx]; + my $a = $conf{lAxis}[$idx]; SVG_pO "" if(!defined($a)); next if(!defined($a)); @@ -470,19 +490,20 @@ SVG_render($$$$$$$$) my $yh = $y+$h; #-- Title attributes - my $tl = $lTitle[$idx] ? $lTitle[$idx] : ""; + my $tl = $conf{lTitle}[$idx] ? $conf{lTitle}[$idx] : ""; #my $dec = int(log($hmul*3)/log(10)); # perl can be compiled without log() ! my $dec = length(sprintf("%d",$hmul*3))-1; $dec = 0 if($dec < 0); my $attributes = "id=\"line_$idx\" decimals=\"$dec\" ". "x_off=\"$fromsec\" x_min=\"$x\" x_mul=\"$tmul\" ". "y_h=\"$yh\" y_min=\"$min\" y_mul=\"$hmul\" title=\"$tl\" ". - "onclick=\"parent.svg_click(evt)\" $lWidth[$idx] $lStyle[$idx]"; - my $isFill = ($lStyle[$idx] =~ m/fill/); + "onclick=\"parent.svg_click(evt)\" ". + "$conf{lWidth}[$idx] $conf{lStyle}[$idx]"; + my $isFill = ($conf{lStyle}[$idx] =~ m/fill/); my ($lx, $ly) = (-1,-1); - if($lType[$idx] eq "points" ) { + if($conf{lType}[$idx] eq "points" ) { foreach my $i (0..int(@{$dxp})-1) { my ($x1, $y1) = (int($x+$dxp->[$i]), int($y+$h-($dyp->[$i]-$min)*$hmul)); @@ -493,7 +514,7 @@ SVG_render($$$$$$$$) SVG_pO ""; } - } elsif($lType[$idx] eq "steps" || $lType[$idx] eq "fsteps" ) { + } elsif($conf{lType}[$idx] eq "steps" || $conf{lType}[$idx] eq "fsteps" ) { $ret .= sprintf(" %d,%d", $x+$dxp->[0], $y+$h) if($isFill && @{$dxp}); if(@{$dxp} == 1) { @@ -506,7 +527,7 @@ SVG_render($$$$$$$$) my ($x2, $y2) = ($x+$dxp->[$i], $y+$h-($dyp->[$i] -$min)*$hmul); next if(int($x2) == $lx && int($y1) == $ly); $lx = int($x2); $ly = int($y2); - if($lType[$idx] eq "steps") { + if($conf{lType}[$idx] eq "steps") { $ret .= sprintf(" %d,%d %d,%d %d,%d", $x1,$y1, $x2,$y1, $x2,$y2); } else { $ret .= sprintf(" %d,%d %d,%d %d,%d", $x1,$y1, $x1,$y2, $x2,$y2); @@ -517,7 +538,7 @@ SVG_render($$$$$$$$) SVG_pO ""; - } elsif($lType[$idx] eq "histeps" ) { + } elsif($conf{lType}[$idx] eq "histeps" ) { $ret .= sprintf(" %d,%d", $x+$dxp->[0], $y+$h) if($isFill && @{$dxp}); if(@{$dxp} == 1) { my $y1 = $y+$h-($dyp->[0]-$min)*$hmul; @@ -536,7 +557,7 @@ SVG_render($$$$$$$$) $ret .= sprintf(" %d,%d", $lx, $y+$h) if($isFill && $lx > -1); SVG_pO ""; - } elsif( $lType[$idx] eq "bars" ) { + } elsif( $conf{lType}[$idx] eq "bars" ) { if(@{$dxp} == 1) { my $y1 = $y+$h-($dyp->[0]-$min)*$hmul; $ret .= sprintf(" %d,%d %d,%d %d,%d %d,%d", diff --git a/fhem/FHEM/98_weblink.pm b/fhem/FHEM/98_weblink.pm index 07997e6ee..bbef51018 100755 --- a/fhem/FHEM/98_weblink.pm +++ b/fhem/FHEM/98_weblink.pm @@ -10,6 +10,10 @@ 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 use vars qw(%FW_pos); # scroll position +use vars qw($FW_gplotdir);# gplot directory for web server: the first +use vars qw(%FW_webArgs); # all arguments specified in the GET + +use IO::File; ##################################### sub @@ -20,9 +24,11 @@ weblink_Initialize($) $hash->{DefFn} = "weblink_Define"; $hash->{AttrList} = "fixedrange plotmode plotsize label ". "title htmlattr plotfunction"; + $hash->{SetFn} = "weblink_Set"; $hash->{FW_summaryFn} = "weblink_FwFn"; $hash->{FW_detailFn} = "weblink_FwFn"; $hash->{FW_atPageEnd} = 1; + $data{FWEXT}{"/weblinkDetails"}{FUNC} = "weblink_WriteGplot"; } @@ -44,6 +50,38 @@ weblink_Define($$) return undef; } +sub +weblink_Set($@) +{ + my ($hash, @a) = @_; + my $me = $hash->{NAME}; + return "no set argument specified" if(int(@a) < 2); + my %sets = (copyGplotFile=>0); + + my $cmd = $a[1]; + return "Unknown argument $cmd, choose one of ".join(" ",sort keys %sets) + if(!defined($sets{$cmd})); + return "$cmd needs $sets{$cmd} parameter(s)" if(@a-$sets{$cmd} != 2); + + if($cmd eq "copyGplotFile") { + return "type is not fileplot" if($hash->{WLTYPE} ne "fileplot"); + my @a = split(":", $hash->{LINK}); + my $srcName = "$FW_gplotdir/$a[1].gplot"; + $a[1] = $hash->{NAME}; + my $dstName = "$FW_gplotdir/$a[1].gplot"; + $hash->{LINK} = join(":", @a); + $hash->{DEF} = "$hash->{WLTYPE} $hash->{LINK}"; + open(SFH, $srcName) || return "Can't open $srcName: $!"; + open(DFH, ">$dstName") || return "Can't open $dstName: $!"; + while(my $l = ) { + print DFH $l; + } + close(SFH); close(DFH); + } + return undef; +} + + ##################################### # FLOORPLAN compat sub @@ -143,12 +181,209 @@ weblink_FwFn($$$$) $ret .= ""; } - $ret .= weblink_FwDetail($d) if(!$FW_hiddenroom{detail} && $pageHash); + if(!$pageHash) { + $ret .= wl_PEdit($FW_wname,$d,$room,$pageHash) + if($wltype eq "fileplot" && $FW_plotmode eq "SVG"); + $ret .= "
"; + + } else { + $ret .= weblink_FwDetail($d) if(!$FW_hiddenroom{detail}); + + } + } } return $ret; } +sub +wl_cb($$$) +{ + my ($v,$t,$c) = @_; + $c = ($c ? " checked" : ""); + return "$t "; +} + +sub +wl_txt($$$$) +{ + my ($v,$t,$c,$sz) = @_; + $c = "" if(!defined($c)); + $c =~ s/"//g; + return "$t "; +} + +sub +wl_sel($$$@) +{ + my ($v,$l,$c,$fnData) = @_; + my @al = split(",",$l); + return FW_select($v,$v,\@al,$c, "set", $fnData); +} + +sub +wl_getRegFromFile($) +{ + my ($fName) = @_; + my $fh = new IO::File $fName; + if(!$fh) { + Log 1, "$fName: $!"; + return (3, "NoFile", "NoFile"); + } + $fh->seek(0, 2); # Go to the end + my $sz = $fh->tell; + $fh->seek($sz > 65536 ? $sz-65536 : 0, 0); + my $data = <$fh>; + my $maxcols = 0; + my %h; + while($data = <$fh>) { + my @cols = split(" ", $data); + $maxcols = @cols if(@cols > $maxcols); + $cols[2] =~ s/:/./g; + my $key = "$cols[1].$cols[2]"; + $h{$key} = $data; + } + $fh->close(); + return ($maxcols+1, + join(",", sort keys %h), + join("
", map { $h{$_} } sort keys %h)), + close(FH); +} + +############################ +# gnuplot file "editor" +sub +wl_PEdit($$$$) +{ + my ($FW_wname,$d,$room,$pageHash) = @_; + my @a = split(":", $defs{$d}{LINK}); + my $gp = "$FW_gplotdir/$a[1].gplot"; + my $file = $defs{$a[0]}{currentlogfile}; + + my ($err, $cfg, $plot, $flog) = FW_readgplotfile($d, $gp, $file); + ($cfg, $plot) = FW_substcfg(1, $d, $cfg, $plot, $file, ""); + my %conf = SVG_digestConf($cfg, $plot); + + my $ret .= "
"; + $ret .= FW_hidden("detail", $d); + $ret .= FW_hidden("gplotName", $gp); + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= wl_cb("gridy", "left", $conf{hasygrid}); + $ret .= wl_cb("gridy2","right",$conf{hasy2grid}); + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; + + $ret .= ""; + $ret .= ""; + $ret .=" "; + + my ($colnums, $colregs, $coldata) = wl_getRegFromFile($file); + $colnums = join(",", 3..$colnums); + my $max = @{$conf{lAxis}}+1; + $max = 7 if($max > 7); + my $r = 0; + for($r=0; $r < $max; $r++) { + $ret .= ""; + } + $ret .= ""; + + $ret .= ""; + + $ret .= "
Label".wl_txt("ylabel", "left", $conf{ylabel}, 16)."".wl_txt("y2label","right", $conf{y2label}, 16)."
Tics as (\"Txt\" val, ...)".wl_txt("ytics", "left", $conf{ytics}, 16)."".wl_txt("y2tics","right", $conf{y2tics}, 16)."
Grid aligned
Range as [min:max]".wl_txt("yrange", "left", $conf{yrange}, 16)."".wl_txt("y2range", "right", $conf{y2range}, 16)."
LabelColumn,Regexp,DefaultValue,FunctionY-Axis,Plot-Type,Style
"; + $ret .= wl_txt("title_${r}", "", $conf{lTitle}[$r], 12); + $ret .= ""; + my @f = split(":", ($flog->[$r] ? $flog->[$r] : ":::"), 4); + $ret .= wl_sel("cl_${r}", $colnums, $f[0]); + $ret .= wl_sel("re_${r}", $colregs, $f[1]); + $ret .= wl_txt("df_${r}", "", $f[2], 2); + $ret .= wl_txt("fn_${r}", "", $f[3], 6); + + $ret .= ""; + my $v = $conf{lAxis}[$r]; + $ret .= wl_sel("axes_${r}", "left,right", + ($v && $v eq "x1y1") ? "left" : "right"); + $ret .= wl_sel("type_${r}", "lines,points,steps,fsteps,histeps,bars", + $conf{lType}[$r]); + my $ls = $conf{lStyle}[$r]; + if($ls) { + $ls =~ s/class=//g; + $ls =~ s/"//g; + } + $ret .= wl_sel("style_${r}", "l0,l1,l2,l3,l4,l5,l6,l7,l8,". + "l0fill,l1fill,l2fill,l3fill,l4fill,l5fill,l6fill", $ls); + $ret .= "
"; + $ret .= "Example lines for each regexp:
$coldata
"; + $ret .= FW_submit("submit", "Write .gplot file")."
"; +} + +sub +weblink_WriteGplot($) +{ + my ($arg) = @_; + FW_digestCgi($arg); + + my $fName = $FW_webArgs{gplotName}; + return if(!$fName); + if(!open(FH, ">$fName")) { + Log 1, "weblink_WriteGplot: Can't write $fName"; + return; + } + print FH "# Created by FHEMWEB, ".TimeNow()."\n"; + print FH "set terminal png transparent size crop\n"; + print FH "set output '.png'\n"; + print FH "set xdata time\n"; + print FH "set timefmt \"%Y-%m-%d_%H:%M:%S\"\n"; + print FH "set xlabel \" \"\n"; + print FH "set title ''\n"; + print FH "set ytics ".$FW_webArgs{ytics}."\n"; + print FH "set y2tics ".$FW_webArgs{y2tics}."\n"; + print FH "set grid".($FW_webArgs{gridy} ? " ytics" :""). + ($FW_webArgs{gridy2} ? " y2tics":"")."\n"; + print FH "set ylabel \"$FW_webArgs{ylabel}\"\n"; + print FH "set y2label \"$FW_webArgs{y2label}\"\n"; + print FH "set yrange $FW_webArgs{yrange}\n" if($FW_webArgs{yrange}); + print FH "set y2range $FW_webArgs{yrange}\n" if($FW_webArgs{y2range}); + print FH "\n"; + + my @plot; + for(my $i=0; $i <= 8; $i++) { + next if(!$FW_webArgs{"title_$i"}); + print FH "#FileLog ". $FW_webArgs{"cl_$i"} .":". + $FW_webArgs{"re_$i"} .":". + $FW_webArgs{"df_$i"} .":". + $FW_webArgs{"fn_$i"} ."\n"; + push @plot, "\"\" using 1:2 axes ". + ($FW_webArgs{"axes_$i"} eq "right" ? "x1y2" : "x1y1"). + " title '".$FW_webArgs{"title_$i"} ."'". + " ls " .$FW_webArgs{"style_$i"} . + " with " .$FW_webArgs{"type_$i"}; + } + print FH "\n"; + print FH "plot ".join(",\\\n ", @plot)."\n"; + close(FH); + + #foreach my $k (sort keys %FW_webArgs) { + # Log 1, "$k: $FW_webArgs{$k}"; + #} +} + 1; =pod @@ -192,7 +427,16 @@ weblink_FwFn($$$$) - Set
    N/A

+ Set +
    +
  • copyGplotFile
    + Only applicable to fileplot type weblinks.
    + Copy the currently specified gplot file to a new file, which is named + after the weblink (existing files will be overwritten), in order to be + able to modify it locally without the problem of being overwritten by + update. The weblink definition will be updated. +
  • +

Get
    N/A

diff --git a/fhem/www/gplot/template.gplot b/fhem/www/gplot/template.gplot new file mode 100644 index 000000000..f98816ab3 --- /dev/null +++ b/fhem/www/gplot/template.gplot @@ -0,0 +1,23 @@ +############################ +# Display the power reported by the EM1010 +# Corresponding FileLog definition: +# define ememlog FileLog /var/log/fhem/emem-%Y.log emem:power.* + +set terminal png transparent size crop +set output '.png' +set xdata time +set timefmt "%Y-%m-%d_%H:%M:%S" +set xlabel " " + +set title '' +set ylabel "Power (KW)" +set y2label "Power (KW)" +set grid +set ytics +set y2tics +set format y "%.1f" +set format y2 "%.1f" + +#FileLog 4::0: + +plot "" using 1:4 notitle with lines