2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

SVG: hardcoding for FileLog in GPlot-File-Editor removed.

git-svn-id: https://svn.fhem.de/fhem/trunk@3759 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2013-08-21 08:13:08 +00:00
parent f32db519b9
commit 733aac14bb
3 changed files with 121 additions and 88 deletions

View File

@ -70,11 +70,13 @@ use vars qw(@FW_fhemwebjs);# List of fhemweb*js scripts to load
use vars qw($FW_detail); # currently selected device for detail view use vars qw($FW_detail); # currently selected device for detail view
use vars qw($FW_cmdret); # Returned data by the fhem call use vars qw($FW_cmdret); # Returned data by the fhem call
use vars qw($FW_room); # currently selected room use vars qw($FW_room); # currently selected room
use vars qw($FW_formmethod);
$FW_formmethod = "post";
my $FW_zlib_checked; my $FW_zlib_checked;
my $FW_use_zlib = 1; my $FW_use_zlib = 1;
my $FW_activateInform = 0; my $FW_activateInform = 0;
my $FW_formmethod = "post";
######################### #########################
# As we are _not_ multithreaded, it is safe to use global variables. # As we are _not_ multithreaded, it is safe to use global variables.

View File

@ -21,7 +21,7 @@ use vars qw($FW_wname); # Web instance
use vars qw(%FW_pos); # scroll position use vars qw(%FW_pos); # scroll position
use vars qw(%FW_webArgs); # all arguments specified in the GET use vars qw(%FW_webArgs); # all arguments specified in the GET
sub seekTo($$$$); sub FileLog_seekTo($$$$);
##################################### #####################################
sub sub
@ -41,6 +41,7 @@ FileLog_Initialize($)
$hash->{FW_summaryFn} = "FileLog_fhemwebFn"; $hash->{FW_summaryFn} = "FileLog_fhemwebFn";
$hash->{FW_detailFn} = "FileLog_fhemwebFn"; $hash->{FW_detailFn} = "FileLog_fhemwebFn";
$hash->{SVG_sampleDataFn} = "FileLog_sampleDataFn";
$data{FWEXT}{"/FileLog_toSVG"}{CONTENTFUNC} = "FileLog_toSVG"; $data{FWEXT}{"/FileLog_toSVG"}{CONTENTFUNC} = "FileLog_toSVG";
$data{FWEXT}{"/FileLog_logWrapper"}{CONTENTFUNC} = "FileLog_logWrapper"; $data{FWEXT}{"/FileLog_logWrapper"}{CONTENTFUNC} = "FileLog_logWrapper";
} }
@ -548,7 +549,7 @@ FileLog_Get($@)
Log3 $name, 4, "$name get: Input file $inf, from:$from to:$to"; Log3 $name, 4, "$name get: Input file $inf, from:$from to:$to";
my $ifh = new IO::File $inf if($inf); my $ifh = new IO::File $inf if($inf);
seekTo($inf, $ifh, $hash, $from) if($ifh); FileLog_seekTo($inf, $ifh, $hash, $from) if($ifh);
# Return the the plain file data, $outf is ignored # Return the the plain file data, $outf is ignored
if(!@a) { if(!@a) {
@ -808,7 +809,7 @@ seekBackOneLine($$)
################################### ###################################
sub sub
seekTo($$$$) FileLog_seekTo($$$$)
{ {
my ($fname, $fh, $hash, $ts) = @_; my ($fname, $fh, $hash, $ts) = @_;
@ -860,6 +861,70 @@ seekTo($$$$)
} }
sub
FileLog_addTics($$)
{
my ($in, $p) = @_;
return if(!$in || $in !~ m/^\((.*)\)$/);
map { $p->{"\"$2\""}=1 if(m/^ *([^ ]+) ([^ ]+) */); } split(",",$1);
}
sub
FileLog_sampleDataFn($$$$$)
{
my ($flName, $flog, $max, $conf, $wName) = @_;
my $desc = "Input:Column,Regexp,DefaultValue,Function";
my $fName = $defs{$flName}{currentlogfile};
my $fh = new IO::File $fName;
if(!$fh) {
$fName = "<undefined>" if(!defined($fName));
Log3 $wName, 1, "FileLog get sample data: $fName: $!";
return ($desc, undef, "");
}
$fh->seek(0, 2); # Go to the end
my $sz = $fh->tell;
$fh->seek($sz > 65536 ? $sz-65536 : 0, 0);
my $data;
$data = <$fh> if($sz > 65536); # discard the first/partial line
my $maxcols = 0;
my %h;
while($data = <$fh>) {
my @cols = split(" ", $data);
next if(@cols < 3);
$maxcols = @cols if(@cols > $maxcols);
$cols[2] = "*" if($cols[2] =~ m/^[-\.\d]+$/);
$h{"$cols[1].$cols[2]"} = $data;
$h{"$cols[1].*"} = "" if($cols[2] ne "*");
}
$fh->close();
my $colnums = $maxcols+1;
my $colregs = join(",", sort keys %h);
my $example = join("<br>", grep /.+/,map { $h{$_} } sort keys %h);
$colnums = join(",", 3..$colnums);
my %tickh;
FileLog_addTics($conf->{ytics}, \%tickh);
FileLog_addTics($conf->{y2tics}, \%tickh);
$colnums = join(",", sort keys %tickh).",$colnums" if(%tickh);
$max = 8 if($max > 8);
my @htmlArr;
for(my $r=0; $r < $max; $r++) {
my @f = split(":", ($flog->[$r] ? $flog->[$r] : ":::"), 4);
my $ret = "";
$ret .= SVG_sel("par_${r}_0", $colnums, $f[0]);
$ret .= SVG_sel("par_${r}_1", $colregs, $f[1]);
$ret .= SVG_txt("par_${r}_2", "", $f[2], 1);
$ret .= SVG_txt("par_${r}_3", "", $f[3], 6);
push @htmlArr, $ret;
}
return ($desc, \@htmlArr, $example);
}
1; 1;
=pod =pod

View File

@ -24,13 +24,14 @@ use vars qw($FW_wname); # Web instance
use vars qw(%FW_hiddenroom); # hash of hidden rooms, used by weblink use vars qw(%FW_hiddenroom); # hash of hidden rooms, used by weblink
use vars qw(%FW_pos); # scroll position use vars qw(%FW_pos); # scroll position
use vars qw(%FW_webArgs); # all arguments specified in the GET use vars qw(%FW_webArgs); # all arguments specified in the GET
use vars qw($FW_formmethod);
my $SVG_RET; # Returned data (SVG) my $SVG_RET; # Returned data (SVG)
sub SVG_calcWeblink($$); sub SVG_calcWeblink($$);
sub SVG_doround($$$); sub SVG_doround($$$);
sub SVG_fmtTime($$); sub SVG_fmtTime($$);
sub SVG_pO($); sub SVG_pO($);
sub SVG_readgplotfile($$$); sub SVG_readgplotfile($$);
sub SVG_render($$$$$$$$$); sub SVG_render($$$$$$$$$);
sub SVG_showLog($); sub SVG_showLog($);
sub SVG_substcfg($$$$$$); sub SVG_substcfg($$$$$$);
@ -198,60 +199,27 @@ SVG_sel($$$@)
return FW_select($v,$v,\@al,$c, "set", $fnData); return FW_select($v,$v,\@al,$c, "set", $fnData);
} }
sub
SVG_getRegFromFile($$)
{
my ($wName, $fName) = @_;
my $fh = new IO::File $fName;
if(!$fh) {
Log3 $wName, 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;
$data = <$fh> if($sz > 65536); # discard the first/partial line
my $maxcols = 0;
my %h;
while($data = <$fh>) {
my @cols = split(" ", $data);
next if(@cols < 3);
$maxcols = @cols if(@cols > $maxcols);
$cols[2] = "*" if($cols[2] =~ m/^[-\.\d]+$/);
$h{"$cols[1].$cols[2]"} = $data;
$h{"$cols[1].*"} = "" if($cols[2] ne "*");
}
$fh->close();
return ($maxcols+1,
join(",", sort keys %h),
join("<br>", grep /.+/,map { $h{$_} } sort keys %h)),
close(FH);
}
sub
SVG_addTics($$)
{
my ($in, $p) = @_;
return if(!$in || $in !~ m/^\((.*)\)$/);
map { $p->{"\"$2\""}=1 if(m/^ *([^ ]+) ([^ ]+) */); } split(",",$1);
}
############################ ############################
# gnuplot file "editor" # gnuplot file "editor"
sub sub
SVG_PEdit($$$$) SVG_PEdit($$$$)
{ {
my ($FW_wname,$d,$room,$pageHash) = @_; my ($FW_wname,$d,$room,$pageHash) = @_;
my $gp = "$FW_gplotdir/$defs{$d}{GPLOTFILE}.gplot";
my $file = $defs{$defs{$d}{LOGDEVICE}}{currentlogfile};
my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($d, $gp, $file); my $ld = $defs{$d}{LOGDEVICE};
my $ldt = $defs{$ld}{TYPE};
my $gp = "$FW_gplotdir/$defs{$d}{GPLOTFILE}.gplot";
my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($d, $gp);
my %conf = SVG_digestConf($cfg, $plot); my %conf = SVG_digestConf($cfg, $plot);
my $ret .= "<br><form autocomplete=\"off\" action=\"$FW_ME/SVG_WriteGplot\">"; my $ret = "<br>";
$ret .= "<form method=\"$FW_formmethod\" autocomplete=\"off\" ".
"action=\"$FW_ME/SVG_WriteGplot\">";
$ret .= FW_hidden("detail", $d); $ret .= FW_hidden("detail", $d);
$ret .= FW_hidden("gplotName", $gp); $ret .= FW_hidden("gplotName", $gp);
$ret .= FW_hidden("logdevicetype", $ldt);
$ret .= "<table class=\"block wide plotEditor\">"; $ret .= "<table class=\"block wide plotEditor\">";
$ret .= "<tr class=\"even\">"; $ret .= "<tr class=\"even\">";
$ret .= "<td>Plot title</td>"; $ret .= "<td>Plot title</td>";
@ -280,32 +248,32 @@ SVG_PEdit($$$$)
$ret .= "<td>".SVG_txt("y2tics","right", $conf{y2tics}, 16)."</td>"; $ret .= "<td>".SVG_txt("y2tics","right", $conf{y2tics}, 16)."</td>";
$ret .= "</tr>"; $ret .= "</tr>";
$ret .= "<tr class=\"odd\"><td>Diagramm label</td>";
$ret .= "<td>Input:Column,Regexp,DefaultValue,Function</td>";
$ret .=" <td>Y-Axis,Plot-Type,Style,Width</td></tr>";
my ($colnums, $colregs, $coldata) = SVG_getRegFromFile($FW_wname, $file);
$colnums = join(",", 3..$colnums);
my %tickh;
SVG_addTics($conf{ytics}, \%tickh);
SVG_addTics($conf{y2tics}, \%tickh);
$colnums = join(",", sort keys %tickh).",$colnums" if(%tickh);
my $max = @{$conf{lType}}+1; my $max = @{$conf{lType}}+1;
$max = 8 if($max > 8); $max = 8 if($max > 8);
my ($desc, $htmlArr, $example) = ("Spec", undef, "");
if($modules{$ldt}{SVG_sampleDataFn}) {
no strict "refs";
($desc, $htmlArr, $example) =
&{$modules{$ldt}{SVG_sampleDataFn}}($ld, $flog, $max,\%conf, $FW_wname);
use strict "refs";
} else {
my @htmlArr;
@htmlArr = map { SVG_txt("par_${_}_0","",$flog->[$_] ? $flog->[$_]:"",20) }
(0..$max-1);
$htmlArr = \@htmlArr;
}
$ret .= "<tr class=\"odd\"><td>Diagramm label</td>";
$ret .= "<td>$desc</td>";
$ret .=" <td>Y-Axis,Plot-Type,Style,Width</td></tr>";
my $r = 0; my $r = 0;
for($r=0; $r < $max; $r++) { for($r=0; $r < $max; $r++) {
$ret .= "<tr class=\"".(($r&1)?"odd":"even")."\"><td>"; $ret .= "<tr class=\"".(($r&1)?"odd":"even")."\"><td>";
$ret .= SVG_txt("title_${r}", "", !$conf{lTitle}[$r]&&$r<($max-1) ? $ret .= SVG_txt("title_${r}", "", !$conf{lTitle}[$r]&&$r<($max-1) ?
"notitle" : $conf{lTitle}[$r], 12); "notitle" : $conf{lTitle}[$r], 12);
$ret .= "</td><td>"; $ret .= "</td><td>";
my @f = split(":", ($flog->[$r] ? $flog->[$r] : ":::"), 4); $ret .= $htmlArr->[$r] if($htmlArr && @{$htmlArr} > $r);
$ret .= SVG_sel("cl_${r}", $colnums, $f[0]);
$ret .= SVG_sel("re_${r}", $colregs, $f[1]);
$ret .= SVG_txt("df_${r}", "", $f[2], 1);
$ret .= SVG_txt("fn_${r}", "", $f[3], 6);
$ret .= "</td><td>"; $ret .= "</td><td>";
my $v = $conf{lAxis}[$r]; my $v = $conf{lAxis}[$r];
$ret .= SVG_sel("axes_${r}", "left,right", $ret .= SVG_sel("axes_${r}", "left,right",
@ -328,7 +296,7 @@ SVG_PEdit($$$$)
$ret .= "</td></tr>"; $ret .= "</td></tr>";
} }
$ret .= "<tr class=\"".(($r++&1)?"odd":"even")."\"><td colspan=\"3\">"; $ret .= "<tr class=\"".(($r++&1)?"odd":"even")."\"><td colspan=\"3\">";
$ret .= "Example lines for input:<br>$coldata</td></tr>"; $ret .= "Example lines for input:<br>$example</td></tr>";
$ret .= "<tr class=\"".(($r++&1)?"odd":"even")."\"><td colspan=\"3\">"; $ret .= "<tr class=\"".(($r++&1)?"odd":"even")."\"><td colspan=\"3\">";
$ret .= FW_submit("submit", "Write .gplot file")."</td></tr>"; $ret .= FW_submit("submit", "Write .gplot file")."</td></tr>";
@ -405,7 +373,7 @@ SVG_WriteGplot($)
my ($arg) = @_; my ($arg) = @_;
FW_digestCgi($arg); FW_digestCgi($arg);
if(!defined($FW_webArgs{cl_0})) { if(!defined($FW_webArgs{par_0_0})) {
FW_pO "missing data in logfile: won't write incomplete .gplot definition"; FW_pO "missing data in logfile: won't write incomplete .gplot definition";
return 0; return 0;
} }
@ -422,7 +390,7 @@ SVG_WriteGplot($)
FW_pO "SVG_WriteGplot: Can't write $fName"; FW_pO "SVG_WriteGplot: Can't write $fName";
return 0; return 0;
} }
print FH "# Created by FHEMWEB, ".TimeNow()."\n"; print FH "# Created by FHEM/98_SVG.pm, ".TimeNow()."\n";
print FH "set terminal png transparent size <SIZE> crop\n"; print FH "set terminal png transparent size <SIZE> crop\n";
print FH "set output '<OUT>.png'\n"; print FH "set output '<OUT>.png'\n";
print FH "set xdata time\n"; print FH "set xdata time\n";
@ -439,15 +407,15 @@ SVG_WriteGplot($)
print FH "set y2range $FW_webArgs{y2range}\n" if($FW_webArgs{y2range}); print FH "set y2range $FW_webArgs{y2range}\n" if($FW_webArgs{y2range});
print FH "\n"; print FH "\n";
my $ld = $FW_webArgs{logdevicetype};
my @plot; my @plot;
for(my $i=0; $i <= 8; $i++) { for(my $i=0; $i <= 8; $i++) {
next if(!$FW_webArgs{"title_$i"}); next if(!$FW_webArgs{"title_$i"});
my $re = $FW_webArgs{"re_$i"}; my $prf = "par_${i}_";
$re = "" if(!defined($re)); my @v = map {$FW_webArgs{"$prf$_"}} grep {$FW_webArgs{"$prf$_"}} (0..9);
$re =~ s/:/\\x3a/g; my $r = @v > 1 ? join(":", map { s/:/\\x3a/g; $_ } @v) : $v[0];
print FH "#FileLog ". $FW_webArgs{"cl_$i"} .":$re:".
$FW_webArgs{"df_$i"} .":". print FH "#$ld $r\n";
$FW_webArgs{"fn_$i"} ."\n";
push @plot, "\"<IN>\" using 1:2 axes ". push @plot, "\"<IN>\" using 1:2 axes ".
($FW_webArgs{"axes_$i"} eq "right" ? "x1y2" : "x1y1"). ($FW_webArgs{"axes_$i"} eq "right" ? "x1y2" : "x1y1").
($FW_webArgs{"title_$i"} eq "notitle" ? " notitle" : ($FW_webArgs{"title_$i"} eq "notitle" ? " notitle" :
@ -464,9 +432,9 @@ SVG_WriteGplot($)
} }
sub sub
SVG_readgplotfile($$$) SVG_readgplotfile($$)
{ {
my ($wl, $gplot_pgm, $file) = @_; my ($wl, $gplot_pgm) = @_;
############################ ############################
# Read in the template gnuplot file. Digest the #FileLog lines. Replace # Read in the template gnuplot file. Digest the #FileLog lines. Replace
@ -518,7 +486,8 @@ SVG_substcfg($$$$$$)
my $oll = $attr{global}{verbose}; my $oll = $attr{global}{verbose};
$attr{global}{verbose} = 0; # Else the filenames will be Log'ged $attr{global}{verbose} = 0; # Else the filenames will be Log'ged
if($file eq "CURRENT") { my $ldt = $defs{$defs{$wl}{LOGDEVICE}}{TYPE};
if($file eq "CURRENT" && $ldt eq "FileLog") {
$file = $defs{$defs{$wl}{LOGDEVICE}}{currentlogfile}; $file = $defs{$defs{$wl}{LOGDEVICE}}{currentlogfile};
$file =~ s+.*/++; $file =~ s+.*/++;
} }
@ -722,7 +691,7 @@ SVG_showLog($)
$path = AttrVal($d,"archivedir","") . "/$file" if(!-f $path); $path = AttrVal($d,"archivedir","") . "/$file" if(!-f $path);
return ($FW_RETTYPE, "Cannot read $path") if(!-r $path); return ($FW_RETTYPE, "Cannot read $path") if(!-r $path);
my ($err, $cfg, $plot, undef) = SVG_readgplotfile($wl, $gplot_pgm, $file); my ($err, $cfg, $plot, undef) = SVG_readgplotfile($wl, $gplot_pgm);
return ($FW_RETTYPE, $err) if($err); return ($FW_RETTYPE, $err) if($err);
my $gplot_script = SVG_substcfg(0, $wl, $cfg, $plot, $file,$tmpfile); my $gplot_script = SVG_substcfg(0, $wl, $cfg, $plot, $file,$tmpfile);
@ -738,7 +707,7 @@ SVG_showLog($)
close(FH); close(FH);
} elsif($pm eq "gnuplot-scroll") { } elsif($pm eq "gnuplot-scroll") {
my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($wl, $gplot_pgm, $file); my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($wl, $gplot_pgm);
return ($FW_RETTYPE, $err) if($err); return ($FW_RETTYPE, $err) if($err);
# Read the data from the filelog # Read the data from the filelog
@ -777,18 +746,13 @@ SVG_showLog($)
unlink("$tmpfile.png"); unlink("$tmpfile.png");
} elsif($pm eq "SVG") { } elsif($pm eq "SVG") {
my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($wl, $gplot_pgm, $file); my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($wl, $gplot_pgm);
return ($FW_RETTYPE, $err) if($err); return ($FW_RETTYPE, $err) if($err);
my ($f,$t)=($SVG_devs{$d}{from}, $SVG_devs{$d}{to}); my ($f,$t)=($SVG_devs{$d}{from}, $SVG_devs{$d}{to});
$f = 0 if(!$f); # From the beginning of time... $f = 0 if(!$f); # From the beginning of time...
$t = 9 if(!$t); # till the end $t = 9 if(!$t); # till the end
my $ret;
if(!$modules{SVG}{LOADED}) {
$ret = CommandReload(undef, "98_SVG");
Log3 $FW_wname, 1, $ret if($ret);
}
Log3 $FW_wname, 5, Log3 $FW_wname, 5,
"plotcommand: get $d $file INT $f $t " . join(" ", @{$flog}); "plotcommand: get $d $file INT $f $t " . join(" ", @{$flog});
@ -805,7 +769,7 @@ SVG_showLog($)
} else { } else {
FW_fC("get $d $file INT $f $t " . join(" ", @{$flog}), 1); FW_fC("get $d $file INT $f $t " . join(" ", @{$flog}), 1);
($cfg, $plot) = SVG_substcfg(1, $wl, $cfg, $plot, $file, "<OuT>"); ($cfg, $plot) = SVG_substcfg(1, $wl, $cfg, $plot, $file, "<OuT>");
$ret = SVG_render($wl, $f, $t, $cfg, my $ret = SVG_render($wl, $f, $t, $cfg,
$internal_data, $plot, $FW_wname, $FW_cssdir, $flog); $internal_data, $plot, $FW_wname, $FW_cssdir, $flog);
FW_pO $ret; FW_pO $ret;
if($SVGcache) { if($SVGcache) {
@ -1176,6 +1140,8 @@ SVG_render($$$$$$$$$)
next if( $axdrawn{$a} ); next if( $axdrawn{$a} );
$axdrawn{$a}=1; $axdrawn{$a}=1;
next if(!defined($hmin{$a})); # Bogus case
#-- safeguarding against pathological data #-- safeguarding against pathological data
if( !$hstep{$a} ){ if( !$hstep{$a} ){
$hmax{$a} = $hmin{$a}+1; $hmax{$a} = $hmin{$a}+1;