From b41b81c9f48c0339f9869c807b9874ed5b18a6e6 Mon Sep 17 00:00:00 2001 From: Martin Kompf Date: Sat, 9 Apr 2016 18:06:19 +0200 Subject: [PATCH] Website added --- .gitignore | 6 ++ graph.sh | 2 +- www/graph.pl | 119 +++++++++++++++++++++++++++++++++++++++ www/index.html | 105 ++++++++++++++++++++++++++++++++++ www/table.pl | 150 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 381 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100755 www/graph.pl create mode 100644 www/index.html create mode 100755 www/table.pl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..849d386 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*~ +*.bak +*.rrd +nohup.out +*.gif +minicom.cap diff --git a/graph.sh b/graph.sh index a02cd08..d160403 100755 --- a/graph.sh +++ b/graph.sh @@ -2,7 +2,7 @@ rrdtool graph counter.gif \ -s 'now -1 day' -e 'now' \ -w 800 -h 600 \ - -X 0 -A \ + -A -Y \ DEF:counter=water.rrd:counter:LAST \ VDEF:lastcount=counter,LAST \ "GPRINT:lastcount:%6.3lf m³" \ diff --git a/www/graph.pl b/www/graph.pl new file mode 100755 index 0000000..fb3b4ae --- /dev/null +++ b/www/graph.pl @@ -0,0 +1,119 @@ +#!/usr/bin/perl +# +# CGI script to create image using RRD graph +use CGI qw(:all); +use RRDs; +use POSIX qw(locale_h); + +$ENV{'LANG'}='de_DE.UTF-8'; +setlocale(LC_ALL, 'de_DE.UTF-8'); + +# path to database +$rrd='../../water-counter/water.rrd'; + +# force to always create image from rrd +#$force=1; + +$query=new CGI; +#$query=new CGI("type=consumweek&size=small"); + +$size=$query->param('size'); +$type=$query->param('type'); +if ($size eq 'big') { + $width=900; + $height=700; + $size="b"; +} else { + $width=500; + $height=160; + $size="s"; +} +die "invalid type\n" unless $type =~ /(count|consum)(day|week|month|year)/; +$ds=$1; +$range=$2; +$filename="/tmp/em${type}_${size}.png"; + +# create new image if existing file is older than rrd file +my $maxdiff = 10; +if ((mtime($rrd) - mtime($filename) > $maxdiff) or $force) { + $tmpfile="/tmp/wai${type}_${size}_$$.png"; + # call sub to create image according to type + &$ds($range); + # check error + my $err=RRDs::error; + die "$err\n" if $err; + rename $tmpfile, $filename; +} + +# feed image to stdout +open(IMG, $filename) or die "can't open $filename"; +print header('image/png'); +print ; +close IMG; + +# end MAIN + +# Return modification date of file +sub mtime { + my $file=shift; + my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$fsize, + $atime,$mtime,$ctime,$blksize,$blocks) + = stat($file); + return $mtime; +} + +sub count { + my $range = shift; + my @opts=( + "-w", $width, + "-h", $height, + "-s", "now - 1 $range", + "-e", "now", + "-D", + "-Y", + "-A"); + RRDs::graph($tmpfile, + @opts, + "DEF:counter=$rrd:counter:LAST", + "LINE2:counter#000000:Zähler", + "VDEF:countlast=counter,LAST", + "GPRINT:countlast:%.3lf m³" + ); +} + +sub consum { + my $range = shift; + my @opts=( + "-w", $width, + "-h", $height, + "-D", + "-Y", + "-A", + "-e", "now", + "-s" + ); + if ($range eq 'month') { + push(@opts, "now - 30 days"); + } else { + push(@opts, "now - 1 $range"); + } + + if ($range eq 'day') { + RRDs::graph($tmpfile, + @opts, + "DEF:consum=$rrd:consum:AVERAGE", + "CDEF:conlpmin=consum,60000,*", + "CDEF:conlpd=conlpmin,60,*,24,*", + "VDEF:conlpdtotal=conlpd,AVERAGE", + "GPRINT:conlpdtotal:Total %4.0lf l/d", + "LINE2:conlpmin#00FF00:Verbrauch [l/min]" + ); + } else { + RRDs::graph($tmpfile, + @opts, + "DEF:consum=$rrd:consum:AVERAGE", + "CDEF:conlpd=consum,60000,*,60,*,24,*", + "LINE2:conlpd#00FF00:l/d" + ); + } +} diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..8feddc4 --- /dev/null +++ b/www/index.html @@ -0,0 +1,105 @@ + + + + + +Wasserverbrauch + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Wasserverbrauch

+
+ Zählerstand (24 h) +
+ Vergrößern + | Tabelle +
+ Verbrauch (24 h) +
+ Vergrößern + | Tabelle +
+ Verbrauch (Woche) +
+ Vergrößern + | Tabelle +
+ Verbrauch (Monat) +
+ Vergrößern + | Tabelle +
+ Verbrauch (Jahr) +
+ Vergrößern + | Tabelle +
+ + + diff --git a/www/table.pl b/www/table.pl new file mode 100755 index 0000000..f718938 --- /dev/null +++ b/www/table.pl @@ -0,0 +1,150 @@ +#!/usr/bin/perl +# +# CGI script to create a table of values from RRD +use CGI qw(:all *table *Tr); +use RRDs; +use POSIX qw(strftime); +use POSIX qw(locale_h); + +$ENV{'LANG'}='de_DE.UTF-8'; +setlocale(LC_TIME, 'de_DE.UTF-8'); + +# path to database +$rrdb='../../water-counter/water.rrd'; + +$query=new CGI; +#$query=new CGI("type=consumweek"); + +print header(-charset=>"utf-8"); + +$type=$query->param('type'); +if ($type !~ /(count|consum)(day|week|month|year)/) { + print "Invalid type\n"; + exit; +} +$sensor=$1; +$range=$2; + +#print "Sensor: $sensor Range: $range\n"; + +$timeformat="%a, %d. %b %Y"; +$resolution=24*60*60; +if ($range eq 'day') { + $resolution=60*60; + $timeformat="%a, %d. %b %Y %H:%M"; +} elsif ($range eq 'year') { + $resolution=7*24*60*60; + $timeformat="Wo %d. %b %Y"; +} + +if ($range eq 'day') { + @factors = (1.0, 60000.0); # consumption in l/min + @headings = ('m³', 'l/min'); + @formats = ('%7.3f', '%3.1f'); +} else { + @factors = (1.0, 60000.0*60*24); # consumption l/day + @headings = ('m³', 'l/d'); + @formats = ('%7.3f', '%4.0f'); +} + +($laststart,$laststep,$lastnames,$lastdata) = getdata($rrdb, 'LAST', $resolution, $range); +($avrstart,$avrstep,$avrnames,$avrdata) = getdata($rrdb, 'AVERAGE', $resolution, $range); +# print result + +# print heading +$style=< +END + +print start_html(-title=>"Wasserverbrauch", + -style=>{-code=>$style}, + -meta=>{"viewport"=>"initial-scale=1, minimum-scale=0.75, width=device-width"} +); +print start_table(); +print "\n"; +print thead(Tr(th({-class=>'time'}, ' '), th([@headings]))); +print "\n"; + +# print data +$avrstart -= 12*60*60 unless $timeformat =~ / %H:%M$/; +for $avrline (@$avrdata) { + $lastline = shift(@$lastdata); + print start_Tr({-class=>'avrdata'}); + print td({-class=>'time'}, strftime($timeformat, localtime($avrstart))); + print formatline(@$lastline[0], @$avrline[1]); + print end_Tr; + print "\n"; + + $avrstart += $avrstep; +} +print end_table(); +print end_html; + +sub getdata { + my ($db, $cf, $resolution, $range) = @_; + + my $sarg = "now -1 $range"; + if ($range eq 'month') { + $sarg = "now - 30 days"; + } + my ($start,$step,$names,$data) = RRDs::fetch($db, $cf, '-r', $resolution, '-s', $sarg, '-e', 'now'); + + # check error + my $err=RRDs::error; + print "$err\n" if $err; + exit if $err; + return ($start,$step,$names,$data); +} + +sub formatline { + my $str = ''; + my $i = 0; + for $val (@_) { + if (defined $val) { + $str .= td(sprintf $formats[$i], $val * $factors[$i]); + } else { + $str .= td; + } + $i++; + } + return $str; +}