1
0
mirror of https://github.com/skaringa/water-counter.git synced 2024-11-21 08:54:25 +01:00

Website added

This commit is contained in:
Martin Kompf 2016-04-09 18:06:19 +02:00
parent 8a3a787351
commit b41b81c9f4
5 changed files with 381 additions and 1 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
*~
*.bak
*.rrd
nohup.out
*.gif
minicom.cap

View File

@ -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³" \

119
www/graph.pl Executable file
View File

@ -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 <IMG>;
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"
);
}
}

105
www/index.html Normal file
View File

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="initial-scale=1, minimum-scale=0.75, width=device-width"/>
<title>Wasserverbrauch</title>
<script type="text/javascript">
// <![CDATA[
// open table popup window
function table(href) {
window.open(href, 'table', 'width=400,height=500,scrollbars=yes');
return false;
}
// open graph popup window
function graph(href) {
window.open(href, 'graph', 'width=950,height=750,scrollbars=no');
return false;
}
// initialize the page
function init() {
// reload after 5 min
window.setTimeout("window.location.reload(true)", 5 * 60 * 1000);
}
// ]]>
</script>
<style type="text/css">
body, table, form {
font: 10px/16px verdana, arial, helvetica, sans-serif;
background-color: white;
}
h2 {
font-size: 12px;
font-weight: bold;
}
.datatable {
width: 500px;
border: 0px;
}
img.graph {
width: 500px;
height: 160px;
}
td {
border-width: 0px 0px 1px 0px;
border-style: solid;
border-color: #998DB3;
}
</style>
</head>
<body onload="init()">
<table class="datatable">
<tr>
<td>
<h2>Wasserverbrauch</h2>
</td>
</tr>
<tr>
<td>
<img alt="Zählerstand (24 h)" id="i0l" class="graph" src="graph.pl?type=countday" title="Zählerstand (24 h)"/>
<br/>
<a href="graph.pl?type=countday&amp;size=big" onclick="return graph(this.href);">Vergrößern</a>
| <a href="table.pl?type=countday" onclick="return table(this.href);" target="table">Tabelle</a>
</td>
</tr>
<tr>
<td>
<img alt="Verbrauch (24 h)" id="i1l" class="graph" src="graph.pl?type=consumday" title="Verbrauch (24 h)"/>
<br/>
<a href="graph.pl?type=consumday&amp;size=big" onclick="return graph(this.href);" >Vergrößern</a>
| <a href="table.pl?type=consumday" onclick="return table(this.href);" target="table">Tabelle</a>
</td>
</tr>
<tr>
<td>
<img alt="Verbrauch (Woche)" id="i2l" class="graph" src="graph.pl?type=consumweek" title="Verbrauch (Woche)"/>
<br/>
<a href="graph.pl?type=consumweek&amp;size=big" onclick="return graph(this.href);" >Vergrößern</a>
| <a href="table.pl?type=consumweek" onclick="return table(this.href);" target="table">Tabelle</a>
</td>
</tr>
<tr>
<td>
<img alt="Verbrauch (Monat)" id="i3l" class="graph" src="graph.pl?type=consummonth" title="Verbrauch (Monat)"/>
<br/>
<a href="graph.pl?type=consummonth&amp;size=big" onclick="return graph(this.href);" >Vergrößern</a>
| <a href="table.pl?type=consummonth" onclick="return table(this.href);" target="table">Tabelle</a>
</td>
</tr>
<tr>
<td>
<img alt="Verbrauch (Jahr)" id="i4l" class="graph" src="graph.pl?type=consumyear" title="Verbrauch (Jahr)"/>
<br/>
<a href="graph.pl?type=consumyear&amp;size=big" onclick="return graph(this.href);" >Vergrößern</a>
| <a href="table.pl?type=consumyear" onclick="return table(this.href);" target="table">Tabelle</a>
</td>
</tr>
</table>
</body>
</html>

150
www/table.pl Executable file
View File

@ -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;
<!--
body {
font: 10px/16px verdana, arial, helvetica, sans-serif;
background-color: white;
color: black;
}
th, td {
border-width: 1px 1px 0px 0px;
border-style: solid;
border-color: #998DB3;
text-align: right;
width: 50px;
}
th {
background-color: lightgreen;
font-weight: normal;
}
thead {
position: fixed;
top: 0px;
background-color: white;
z-index: 1;
}
tbody {
position: absolute;
top: 30px;
z-index: -1;
}
.mindata {
color: blue;
}
.maxdata {
color: red;
}
.time {
color: black;
text-align: left;
width: 100px;
}
-->
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;
}