Legende:
";
$dataTab=simpleTable->new({"cols"=>"2", "auto"=>"1"},
'border="0" cellspacing="1" cellpadding="5" ', "");
$dataTab->startTable(0, 0);
$dataTab->newCol(0,"class=\"sensTextTabMin\"");
print "\ \ ";
$dataTab->newCol(); print "Min";
$dataTab->newCol(0,"class=\"sensTextTabMax\"");
print "\ \ ";
$dataTab->newCol(); print "Max";
$dataTab->endTable();
print "
Sensor | ". "Min | " . "Max | ". "Avg | "; if( defined($refSensor->{"gettotal"}) ){ print "Tot | ||
---|---|---|---|---|---|---|
", # "$colName", " | "; # Minimum value for current sensor if( $hasMin ){ $min= $refMma->{"$col"}->{"minValue"}; $minDate=$refMma->{"$col"}->{"minDate"}; $minTime=$refMma->{"$col"}->{"minTime"}; $minUnit=$refSensor->{"mmaUnits"}->[$j]; ($minDate, $minTime)=timeConvert($minDate, $minTime, "LOC"); @d=split(/-/, $minDate ); $minDate="$d[2]-$d[1]-$d[0]"; }else{ $min=" - "; $minDate=""; $minTime=""; $minUnit=""; } # Maximum value for current sensor $max= $refMma->{"$col"}->{"maxValue"}; $maxDate=$refMma->{"$col"}->{"maxDate"}; $maxTime=$refMma->{"$col"}->{"maxTime"}; $maxUnit=$refSensor->{"mmaUnits"}->[$j]; if( defined($maxDate ) ){ ($maxDate, $maxTime)=timeConvert($maxDate, $maxTime, "LOC"); @d=split(/-/, $maxDate ); $maxDate="$d[2]-$d[1]-$d[0]"; }else{ $maxDate=""; $maxTime=""; } # Average value for current sensor $avg= $refMma->{"$col"}->{"avgValue"}; $avgUnit=$refSensor->{"mmaUnits"}->[$j]; # Total value mainly for rain sensor if( defined($refSensor->{"gettotal"})){ $tot= $refMma->{"$col"}->{"total"}; $totUnit=$refSensor->{"totalUnit"}; } # For wind sensor also print speed in BF units and in textual form $maxExtraTxt=""; $avgExtraTxt=""; if( $refSensor->{"sensType"}=~/^W[A-Z]/ && $col =~ /speed/io ){ ($tmp, $tmp1)=doWindSpeed($max, $refSensor->{"windSpeedType"}); $maxExtraTxt=" $tmp ($tmp1), "; ($tmp, $tmp1)=doWindSpeed($avg, $refSensor->{"windSpeedType"}); $avgExtraTxt=" $tmp ($tmp1), "; } # Now print the values into a table print "\n||||||
", $colName, " ", "($sensorName)", " | ";
}else{
print "", $sensorName, " | "; } print "", "$min", " ", $minUnit, " ", "", $minDate, " ", $minTime, "", " | \n";
# For rain sensor when there is no rain and so no max-date
if( length($maxDate) ){
print "", $maxExtraTxt, "$max", " ", $maxUnit, " ", "", $maxDate, " ", $maxTime, "", " | \n";
}else{
print "", $maxExtraTxt, "$max", " ", $maxUnit, "", " | \n"; } print "", $avgExtraTxt, "$avg", " ", $avgUnit, "", " | \n"; if( defined($refSensor->{"gettotal"}) ){ print "", "$tot", " ", $totUnit, "", " | \n"; } print "
", "$k ($sensorName)", " | ";
print "", "$min", " ", $minUnit, " ", "", $minDate, " ", $minTime, "", " | \n";
print "", "$max", " ", $maxUnit, " ", "", $maxDate, " ", $maxTime, "", " | \n";
print "", "$avg", " ", $avgUnit, "", " | \n"; print "
Durch Anwahl eines der Links in der ganz links stehenden Spalte wird der Zeitraum für die Darstellung ausgewählt. Durch Klick auf z.B. "1T" wird ein Tag an Daten dargestellt. Durch Klick auf z.B. 3M wird der Zeitbereich von 3 Monaten dargestellt jeweils ausgehend vom aktuellen Enddatum.
Mit den Kürzeln der beiden weiteren Spalten der Form -1T, +1T, -1W, +1W, -1M, +1M usw. kann der dargestellte Zeitbereich (Anfang und Ende) um die angegebene Zeit verschoben werden. Wird z.B. +1W angeklickt, wird die nächste Woche des dargestellten Bereichs angezeigt, sprich das bisherige Anfangs und Enddatum wird um 1 Woche verschoben. Durch Klick auf einen negativen Wert wie z.B. -6M wird das Zeitfenster rückwärts um die angegebene Spanne (hier: 6 Monate) verschoben.
Die Anwahl der +/- Links verändeert also immer nur das Start-End-Datum, nicht jedoch den
angezeigten Zeitraum, der über die links stehenden T,W,M -Links bestimmt werden kann.
EOF
;
$helpSensorGraphics=< Grundsätzlich können zwei verschiedene Arten von Sensoren dargestellt werden. Zum einen
sind dies Daten der realen Sensoren, also z.B. Temperatur, Windgeschwindigkeit
oder Luftdruck. Darüber hinaus ist auch die Darstellung "virtueller" Sensoren möglich.
Als virtueller Sensor werden hier solche Daten bezeichnet, die aus den realen
Sensordaten berechnet werden, für die es aber keinen eignen realen Sensor
zur Messung des Werts gibt. Beispiele sind die Windchilltemperatur, der Taupunkt
und die absolute Luftfeuchte.
Für virtuelle Sensoren gelten einige Sonderregeln:
Unter den Sensorgraphiken wird immer eine Tabelle mit den maximalen und minimalen
sowie den Durchschnittswerten des dargestellten Sensors ausgegeben. Werden in einer
Graphik auch virtuelle Sensoren dargestellt, so werden auch für diese virtuellen
Sensoren in der Tabelle die Minima, Maxima und der
Durchschnitt der Datenwerte ausgegeben. Zur Kennzeichnung, das es sich hierbei um virtuelle
Sensoren handelt, erfolgt die Ausgabe jedoch in grauer Schrift. Das gleiche gilt
für die tabellarische Darstellung der Daten selbst. Auch hier werden die Daten
virtueller Sensoren zur Kennzeichnung in grauer Schrift dargestellt.
Eine weitere Sonderregel besteht darin, das Daten virtueller Sensoren nur auf
Basis der Originaldaten oder auf Basis von Tages-, Wochen-, Montas- oder
Jahresdurchschnitten angezeigt werden können. Was nicht geht, ist die Darstellung
der Minima, Maxima für Tage, Wochen,Monate oder Jahre. Wird also zunächst der
Punkt "Nutze für die Darstellung: Mittelwerte auf Tagesbasis" und dann einer der
Punkte "Nutze für die Darstellung: Minima/Maxima" angewählt, so werden nur die
entsprechenden Daten realer Sensoren angezeigt. Virtuelle Sensoren werden hier
ausgeblendet und sind weder in der Graphik noch in der tabellarischen Datenansicht
oder der Anzeige
der Minimum/Maximum/Average-Tabelle sichtbar. Falls in diesem Fall in einer Graphik
ausschließlich virtuelle Sensoren dargestellt wurden, erfolgt keinerlei
Graphikanzeige. Stattdessen wird eine Warnung ausgegeben, das keine Daten für
die Darstellung zur Verfügung stehen.
EOF
;
$helpMMA=< Ebenfalls grau werden solche Daten dargestellt, die nicht zum dargestellten Sensor gehören.
Werden also beipsielsweise Temperatur und Feuchte Daten eines Sensors dargestellt, und zudem
die Windchill-Temperatur für diesen Sensor, so wird auch die Windgeschwindigkeit mit bei den Daten
des Temperatur/Feuchte Sensors ausgegeben da sie zur Berechnung des Windchills verwendet wurde,
obwohl sie ja nicht zum dargestellten Temp/Feuchte-Sensor gehört. Um dies deutlich zu machen wird
der Text grau gedruckt. Für diese Werte erfolgt keine Darstellung der Minima/Maxima
EOF
;
$helpSampleTime=<
Um die Darstellung schneller ausführen zu können, kann der Administrator des Skripts
in der Konfiguration die Variable \$doAutoBaseData (aktueller Wert: $doAutoBaseData Tage)
auf einen Wert setzen,
der verschieden von 0 sein muß und die Zahl der Tage angibt, ab
der in einer Darstellung anstelle der Originaldaten automatisch Mittelwerte auf Stundenbasis zur Anzeige
verwendet werden. Auch in einem solchen Fall hat der Benutzer immer die Möglichkeit
sich die Originaldaten anzeigen zu lassen.
Darüber hinaus kann der Benutzer auch andere Angaben für die Datenbais auswählen.
Dies erfolgt mit den Zeitbasis-Links "Mittelwerte auf Stundenbasis",
"Mittelwerte auf Tagesbasis",
"Monatsbasis" bzw. "Jahresbasis" möglich. Neben der Darstellung von Mittelwerten kann
anschließend über die dann zusätzlich sichtbaren Links "Mittelwerte/Minima/Maxima"
auch zwischen der Darstellung von Mittelwerten (Default), Minima oder Maxima
umgeschaltet werden. Was bewirkt nun die Einstellung über die
Zeitbasis-Links?
Wurde Beispielsweise "Mittelwerte auf Tagesbasis" gewählt, werden für den anzuzeigenden
Zeitraum in den Graphiken nicht mehr die Basisdaten zur Darstellung verwendet, sondern
die Mittelwerte der dargestellten Sensoren über jeweils einen Tag. Angenommen zur Zeit
werden die Original-Daten einer Woche dargestellt. Für eine Woche könnte es sich hierbei
je nach Einstellung des Meßintervalls in der Wetterstation beispielsweise um 1000
Datensätze handeln. Durch die Darstellung der Mittelwerte auf Tagesbasis wird nun
für jeden Tag der Woche genau ein Mittelwert aller Daten dieses Tages für den
dargestellten Sensors gebildet. Das Ergebnis, das zur Darstellung der
Wochen-Graphik verwendet wird, besteht in
diesem Fall also aus nur 7 Mittelwertsdaten (eine Woche gleich 7 Tage), anstelle der 1000
Einzeldaten. Dadurch wird zum einen die Zahl der Daten für die Darstellung reduziert, zum
anderen ergibt sich aber durch die Bildung von Mittelwerten der Sensordaten insbesondere
eine geglättete Darstellung. Ähnliches gilt für die Darstellung der Minima und Maxima auf
Tages-, Wochen-, Monats, und Jahresbasis. Hier werden keine Mittelwerte z.B. je eines
Tages, sondern das Minimum bzw. das Maximum je eines Tages zur Darstellung herangezogen.
Für den Regensensor ist es zudem möglich anstelle von Summen
(z.B. eines Tages) auch Mittelwerte auszugeben (s.u.). Zur Kennzeichnung
der Darstellung von Mittelwerten/minima/Maxima (im Vergleich zur Darstellung von
Originaldaten) werden die Graphiken mit einer leicht unterschiedlichen Hintergrundfarbe
versehen.
Speziell für den Regensensor kann durch Selektion des Knopfs "Mittelwerte statt Summen"
von der
Darstellung der Summen eines Tags/Woche/Montats/Jahres auf die Mittelwerte/Minima/Maxima-Darstellung
gewechselt werden (zur Anzeige muß anschließend der "Anzeigen"-Knopf gedrückt werden). In der
Summendarstellung des Regensensors werden die Gesamtmengen an Regen für die jeweilige Periode dargestellt,
also z.B. die Gesamtregenmenge eines Tages, einer Woche, eines Montas oder eines Jahres.
Der Knopf "Mittelwerte statt Summen" ist nur dann sichtbar, wenn die
Darstellung einen Regensensor beinhaltet und zusätzlich die Darstellung
von Tages/Wochen/Montas/Jahres-Durchschnitten angewählt wurde. Werden die original
Daten dargestellt, wird der Knopf daher nicht angezeigt.
Bei der Darstellung von Montas- bzw. Jahresdurchschnitten wird das angegebene
Startdatum automatisch auf den Anfang des Montas bzw. den Anfang des Jahres gesetzt
um eine sinvolle Darstellung zu ermöglichen. Alle Montas- bzw. Jahresmittelwerte
werden jeweils auf den ersten Tag des jeweiligen Monats bzw. Jahres gelegt. Diese
Wahl ist zwar grundsätzlich willkürlich, aber für die Darstellung sinnvoll. Die Wirkung
besteht darin, das z.B. in der
Regensensor Graphik der Regenmittelwert eines Monats für den ersten Tag des Montas dargestellt wird
und nicht z.B. in der Mitte oder am Ende des Montas. Bei der Darstellung von Tages-Mittelwerten
wird die Uhrzeit des Mittelwerts für den jeweiligen Tag
auf 00:00:00 Uhr gesetzt.
Die Anwahl von z.B.
"Jahres-Durchschnitte" macht natürlich auch nur dann Sinn, wenn Originaldaten
von mehreren Jahren vorliegen, da ja in diesem Fall alle Daten eines Jahres zu genau
einem Mittelwert zusammengefaßt werden, der dann in der Graphik dargestellt wird
Eine Graphik über den Zeitraum von 2 Jahren besteht folglich nur aus zwei Werten
für die Darstellung!
Durch Anwahl von "Originaldaten" wird wieder auf die Verwendung der
Originaldaten umgeschaltet.
Die unter den Graphiken stehenden Maximum-/Minimum-/Average-Tabellen
enthalten für reale Sensoren IMMER Werte, die auf den Originaldaten basieren.
Daher kann es durchaus
vorkommen, das hier z.B. ein Maximalwert ausgewiesen wird, der in der
z.B. Wochen-basierten Mittelwertsgraphik
nicht zu entdecken ist, eben weil die Graphik in diesem Fall nur
Mittelwerte darstellt. Anders verhält es sich für die Angabe von Minima/Maxima
und Mittelwerten für virtuelle Sensoren (grauer Text) wie z.B. Windchilltemperatur oder
Taupunkt. Die Maxima, Minima udn Durchschnitte für diese Sensoren basieren immer auf den
dargestellten Daten, da sie sich aus diesen errechnen.
EOF
;
# Temp
$h[0]=$latest_trendThresholdT->[0];
$h[1]=$latest_trendThresholdT->[1];
$h[2]=$latest_trendThresholdT->[2];
# Hum
$h[3]=$latest_trendThresholdH->[0];
$h[4]=$latest_trendThresholdH->[1];
$h[5]=$latest_trendThresholdH->[2];
# Pressure
$h[6]=$latest_trendThresholdPres->[0];
$h[7]=$latest_trendThresholdPres->[1];
$h[8]=$latest_trendThresholdPres->[2];
# Symbols:
$h[100]=$latest_trendSymbUp->[0];
$h[101]=$latest_trendSymbUp->[1];
$h[102]=$latest_trendSymbUp->[2];
$h[103]=$latest_trendSymbDown->[0];
$h[104]=$latest_trendSymbDown->[1];
$h[105]=$latest_trendSymbDown->[2];
$helpLatest=< Die für den Luftdruck dargestellten Werte, die z.B. als "(1h:) -6 hPa" gekennzeichnet sind zeigen, wie sich
der Luftdruck in der letzten Zeit (hier: "1h"= in einer Stunde; Betrag:
-6 hPa) verändert hat. Die Zeit wird von der Uhrzeit des letzten verfügbaren Datensatzes
aus gerechnet, die in der Überschrift "Letzte Werte vom ..." dargestellt wird. Wird ein positiver
Wert angezeigt, bedeutet dies, das der Luftdruck in der letzten Stunde
um den angezeigten Differenzbetrag auf den als aktuell angezeigten Wert gestiegen ist.
Ist der Wert negativ, bedeutet dies, das der Luftdruck
in der letzten Stunde um den angezeigten Differenzbetrag auf den als aktuell angezeigten Wert gefallen ist.
Die oben als Beispiel angegebene Anzeige "(1h:) -6 hPa" bedeutet also, das der Luftdruck in der letzten Stunde um 6 hPa
gefallen ist. Andersherum gesagt: Vor einer Stunde war der Luftdruck um 6 hPa höher als der jetzt als
aktuell angezeigte Wert.
Wird hinter einem Meßwert ein Pfeil (↑/↓) dargestellt, so
bedeutet dies, das der Wert einen Trend nach oben bzw. unten zeigt. Verschieden starke Trends werden
durch unterschiedliche Symbole gekennzeichnet in Abhängigkeit davon, wie stark der Wert eines Sensors
sich zuletzt geändert hat. Ausschlaggebend für die Auswahl des Trend-Symbols ist der Unterschied
vom letzten Wert des Sensors zum aktuellen Wert. Diese Differenz wird
nach ihrer Größe (also dem Betrag der Differenz, ohne Vorzeichen) in Bereiche eingeteilt für die
verschiedenfarbige Symbole dargestellt werden. Die unten verwendete Schreibweise, z.B.
$h[0]°C ≤ dt < $h[1]°C: $h[100]/$h[103] für Temperatursensoren bedeutet,
das falls die Temperaturdifferenz (dt) größer oder
gleich dem linken Wert ist und zugleich kleiner als der Rechte, eines der ganz rechts stehenden
Pfeil-Symbole verwendet wird je nachdem ob der Wert des Sensors gestiegen oder gefallen ist.
Vereinfacht gesagt: Liegt der Temperaturunterschied zwischen $h[0]°C und $h[1]°C ($h[1] exklusiv) wird eines der Symbole $h[100] bzw. $h[103] verwendet.
Das Symbol
"≤" steht also für "kleiner gleich", das Symbol "<" für "kleiner" und "≥" für größer gleich.
Für Temperatursensoren erfolgt die Auswahl des Trendsymbols in Abhängigkeit von der
Temperaturdifferenz (dt) wie folgt:
$h[0]°C ≤ dt < $h[1]°C: $h[100]/$h[103],
$h[1]°C ≤ dt < $h[2]°C: $h[101]/$h[104],
dt ≥ $h[2]°C: $h[102]/$h[105].
Für Feuchtesensoren erfolgt die Auswahl des Trendsymbols in Abhängigkeit von der
Feuchtedifferenz (dh) wie folgt:
$h[3]% ≤ dh < $h[4]%: $h[100]/$h[103],
$h[4]% ≤ dh < $h[5]%: $h[101]/$h[104],
dh ≥ $h[5]%: $h[102]/$h[105].
Für den Luftdrucksensor erfolgt die Auswahl des Trendsymbols in Abhängigkeit von der
Druckdifferenz (dp) wie folgt:
$h[6]hPa ≤ dp < $h[7]hPa: $h[100]/$h[103],
$h[7]hPa ≤ dp < $h[8]hPa: $h[101]/$h[104],
dp ≥ $h[8]hPa: $h[102]/$h[105].
Für die Anzeige des Regensensors bedeuten die konkreten Angaben der Regenmenge,
wieviel Regen insgesamt in der angegebenen
Zeitspanne gefallen ist. Eine Angabe von z.B. "(12h:) 3 mm bedeutet, daß in den
letzten 12 Stunden insgesamt 3 mm Regen gefallen sind. Die dargestellte
Gesamtregenmenge für den heutigen Tag wird ab Mitternacht des aktuellen
Tags gemessen.
Je nach der Einstellung des Datenintervalls der Wetterstation, kann es
sein, das für die Ermittlung der Trendwerte, bzw für die Darstellung konkreter Werte von
z.B. vor 1h, 3h oder 12h kein Wert in der Datenbank gefunden wird, der z.B. genau 1, 3
oder 12 Stunden zurück liegt. In diesem Fall wird der Datensatz
verwendet, der dem gesuchten Zeitpunkt am nächsten liegt. Wird kein zeitlich genau
passender Wert gefunden und keiner, der zeitlich in der Nähe liegt, so wird kein
Trend-Wert ausgegeben.
EOF
;
$helpStatistics=< Unter der Angabe des Datums in der ganz
linken Spalte sowie in jeder Spalte eines Sensors befindet sich das ιΙι-Zeichen.
Durch einen Klick auf diese Verknüpfung
werden die Sensordaten des entsprechenden Zeitabschnitts in einem neuen Fenster graphisch dargestellt.
Abhängig davon ob die Verknüpfung in der ganz links stehenden Datumsspalte oder in einer der Spalten mit
Sensorenstatistiken gewählt wurde, öffnet sich ein Fenster mit Grpahiken aller bzw. nur des gewählten Sensors
für den jeweiligen Zeitabschnitt. Auf diese Weise kann die Grundlage für die statistischen Werte leicht
eingesehen werden.
Unter der Verknüpfung für die Sensorgrafik stehen weitere Verknüpfungen,
die dazu dienen, den in dieser Zeile dargestellten Zeitabschnitt genauer auflösen zu können.
Werden in der aktuellen Zeile beispielsweise statistische Daten des Zeitraums eines Montas
dargestellt, so stehen darunter Verknüfungen, um den gleichen Zeitraum entweder in Abschnitten
von Wochen oder Tagen darzustellen. Wird dann beispielsweise die Wochen-Verknüpfung gewählt
so findet in der neuen Darstellung wiederum eine Verknüpfung für eine noch feinere Auflösung
in Tagen (die nächst feinere Auflösung).
Die Verknüpfungen werden stets in zwei Varianten dargestellt. Die Form [m]», [w]»,
[d]» dient zur Anzeige des Zeitraums in Abschnitten von Monaten, Wochen oder Tagen
jeweils in einem neuen Fenster. In der Form [m], [w], [d] werden die Daten im aktuellen Fenster
dargestellt.
Die In der Tabelle verwendeten Abkürzungen sind:
Weitere Informationen sind als Tooltip abrufbar, indem man mit der Maus über den entsprechenden Wert
fährt:
'.
'In der Beschreibung der Beaufort' .
"-Skala können Sie die Umrechnung der Windstärken in verschiedene Einheiten sowie" .
" die Ausprägung der sichtbaren Merkmale nachlesen. ".
"Um für den Regensensor aussagekräftige Resultate zu erlangen, sollte man daher die Anzeige ".
"auf Stundenbasis (Summe auf Stundenbasis) umschalten. Dadurch kann man in der Graphik genau ablesen wieviel Niederschlag je Stunde gefallen ist.
Bei der Angabe des Minimalen-, Maximalen- und des Durchschnittwerts in der Tabelle unter der Graphik
wird für den Maximalen- (Max) und den Durchschnittswert (Avg) die Regenmenge immer bezogen
auf eine Stunde (nicht auf eine Meßperiode) angegeben. $news \n";
if ($condition1)
{
print " Warnung: Warnung: ',
"Der gewünschte Datumsbereich war nicht " .
"gültig/verfügbar und wurde korrigiert....
\n";
#
# Select which help was requested
#
$moreHelp="";
if( $subject=~/scaling/i ){
$help=$helpScaling;
$helpSubject="Skalierung";
}elsif( $subject=~/displayPeriod/i ){
$help=$helpDisplayPeriod;
$helpSubject="Auswahl des Darstellungszeitraums";
}elsif( $subject=~/quicknavi/i ){
$help=$helpQuickNavi;
$helpSubject="Quicknavigation mit Links";
}elsif( $subject=~/sensorGraphics/i ){
if( $subject =~/Wind/ ){
$moreHelp='Für den Windsensor sind verschiedene Darstellungen möglich. Zum einen kann '.
'die Windgeschwindigkeit über die Zeit dargestellt werden. Eine zweite Darstellungsform '.
'ermöglicht einen Überblick über die Winstärke in Korrelation zur Windrichtung. '.
'In der dritten Darstellungsform schließlich kann abgelesen werden, wie sich die Windrichtung '.
'in der Zeit verändert hat.
EOF
;
for($i=0; $i<=$#bfNames; $i++){
if( $i == $#bfNames ){
$helpStatistics .= "
Siehe auch die Beaufort-Skala." .
"bei Wikipedia.
";
$help=$helpSensorGraphics;
$helpSubject="Die Darstellung der Sensordaten des Windsensors";
}elsif( $subject=~/Rain/ ){
$moreHelp="Die Originaldaten des Regensensors stellen die gefallene Menge an Niederschlag " .
"je Meßperiode dar. Die Meßperiode (z.B. 10 Minuten) ist jedoch nicht fest vorgegeben, sondern kann vom Verwalter ".
"der Station gesetzt werden. Zudem wird für den Regensensor nur dann ein Meßwert erfaßt, " .
"wenn wirklich Regen gefallen ist. Zeiträume ohne Regen werden nicht in der Datenbank " .
"gespeichert, so daß man in der tabellarischen Sicht nur Einträge findet, in denen es ".
"geregnet hat, wobei zwischen zwei Zeilen der Tabelle u.U. ein großer (trockener) Zeitraum liegen kann. " .
"Die Länge der Meßperiode kann in der tabellarischen Ausgabe der Daten " .
"anhand der Datumseinträge aufeinanderfolgender Meßwerte (mit Regen) abgelesen werden. In den Graphiken ist dies jedoch nicht genau erkennbar. ".
"Die Darstellung der Originaldaten für den Regensensor ".
"kann also nur dazu dienen möglichst genau zu sehen wann Regen gefallen ist, nicht jedoch " .
"dazu zu erfahren, wieviel Regen in jeweils einer Stunde gefallen ist.
";
$help=$helpSensorGraphics;
$helpSubject="Die Darstellung der Sensordaten des Regensensors";
}elsif( $subject=~/LD/ ){
$moreHelp="Die Anzeige der Sonnenscheindauer erfolgt immer in Stunden ".
"Daher entspricht eine Anzeige von 0.5 h Sonne einer halben Stunde Sonnenschein" .
"Die Anzeige 0.1 h entspricht 6 Minuten Sonne." .
" " .
"
";
$help=$helpSensorGraphics;
$helpSubject="Die Darstellung der Sonnenscheindauer";
}else{
$help=$helpSensorGraphics;
$helpSubject="Die Darstellung der Sensordaten, eine grundlegende Beschreibung";
}
}elsif( $subject=~/mma/i ){
$help=$helpMMA;
$helpSubject="Darstellung von Maximum, Minimum, Average-Werten";
}elsif( $subject=~/tableView/i ){
$help=$helpTableView;
$helpSubject="Tabellarische Datenansicht";
}elsif( $subject=~/sampleTime/i ){
$help=$helpSampleTime;
$helpSubject="Auswahl der Basisdaten";
}elsif( $subject=~/latestValue/i ){
$help=$helpLatest;
$helpSubject="Anzeige der aktuellen Werte";
}elsif( $subject=~/statisticDisplay/i ){
$help=$helpStatistics;
$helpSubject="Anzeige von statistischen Daten:";
}
# Convert some special chars to HTML encoding
# Note: This cahrs are in latin1 as are the umlauts in the text above
# So even if you cannot read the umlauts above because you use UTF8
# these umlauts should be converted here to correct HTML umlauts:
#
$help=~s/ü/\ü/g;
$help=~s/ö/\ö/g;
$help=~s/ä/\ä/g;
$help=~s/Ü/\Ü/g;
$help=~s/Ö/\Ö/g;
$help=~s/Ä/\Ä/g;
$help=~s/ß/\ß/g;
$moreHelp=~s/ü/\ü/g;
$moreHelp=~s/ö/\ö/g;
$moreHelp=~s/ä/\ä/g;
$moreHelp=~s/Ü/\Ü/g;
$moreHelp=~s/Ö/\Ö/g;
$moreHelp=~s/Ä/\Ä/g;
$moreHelp=~s/ß/\ß/g;
print h3("Hilfe zu...
$helpSubject");
print '', $moreHelp, $help, '';
print end_html, "\n";
exit 0;
}
#
# Return latest date and time in form of Date:Calc:Today_and_Now
#
sub getLastTimeDateSet{
my($dbh)=shift;
my($sensorData)=shift;
my($sql, $result, $stationIdSql);
my($refSensor, $id, $table, @timeDateN, @timeDate, $tmp1, $tmp2);
# Run through all defined sensors (at least all types the first sensor of this type)
# To find the latest date.
$refSensor=$sensorData->getFirstSensor("all");
while( defined(%{$refSensor}) ){
if( ! ${$refSensor}{"doPlot"} || $refSensor->{"ignoreInGetLastTimeDateSet"} != 0 ){
# Get next
$refSensor=$sensorData->getNextSensor("all");
next;
}
$stationIdSql=$refSensor->{"stationIdSql"};
$id=$refSensor->{"sensIds"}->[0];
$table=$refSensor->{"tableName"};
$sql="SELECT datetime FROM $table WHERE $stationIdSql AND " .
"sensid=$id ORDER by datetime desc LIMIT 1";
#print "$sql
\n";
$result=$dbh->selectrow_hashref($sql);
($tmp1,$tmp2)=split(/\s/, $result->{"datetime"});
@timeDate=(split(/-/o, $tmp1), split(/:/o, $tmp2));
if( $#timeDateN >0 ){
if( Date_to_Time(@timeDateN) < Date_to_Time(@timeDate) ){
@timeDateN=@timeDate;
}
}else{
@timeDateN=@timeDate;
}
# Get next
$refSensor=$sensorData->getNextSensor("all");
}
return( @timeDateN );
}
#
# Return first (most early) date and time in form of Date:Calc:Today_and_Now
#
sub getFirstTimeDateSet{
my($dbh)=shift;
my($sensorData)=shift;
my($sql, $result, $stationIdSql);
my($refSensor, $id, $table, @timeDateN, @timeDate, $tmp1, $tmp2, $found);
# Run through all defined sensors (at least all types the first sensor of this type)
# To find the latest date.
$found=0;
$refSensor=$sensorData->getFirstSensor("all");
while( defined(%{$refSensor}) ){
next if( ! ${$refSensor}{"doPlot"} );
$stationIdSql=$refSensor->{"stationIdSql"};
$id=$refSensor->{"sensIds"}->[0];
$table=$refSensor->{"tableName"};
$sql="SELECT datetime FROM $table WHERE $stationIdSql AND " .
"sensid=$id ORDER by datetime asc LIMIT 1";
$result=$dbh->selectrow_hashref($sql);
if( !defined($result) ){
$refSensor=$sensorData->getNextSensor("all");
next;
}
$found=1 if( $result > 0 );
($tmp1,$tmp2)=split(/\s/, $result->{"datetime"});
@timeDate=(split(/-/o, $tmp1), split(/:/o, $tmp2));
if( $#timeDateN >0 ){
if( Date_to_Time(@timeDateN) > Date_to_Time(@timeDate) ){
@timeDateN=@timeDate;
}
}else{
@timeDateN=@timeDate;
}
# Get next
$refSensor=$sensorData->getNextSensor("all");
}
if( $found==0 ){
warn "getFirstTimeDateSet(): Was unable to find any SQL data of sensors for stationIds $stationIdSql .
\n";
}
return( @timeDateN );
}
#
# Calculate and write the complete latestdata section into the web-page
#
sub showLatestDataPanel{
my($plots, $sensorData, $pageTab, $refNow)=@_;
my(%latestSens, $tmp1, $tmp2, $tmpStr, $latestTab, @tmp, $tmp, $cfgId, $i, $j, $k);
my($year,$month,$day, $hour,$min,$sec, $Dd,$Dh,$Dm,$Ds, $help);
#
# Now define the data for the latest sensor values to be calculated and printed
#
if( $plots =~ /TH/ ){
if( defined($latest_th) ){
$tmp=$latest_th; # A ref to a list of sensorId.staionId pairs
$cfgId=$tmp;
}elsif( defined($latestSensId{"TH"}) ){
$tmp=[$latestSensId{"TH"}];
$cfgId=["10"];
}else{
$tmp=["1"];
$cfgId=["10"];
}
$latestSens{"temp"}->{"configIds"}=$cfgId;
$latestSens{"temp"}->{"sensorids"}=$latest_th;
$latestSens{"temp"}->{"sensornames"}=["Aussen","Innen"];
$latestSens{"temp"}->{"stationId"}=$main::defaultStationId;
# Names to be printed as latest values
# These value either have to be a particular datase column name or in
# case a converter was specified it may be any nonempty name, its not used then
# except for the purpose that the converter will be called and has to do its job
# Note: This is true for "dbcols" NOT for "getDbcols" below!
# dbcols and getdbcols should except for a beginning datetime always
# be given in the same sequence allthough dbcols may have more entries
# You may *not* say dbcols=T,H and getdbcols=H,T
$latestSens{"temp"}->{"dbcols"}=["T","H", "absHum", "dewpoint"];
# Functions that convert a database value into something else
$latestSens{"temp"}->{"converter"}=[0, 0, \&absHumidity, \&dewPoint];
# cols to get from the database. Are inserted into
# $latestSens{"sensorval"}->{sensid}->... Hash with the names of the colums as key.
# See printLatestData
$latestSens{"temp"}->{"getDbcols"}=["T","H"];
$latestSens{"temp"}->{"sensorunits"}=["°C", "%rel Feuchte", "g/m3", "°C"];
$latestSens{"temp"}->{"valuename"}=["","", "abs", "Taupunkt"];
$latestSens{"temp"}->{"table"}="th_sensors";
$latestSens{"temp"}->{"type"}="TH";
$latestSens{"temp"}->{"trendData"}=$latest_trendTemp;
# If you want to display several trendData values for this sensor and not only
# an arrow sign for the trend itself set the variable to 1 here:
$latestSens{"temp"}->{"trendDataDisplay"}=0;
# If defined enables printing a tendency sign (up,down arrow) for sensors of this type
# Besides this setting you also need to define that older values for this sensor
# should be fetched. This is done in the head of the script see: $latest_trend*
$latestSens{"temp"}->{"trendThreshold"}->{"T"}=$latest_trendThresholdT;
$latestSens{"temp"}->{"trendThreshold"}->{"H"}=$latest_trendThresholdH;
# Trendsymbol settings. See comments at the beginning of this script
$latestSens{"temp"}->{"trendSymbDown"}=$latest_trendSymbDown;
$latestSens{"temp"}->{"trendSymbUp"}=$latest_trendSymbUp;
$latestSens{"temp"}->{"trendSymbMode"}=$latest_trendSymbMode;
$latestSens{"temp"}->{"trendSymbTextCol"}=$latest_trendSymbTextCol;
$latestSens{"temp"}->{"trendSymbTextSize"}=$latest_trendSymbTextSize;
}
if( $plots =~ /RA/ ){
# In the new sensid scheme where each sensor type starts with a sensid
# of 1. Since then we have a configId that refers to a definition of a certain
# sensor defined by addSensor()
#
if( defined($latest_ra) ){
$tmp=$latest_ra; # A ref to a list of sensorId.staionId pairs
$cfgId=$tmp;
}elsif( defined($latestSensId{"RA"}) ){
$tmp=[$latestSensId{"RA"}];
$cfgId=["40"];
}else{
$tmp=["1"];
$cfgId=["40"];
}
$latestSens{"rain"}->{"configIds"}=$cfgId;
$latestSens{"rain"}->{"sensorids"}=$tmp;
$latestSens{"rain"}->{"stationId"}=$main::defaultStationId;
$latestSens{"rain"}->{"sensornames"}=["Regen"];
$latestSens{"rain"}->{"table"}="rain";
# Special case for rain sensor; SUM($dbcolName) is caculated for this one col
$latestSens{"rain"}->{"dbcolName"}="diff";
$latestSens{"rain"}->{"dbcols"}=["-"];
$latestSens{"rain"}->{"getDbcols"}=$latestSens{"rain"}->{"dbcols"};
$latestSens{"rain"}->{"sensorunits"}=["mm"];
$latestSens{"rain"}->{"unitfactor"}={"diff"=>"0.001"};
$latestSens{"rain"}->{"sensorcolor"}=["#0000ff"];
# This specifies the date from when a diff up to now will be calculated
# Today means: take the difference from the first value of today up to
# now to calculate difference
$latestSens{"rain"}->{"datediff"}="$today";
$latestSens{"rain"}->{"valuename"}=["(Ges. heute)"];
$latestSens{"rain"}->{"type"}="RA";
$latestSens{"rain"}->{"trendData"}=$latest_trendRain;
$latestSens{"rain"}->{"trendDataUnits"}->{"-"}="mm";
$latestSens{"rain"}->{"trendDataDisplay"}=1;
}
if( $plots =~ /WI/ ){
if( defined($latest_wi) ){
$tmp=$latest_wi; # A ref to a list of sensorId.staionId pairs
$cfgId=$tmp;
}elsif( defined($latestSensId{"WI"}) ){
$tmp=[$latestSensId{"WI"}];
$cfgId=["30"];
}else{
$tmp=["1"];
$cfgId=["30"];
}
$latestSens{"wind"}->{"configIds"}=$cfgId;
$latestSens{"wind"}->{"sensorids"}=$tmp;
$latestSens{"wind"}->{"stationId"}=$main::defaultStationId;
$latestSens{"wind"}->{"sensornames"}=["Wind"];
$latestSens{"wind"}->{"table"}="wind";
if( ! $main::latestWindGust ) {
# HARRY !!!!!!
# $latestSens{"wind"}->{"dbcols"}=["speed", "angle", "range", "windchill"];
# $latestSens{"wind"}->{"getDbcols"}= ["speed", "angle", "range"];
# $latestSens{"wind"}->{"sensorunits"}=["Km/h", "", "", "°C"];
# $latestSens{"wind"}->{"valuename"}=["", "aus", "Varianz +/-", "Windchill"];
# $latestSens{"wind"}->{"converter"}=[\&windSpeed, \&windDir2, \&windVar, \&windChill];
$latestSens{"wind"}->{"dbcols"}=["speed", "angle", "windchill"];
$latestSens{"wind"}->{"getDbcols"}= ["speed"];
$latestSens{"wind"}->{"sensorunits"}=["Km/h", "°C"];
$latestSens{"wind"}->{"valuename"}=["", "Windchill"];
$latestSens{"wind"}->{"converter"}=[\&windSpeed, \&windChill];
}else{
$latestSens{"wind"}->{"dbcols"}=["gustspeed", "speed", "angle", "windchill"];
$latestSens{"wind"}->{"getDbcols"}= ["gustspeed", "speed", "angle" ];
$latestSens{"wind"}->{"sensorunits"}=["Km/h", "Km/h", "", "°C"];
$latestSens{"wind"}->{"valuename"}=["", "", "aus", "Windchill"];
$latestSens{"wind"}->{"converter"}=[\&windSpeed, \&windSpeed, \&windDir2,\&windChill];
}
$latestSens{"wind"}->{"type"}="WI";
$latestSens{"wind"}->{"windSpeedType"}=$main::latestWindSpeedType;
if( $main::latestWindSpeedType == 1 ){
$latestSens{"wind"}->{"unitfactor"}->{"speed"}=$main::kmhToKnots;
$latestSens{"wind"}->{"sensorunits"}->[0]="Kn";
}
$latestSens{"wind"}->{"latestWindRose"}=$main::latestWindRose;
$latestSens{"wind"}->{"latestWindRoseUrl"}=$main::latestWindRoseUrl;
}
if( $plots =~ /PR/ ){
#$latestSens{"pressure"}->{"configIds"}=[20];
if( defined($latest_pr) ){
$tmp=$latest_pr; # A ref to a list of sensorId.staionId pairs
$cfgId=$tmp;
}elsif( defined($latestSensId{"PR"}) ){
$tmp=[$latestSensId{"PR"}];
$cfgId=["20"];
}else{
$tmp=["1"];
$cfgId=["20"];
}
$latestSens{"pressure"}->{"configIds"}=$cgfId;
$latestSens{"pressure"}->{"sensorids"}=$tmp;
$latestSens{"pressure"}->{"stationId"}=$main::defaultStationId;
$latestSens{"pressure"}->{"sensornames"}=["Luftdruck"];
$latestSens{"pressure"}->{"table"}="pressure";
$latestSens{"pressure"}->{"dbcols"}=["P"];
$latestSens{"pressure"}->{"getDbcols"}=$latestSens{"pressure"}->{"dbcols"};
$latestSens{"pressure"}->{"sensorunits"}=["hPa"];
$latestSens{"pressure"}->{"valuename"}=[""];
$latestSens{"pressure"}->{"type"}="PR";
$latestSens{"pressure"}->{"trendData"}=$latest_trendPressure;
$latestSens{"pressure"}->{"trendDataUnits"}->{"P"}="hPa";
$latestSens{"pressure"}->{"trendDataDisplay"}=1;
$latestSens{"pressure"}->{"trendThreshold"}->{"P"}=$latest_trendThresholdPres;
# Trendsymbol settings. See comments at the beginning of this script
$latestSens{"pressure"}->{"trendSymbDown"}=$latest_trendSymbDown;
$latestSens{"pressure"}->{"trendSymbUp"}=$latest_trendSymbUp;
$latestSens{"pressure"}->{"trendSymbMode"}=$latest_trendSymbMode;
$latestSens{"pressure"}->{"trendSymbTextCol"}=$latest_trendSymbTextCol;
$latestSens{"pressure"}->{"trendSymbTextSize"}=$latest_trendSymbTextSize;
}
if( $plots =~ /LI/ ){
if( defined($latest_li) ){
$tmp=$latest_li; # A ref to a list of sensorId.staionId pairs
$cfgId=$tmp;
}elsif( defined($latestSensId{"LI"}) ){
$tmp=[$latestSensId{"LI"}];
$cfgId=["50"];
}else{
$tmp=["1"];
$cfgId=["50"];
}
$latestSens{"light"}->{"stationId"}=$main::defaultStationId;
$latestSens{"light"}->{"configIds"}=$cfgId;
$latestSens{"light"}->{"sensorids"}=$tmp;
$latestSens{"light"}->{"sensornames"}=["Helligkeit"];
$latestSens{"light"}->{"table"}="light";
$latestSens{"light"}->{"dbcols"}=["lux"];
$latestSens{"light"}->{"getDbcols"}=["lux", "factor"];
$latestSens{"light"}->{"sensorunits"}=["Lux"];
$latestSens{"light"}->{"valuename"}=[""];
$latestSens{"light"}->{"factor"}=[9];
$latestSens{"light"}->{"type"}="LI";
}
if( $plots =~ /LD/ ){
if( defined($latest_ld) ){
$tmp=$latest_ld; # A ref to a list of sensorId.staionId pairs
$cfgId=$tmp;
}elsif( defined($latestSensId{"LD"}) ){
$tmp=[$latestSensId{"LD"}];
$cfgId=["60"];
}else{
$tmp=["1"];
$cfgId=["60"];
}
# In the new sensid scheme where each sensor type starts with a sensid
# of 1. Since then we have a configId that refers to a definition of a certain
# sensor defined by addSensor()
#
$latestSens{"sundur"}->{"configIds"}=$cfgId;
$latestSens{"sundur"}->{"stationId"}=$tmp;
$latestSens{"sundur"}->{"sensornames"}=["Sonnenscheindauer"];
$latestSens{"sundur"}->{"table"}="light";
# Special case for rain sensor; SUM($dbcolName) is caculated for this one col
$latestSens{"sundur"}->{"dbcolName"}="sundur";
$latestSens{"sundur"}->{"dbcols"}=["-"];
$latestSens{"sundur"}->{"getDbcols"}=$latestSens{"rain"}->{"dbcols"};
$latestSens{"sundur"}->{"sensorunits"}=["h"];
$latestSens{"sundur"}->{"unitfactor"}={"sundur"=>"0.0166667"};
$latestSens{"sundur"}->{"sensorcolor"}=["#ff7000"];
# This specifies the date from when a diff up to now will be calculated
# Today means: take the difference from the first value of today up to
# now to calculate difference
$latestSens{"sundur"}->{"datediff"}="$today";
$latestSens{"sundur"}->{"valuename"}=["(heute)"];
$latestSens{"sundur"}->{"type"}="LD";
$latestSens{"sundur"}->{"trendDataDisplay"}=0;
}
if( $plots =~ /LR/ ){ # Sunlight radiation delivered by davis vantage pro 2
if( defined($latest_lr) ){
$tmp=$latest_lr; # A ref to a list of sensorId.staionId pairs
$cfgId=$tmp;
}elsif( defined($latestSensId{"LR"}) ){
$tmp=[$latestSensId{"LR"}];
$cfgId=["70"];
}else{
$tmp=["1"];
$cfgId=["70"];
}
$latestSens{"radiation"}->{"stationId"}=$main::defaultStationId;
$latestSens{"radiation"}->{"configIds"}=$cfgId;
$latestSens{"radiation"}->{"sensorids"}=$tmp;
$latestSens{"radiation"}->{"sensornames"}=["Sonnenstrahlung"];
$latestSens{"radiation"}->{"table"}="light";
$latestSens{"radiation"}->{"dbcols"}=["radiation"];
$latestSens{"radiation"}->{"getDbcols"}=["radiation"];
$latestSens{"radiation"}->{"sensorunits"}=["W/m*m"];
$latestSens{"radiation"}->{"valuename"}=[""];
$latestSens{"radiation"}->{"type"}="LR";
}
if( $plots =~ /LU/ ){ # UVindex deliverred by eg DAVIS Vanmte Pro 2
if( defined($latest_lu) ){
$tmp=$latest_lu; # A ref to a list of sensorId.staionId pairs
$cfgId=$tmp;
}elsif( defined($latestSensId{"LU"}) ){
$tmp=[$latestSensId{"LU"}];
$cfgId=["80"];
}else{
$tmp=["1"];
$cfgId=["80"];
}
$latestSens{"uvindex"}->{"stationId"}=$main::defaultStationId;
$latestSens{"uvindex"}->{"configIds"}=$cfgId;
$latestSens{"uvindex"}->{"sensorids"}=$tmp;
$latestSens{"uvindex"}->{"sensornames"}=["UV-Strahlung"];
$latestSens{"uvindex"}->{"table"}="light";
$latestSens{"uvindex"}->{"dbcols"}=["uvindex"];
$latestSens{"uvindex"}->{"getDbcols"}=["uvindex"];
$latestSens{"uvindex"}->{"sensorunits"}=["Index"];
$latestSens{"uvindex"}->{"valuename"}=[""];
$latestSens{"uvindex"}->{"type"}="LU";
}
getLatestValues($dbh, $sensorData, \%latestSens, @{$refNow});
#
# print out an overview of current values
#
print "$position
";
print "geographische Länge: 14° 25', geographische Breite: 48° 03'
";
print "
Delta:$Dd,$Dh,$Dm,$Ds
\n";
$tmpStr="Letzte Werte vom $tmp[2]-$tmp[1]-$tmp[0] um " .
"$tmp2 Uhr";
$tmpStr.=" (GMT)" if( $timeIsGMT );
#$tmpStr.=" $help";
# Print latest data from text and date values:
print "--- Es regnet seit: $tag.$monat.$jahr, $locstunde:$minute Uhr ---
";
}
else
{
print "--Derzeit regnet es nicht. Letzter Regen: $lasttag.$lastmonat.$lastjahr, $lastrainstunde:$lastminute Uhr---
";
}
# Create Table for Latest data
$latestTab = simpleTable->new(
{ "border" => "1", "cols" => "5", "auto" => "0", "fillEmptyCells" => "1" },
'class="latestTable"',
'Sensor '
. 'Wert1 Wert2 '
. 'Wert3 '
. 'Wert4 '
);
$latestTab->startTable(1,0);
$k=0;
# print out latestData for all sensors defined in $latestSens in the sequence
# they are defined in $latestSens
foreach $i (split(/\s+|,/, $latestSens)){
foreach $j (keys(%latestSens)) {
if( $latestSens{$j}->{"type"}=~ /$i/i ){
$latestTab->newRow() if( $k );
$k=1;
printLatestData(\%latestSens,$j, $latestTab);
}
}
}
$latestTab->endTable();
print hr;
}
#
# Get mma start and end date/time from URL or from start/end date depending on
# Parameters in URL like "mma" etc.
#
sub calcMmaDates{
my($startDate, $endDate, $startTime, $endTime,
$defaultStartTime, $defaultEndTime,$refDoPlotMma)=@_;
my($tmp, $tmp1, $tmp2 );
my($mmaUrlParm, $mma);
my($mmaStartDate,$mmaEndDate,$mmaStartTime,$mmaEndTime, @d);
my($mmaStartDay, $mmaStartMon, $mmaStartYear, $mmaEndDay, $mmaEndMon,$mmaEndYear);
my($locMmaStartYear, $locMmaStartMon, $locMmaStartDay,
$locMmaEndYear, $locMmaEndMon, $locMmaEndDay,
$locMmaStartHour, $locMmaStartMin, $locMmaStartSec,
$locMmaEndHour, $locMmaEndMin, $locMmaEndSec );
#
# Decide if max,min and average should be printed
$mmaUrlParm="";
$mma=url_param("mma");
if( length($mma) ) { # Script was called by post with parameters
($refDoPlotMma->{"min"},$refDoPlotMma->{"max"},$refDoPlotMma->{"avg"})=
split(/\s*,\s*/, $mma);
# Time range for calculation of mma values
if( $refDoPlotMma->{"avg"}==2 ){
$mmaStartDate=url_param("mmasd");
$mmaStartDate=~s/_.*//o;
$mmaStartTime= $defaultStartTime;
$mmaEndDate=url_param("mmaed");
$mmaEndDate=~s/_.*//o;
$mmaEndTime=$defaultEndTime;
$mmaUrlParm="mma=$mma;mmasd=$mmaStartDate;mmaed=$mmaEndDate";
}else{
$mmaStartDate=$startDate;
$mmaStartTime=$startTime;
$mmaEndDate=$endDate;
$mmaEndTime=$endTime;
$mmaUrlParm="mma=$mma";
}
} else{
$mmaStartDate=$startDate;
$mmaStartTime=$startTime;
$mmaEndDate=$endDate;
$mmaEndTime=$endTime;
}
@d=split(/-/, $mmaStartDate);
$mmaStartDay=$d[2]; $mmaStartMon=$d[1]; $mmaStartYear=$d[0];
@d=split(/-/, $mmaEndDate);
$mmaEndDay=$d[2]; $mmaEndMon=$d[1]; $mmaEndYear=$d[0];
# Convert MMA times into local time
($tmp1, $tmp2)=timeConvert($mmaStartDate,$mmaStartTime, "LOC");
($locMmaStartYear, $locMmaStartMon, $locMmaStartDay)=split(/-/o, $tmp1);
($locMmaStartHour, $locMmaStartMin, $locMmaStartSec)=split(/:/o, $tmp2);
($tmp1, $tmp2)=timeConvert($mmaEndDate,$mmaEndTime, "LOC");
($locMmaEndYear, $locMmaEndMon, $locMmaEndDay)=split(/-/o, $tmp1);
($locMmaEndHour, $locMmaEndMin, $locMmaEndSec)=split(/:/o, $tmp2);
return($mmaStartDate, $mmaStartTime, $mmaEndDate, $mmaEndTime,
$locMmaStartYear, $locMmaStartMon, $locMmaStartDay,
$locMmaStartHour, $locMmaStartMin, $locMmaStartSec,
$locMmaEndYear, $locMmaEndMon, $locMmaEndDay,
$locMmaEndHour, $locMmaEndMin, $locMmaEndSec,
$mmaUrlParm
);
}
#
# Create and show the navigation panel that lets the user navigate
# through time and select display options
#
sub showNavigationPanel{
my($startDate, $endDate, $startTime, $endTime,
$defaultStartTime, $defaultEndTime,
$mmaStartDate, $mmaStartTime,
$mmaEndDate, $mmaEndTime,
$locMmaStartYear, $locMmaStartMon, $locMmaStartDay,
$locMmaStartHour, $locMmaStartMin, $locMmaStartSec,
$locMmaEndYear, $locMmaEndMon, $locMmaEndDay,
$locMmaEndHour, $locMmaEndMin, $locMmaEndSec,
$mmaUrlParm,
$sampleTime, $sampleTimeBase, $sampleTimeUser,$defSampleTime, $defSampleDataType, $sampleDataType,
$plots, $plotsSelected, $textPlots,
$rainSumMode, $scaleMode, $defScaleMode, $defScaleFactor,
$scaleFactor, $refDoPlotMma, $plotsTypeSerial, $refNow, $refFirst, $statisticsMode)=@_;
# local variables
my($tmp, $tmp1, $tmp2, $tmp3, $tmp4, %links, %pLinks, $url, %urls, %pUrls, $i, %sampleTypeLabels);
my($frameTab, $navTab, $tmpTab);
my($endYear, $endMon, $endDay, $endHour, $endMin, $endSec,
$startYear, $startMon, $startDay, $startHour, $startMin, $startSec,
$locStartDay, $locStartMon, $locStartYear, $locStartDate,$locStartTime,
$locEndDate, $locEndTime,
$locEndDay, $locEndMon, $locEndYear);
my($startLink, $actionUrl, $statisticsUrl, $nonStatisticsUrl,
$statistics_1YM_Url);
my(@d, $statistics);
my($mmaStartDay, $mmaStartMon, $mmaStartYear, $mmaEndDay, $mmaEndMon,$mmaEndYear,
$mmaLinkmma, $mmaLinkP2mma, $mmaLinkP3mma,
$mmaLink__a,$mmaLinkP2__a, $mmaLinkP3__a, $mmaLink___ );
my($sampleTimeAllLink, $sampleTimeHourLink, $sampleTimeDayLink,$sampleTimeWeekLink,
$sampleTimeMonthLink, $sampleTimeYearLink, $sampleDataTypeLinkAvg,
$sampleDataTypeLinkMin,$sampleDataTypeLinkMax);
my($periodEndDate,$periodEndTime,
$periodSyear,$periodSmon, $periodSday,
$periodShour, $periodSmin, $periodSsec, $periodDate, $periodUrl,
$periodMonSyear,$periodMonSmon, $periodMonSday,
$periodMonShour, $periodMonSmin, $periodMonSsec,
$periodMonDate,$periodMonUrl);
my($tmpSyear, $tmpSmon, $tmpSday, $tmpShour, $tmpSmin, $tmpSsec,
$tmpEyear, $tmpEmon, $tmpEday, $tmpEhour, $tmpEmin, $tmpEsec );
($startYear, $startMon, $startDay)=split(/-/o, $startDate);
($startHour, $startMin, $startSec)=split(/:/o, $startTime);
($endYear, $endMon, $endDay) =split(/-/o, $endDate);
($endHour, $endMin, $endSec) =split(/:/o, $endTime);
# Convert start and end date into local time
($locStartDate, $locStartTime)=timeConvert($startDate, $startTime, "LOC");
($locStartYear, $locStartMon, $locStartDay)=split(/-/o, $locStartDate);
# Fill variables with local time
($locEndDate, $locEndTime)=timeConvert($endDate, $endTime, "LOC");
($locEndYear, $locEndMon, $locEndDay)=split(/-/o, $locEndDate);
# If a particular plot was selected keep this info in URL
if( $plotsSelected ){
if( $textPlots ){
$tmp = "tp";
}else{
$tmp = "pl";
}
$url="${scriptUrl}?$tmp=$plots$plotsTypeSerial";
}else{
$url="$scriptUrl";
}
# Save the scripts url for the action attribute of the form
# $url can now be changed to be used as a base in building
# the date links etc.
$actionUrl=$url;
# If the user defined a scaling mode or factor add this to URL
# for alle the date- and image-links
if( $scaleMode ne $defScaleMode || $scaleFactor!=$defScaleFactor ){
$url=addUrlParm($url, "sm=$scaleMode", "sf=$scaleFactor");
}
# Create Links for sampleTime: all, day, week, month, year
# stuser is a flag meaning the user has selected this
# sample time it was NOT done automatically
$sampleTimeAllLink=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime",
"st=0,$defSampleDataType", "stuser=1", $mmaUrlParm);
$sampleTimeAllLink=addUrlParm($sampleTimeAllLink, "statMode=1") if( $statisticsMode );
# ------------------
$sampleTimeHourLink=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime",
"st=h,$sampleDataType","rst=$rainSumMode", "stuser=1", $mmaUrlParm);
$sampleTimeHourLink=addUrlParm($sampleTimeHourLink, "statMode=1") if( $statisticsMode );
# ------------------
$sampleTimeDayLink=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime",
"st=d,$sampleDataType","rst=$rainSumMode", "stuser=1", $mmaUrlParm);
$sampleTimeDayLink=addUrlParm($sampleTimeDayLink, "statMode=1") if( $statisticsMode );
# ------------------
$sampleTimeWeekLink=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime",
"st=w,$sampleDataType", "rst=$rainSumMode", "stuser=1", $mmaUrlParm);
$sampleTimeWeekLink=addUrlParm($sampleTimeWeekLink, "statMode=1") if( $statisticsMode );
# ------------------
$sampleTimeMonthLink=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime",
"st=m,$sampleDataType", "rst=$rainSumMode", "stuser=1", $mmaUrlParm);
$sampleTimeMonthLink=addUrlParm($sampleTimeMonthLink, "statMode=1") if( $statisticsMode );
# ------------------
$sampleTimeYearLink=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime",
"st=y,$sampleDataType", "rst=$rainSumMode", "stuser=1", $mmaUrlParm);
$sampleTimeYearLink=addUrlParm($sampleTimeYearLink, "statMode=1") if( $statisticsMode );
# Create Links for sampleTime: all, day, week, month, year
$sampleDataTypeLinkAvg=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime","st=$sampleTimeBase,Avg",
"stuser=$sampleTimeUser", $mmaUrlParm);
$sampleDataTypeLinkMin=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime",
"st=$sampleTimeBase,Min", "stuser=$sampleTimeUser", $mmaUrlParm);
$sampleDataTypeLinkMax=addUrlParm($url, "sd=${startDate}_$startTime;ed=${endDate}_$endTime",
"st=$sampleTimeBase,Max", "stuser=$sampleTimeUser", $mmaUrlParm);
# If the user defined a sampleTime mode add this to URL
# for alle the date- and image-links
if( $sampleTimeBase ne $defSampleTime ){
$url=addUrlParm($url, "st=$sampleTime" );
$url=addUrlParm($url, "rst=$rainSumMode" );
if( length($sampleTimeUser) ){
$url=addUrlParm($url, "stuser=$sampleTimeUser" );
}
}
# Initialize datastructure for date links like next week, last week...
# Tag is the number printed in the html form eg "1,2,4 days"
$links{"day"}={ "months" => 0, "days" => 1, "tag" => "1T" };
$links{"day2"}={"months" => 0, "days" => 2, "tag" => "2T" };
$links{"day3"}={"months" => 0, "days" => 3, "tag" => "3T" };
$links{"day4"}={"months" => 0, "days" => 5, "tag" => "5T" };
# Copy data into period hash f%plinks or selection of one day, week,month, ...
# The plinks hash is used for the period links only, while the
# links hash is used for the +/- period links. The calculation
# for period links is different depending on sttaisticsMode.
$plinks{"day"}=$links{"day"};
$plinks{"day2"}=$links{"day2"};
$plinks{"day3"}=$links{"day3"};
$plinks{"day4"}=$links{"day4"};
$links{"week"}={ "months" => 0, "days" => 7, "tag" => "1W" };
$links{"week2"}={"months" => 0, "days" => 14,"tag" => "2W" };
$links{"week3"}={"months" => 0, "days" => 21,"tag" => "3W" };
# Copy data into period hash for selection of one day, week,month, ...
# See above
$plinks{"week"}=$links{"week"};
$plinks{"week2"}=$links{"week2"};
$plinks{"week3"}=$links{"week3"};
$links{"month"}={ "months" => 1, "days" => 0, "tag" => "1M" };
$links{"month2"}={"months" => 3, "days" => 0, "tag" => "3M" };
$links{"month3"}={"months" => 6, "days" => 0, "tag" => "6M" };
# Copy data into period hash for selection of one day, week,month, ...
# See above
$plinks{"month"}=$links{"month"};
$plinks{"month2"}=$links{"month2"};
$plinks{"month3"}=$links{"month3"};
$links{"year"}={ "months" => 12, "days" => 0, "tag" => "1J" };
$links{"year2"}={"months" => 36, "days" => 0, "tag" => "3J" };
$links{"year3"}={"months" => 60, "days" => 0, "tag" => "5J" };
$links{"year4"}={"months" => 120,"days" => 0, "tag" => "10J" };
# Copy data into period hash for selection of one day, week,month, ...
# See above
$plinks{"year"}=$links{"year"};
$plinks{"year2"}=$links{"year2"};
$plinks{"year3"}=$links{"year3"};
$plinks{"year4"}=$links{"year4"};
# If statisticsmode was selected, create the
# "opposite" mode url
if( $statisticsMode > 0){
# The url has to be modified to stay in statMode by default
$nonStatisticsUrl=$actionUrl;
$url=addUrlParm($url, "statMode=1");
#$nonStatisticsUrl=addUrlParm($nonStatisticsUrl, "sd=${startDate}_$startTime;ed=${endDate}_$endTime","st=$sampleTime");
$nonStatisticsUrl=addUrlParm($nonStatisticsUrl, "sd=${startDate}_$startTime;ed=${endDate}_$endTime");
# Create an instance of statistics Class to get
# the %plinks values for statistics mode
$statistics=statistics->new($tmp, $startDate, $startTime,
$endDate, $endTime, $sampleTime, $tmp1, $tmp1,
$refNow, $refFirst );
$statistics->setPeriodData(\%links, \%plinks, $locEndDate);
#
}else{
$statisticsUrl=$url;
$statisticsUrl=~s/st=[^;]*;//o;
$statistics_1YM_Url=$statisticsUrl;
$statisticsUrl=addUrlParm($statisticsUrl, "statMode=1");
$statisticsUrl=addUrlParm($statisticsUrl, "sd=${startDate}_$startTime;ed=${endDate}_$endTime","st=$sampleTime");
# Statisticsmode for current year in month segments
$tmp=$startYear-1;
$statistics_1YM_Url=addUrlParm($statistics_1YM_Url, "sd=${tmp}-12-31_23:00:00;ed=${startYear}-12-31_22:59:59");
$statistics_1YM_Url=addUrlParm($statistics_1YM_Url, "statMode=1;st=m,Avg");
}
# Calculate data for timeperiod links (display a day, a month. a year )
# the values are calculated backwards from today
# For one day we have to subtract one day and add one second since the endDate
# alwyas ends at day x 23:59:59 and not 00:00:00, but the startDay should be
# day y 00:00:00 and not 23:59:59
($tmp1, $tmp2)=timeConvert($endDate, $endTime, "LOC");
$tmp2=$defaultEndTime;
($periodEndDate, $periodEndTime)=timeConvert($tmp1, $tmp2, "GMT");
# Now calculate the period links (day, week, month)
foreach $i (keys(%links)){
#
# Days
($periodSyear,$periodSmon, $periodSday,
$periodShour, $periodSmin, $periodSsec)=
Add_Delta_YMDHMS($locEndYear, $locEndMon, $locEndDay, $locEndHour, $locEndMin, $locEndSec,
0, -$plinks{$i}->{"months"}, -$plinks{$i}->{"days"}+1, 0, 0, 0);
# Set new start date to defaulttime
$tmp1= "$periodSyear-$periodSmon-$periodSday";
$tmp2=$defaultStartTime;
# Now reconvert new local start time back to GMT
($tmp1, $tmp2)=timeConvert($tmp1, $tmp2, "GMT");
$periodDate="${tmp1}_$tmp2";
# Store result
$pUrls{$i}=addUrlParm($url, "sd=$periodDate;ed=${periodEndDate}_$periodEndTime", "$mmaUrlParm");
#if( $statisticsMode ){
# $pUrls{$i}=addUrlParm($pUrls{$i}, "statMode=1" );
#}
}
# Calculate $periodMonDate for month MMA display date range below
($periodMonSyear,$periodMonSmon, $periodMonSday,
$periodMonShour, $periodMonSmin, $periodMonSsec)=
Add_Delta_YMDHMS($locEndYear, $locEndMon, $locEndDay, $locEndHour, $locEndMin, $locEndSec,
0, -1, 0, 0, 0, 0);
$tmp1="$periodMonSyear-$periodMonSmon-$periodMonSday";
$tmp2=$defaultStartTime;
# Now reconvert new local start time back to GMT
($tmp1, $tmp2)=timeConvert($tmp1, $tmp2, "GMT");
$periodMonDate="${tmp1}_$tmp2";
# create links for setting mma options
# We create links for the current period of time as well as for the last
# month. They can can be distinguished by the value of mma
# "1" means current period; "2" means month
$mmaLinkmma=addUrlParm($url, "mma=1,1,1", "sd=${startDate}_$startTime", "ed=${endDate}_$endTime",
"st=$sampleTime", "rst=$rainSumMode");
$tmp="mma=2,2,2;mmasd=$periodMonDate;mmaed=$endDate";
$mmaLinkP2mma=addUrlParm($url, "$tmp", "sd=${startDate}_$startTime", "ed=${endDate}_$endTime",
"st=$sampleTime", "rst=$rainSumMode");
$tmp="mma=2,2,2;mmasd=$firstDate;mmaed=$endDate";
$mmaLinkP3mma=addUrlParm($url, "$tmp", "sd=${startDate}_$startTime", "ed=${endDate}_$endTime",
"st=$sampleTime", "rst=$rainSumMode");
$mmaLink__a=addUrlParm($url, "mma=0,0,1", "sd=${startDate}_$startTime", "ed=${endDate}_$endTime",
"st=$sampleTime", "rst=$rainSumMode");
$tmp="mma=0,0,2;mmasd=$periodMonDate;mmaed=$endDate";
$mmaLinkP2__a=addUrlParm($url, "$tmp", "sd=${startDate}_$startTime", "ed=${endDate}_$endTime",
"st=$sampleTime", "rst=$rainSumMode");
$tmp="mma=0,0,2;mmasd=$firstDate;mmaed=$endDate";
$mmaLinkP3__a=addUrlParm($url, "$tmp", "sd=${startDate}_$startTime", "ed=${endDate}_$endTime",
"st=$sampleTime", "rst=$rainSumMode");
$mmaLink___=addUrlParm($url, "mma=0,0,0", "sd=${startDate}_$startTime", "ed=${endDate}_$endTime",
"st=$sampleTime", "rst=$rainSumMode");
#print "$startTime, $endTime;; $startYear, $startMon, $startDay -> $endYear, $endMon, $endDay
\n";
# Calculate URLs for tomorrow, yesterday, ... links
foreach $i (keys(%links)){
# Get dates of tomorrow, next week, etc
($tmpSyear, $tmpSmon, $tmpSday, $tmpShour, $tmpSmin, $tmpSsec)=
Add_Delta_YMDHMS($locStartYear, $locStartMon, $locStartDay,
$locStartHour, $locStartMin, $locStartSec,
0, $links{$i}->{"months"}, $links{$i}->{"days"},
0, 0, 0);
($tmpEyear, $tmpEmon, $tmpEday, $tmpEhour, $tmpEmin, $tmpEsec)=
Add_Delta_YMDHMS($locEndYear, $locEndMon, $locEndDay,
$locEndHour, $locEndMin, $locEndSec,
0, $links{$i}->{"months"}, $links{$i}->{"days"},
0, 0, 0);
# Convert new period Start and End to GMT
($tmp1, $tmp2)=timeConvert("${tmpSyear}-${tmpSmon}-${tmpSday}", $defaultStartTime, "GMT");
($tmp3, $tmp4)=timeConvert("${tmpEyear}-${tmpEmon}-${tmpEday}", $defaultEndTime, "GMT");
#
# store URL eg in "next_week"
$urls{"next_$i"}=addUrlParm($url,
"sd=${tmp1}_${tmp2};" . "ed=${tmp3}_${tmp4};" . "$mmaUrlParm");
# Get dates of yesterday, last week etc
($tmpSyear, $tmpSmon, $tmpSday, $tmpShour, $tmpSmin, $tmpSsec)=
Add_Delta_YMDHMS($locStartYear, $locStartMon, $locStartDay,
$locStartHour, $locStartMin, $locStartSec,
0, $links{$i}->{"months"}*-1, $links{$i}->{"days"}*-1,
0, 0, 0);
# In statistics mode when we look at the current year,
# in a month by month fashion, eg when it is now fisrt
# May, and then we click "-1 years" we want that the whole last year
# is displayed and not only Jan-May as in the current year.
# So in this case we have to rewrite the end date
if( $statisticsMode >0 && $sampleTime=~/m,/ ){
($tmpEyear, $tmpEmon, $tmpEday, $tmpEhour, $tmpEmin, $tmpEsec)=
Add_Delta_YMDHMS($locEndYear, 12, 31,
$locEndHour, $locEndMin, $locEndSec,
0, $links{$i}->{"months"}*-1, $links{$i}->{"days"}*-1,
0, 0, 0);
}else{
($tmpEyear, $tmpEmon, $tmpEday, $tmpEhour, $tmpEmin, $tmpEsec)=
Add_Delta_YMDHMS($locEndYear, $locEndMon, $locEndDay,
$locEndHour, $locEndMin, $locEndSec,
0, $links{$i}->{"months"}*-1, $links{$i}->{"days"}*-1,
0, 0, 0);
}
# Convert new period Start and End to GMT
($tmp1, $tmp2)=timeConvert("${tmpSyear}-${tmpSmon}-${tmpSday}", $defaultStartTime, "GMT");
($tmp3, $tmp4)=timeConvert("${tmpEyear}-${tmpEmon}-${tmpEday}", $defaultEndTime, "GMT");
#
# store URL eg in "last_week"
$urls{"last_$i"}=addUrlParm($url,
"sd=${tmp1}_${tmp2};ed=${tmp3}_${tmp4}", "$mmaUrlParm");
}
# *****************************************************************
$frameTab = simpleTable->new(
{ "cols" => "1", "auto" => "0" },
'class="controlPanel"',
""
);
# 'background="sky3.jpg" border="1" cellspacing="1" cellpadding="1"', "");
$frameTab->setRowOptions("VALIGN='TOP'");
$frameTab->startTable(1,0);
$navTab=simpleTable->new({"cols"=>"6", "auto"=>"0"},
'border="0" cellspacing="1" cellpadding="1" width="100%"', "");
print start_form(-method=>"post", -action=>"$url" ); # ***
$navTab->startTable(1,2); # Open first col with colspan=2
print '', "Darstellungsparameter:", '';
$navTab->newCol(2);$navTab->newCol(3);
print '', "Aktuell verwendete Einstellungen:", '';
$navTab->newRow(); print " "; $navTab->newRow();
# Start output for HTML input form
print '', "Skalierung der Graphiken ...", '';
$navTab->newCol(); helpLink(-1, "?", "scaling", 0);
$navTab->newRow(3);
print '';
print radio_group(-name=>'scaling',
-values=>['x','y','x+y'],
-default=>$scaleMode);
print ", ", "Skalierungsfaktor: ",
textfield(-class=>"navTabCurText", -name => "scaleFactor",
-default => $scaleFactor,
-override=>1,
-size => "3",
-maxlength=>5);
print '';
$navTab->newCol();print " "; $navTab->newCol();
print '', "Skalierung:", '';
$navTab->newCol();
print '',
"Modus: $scaleMode, Faktor: $scaleFactor \n";
$navTab->newRow(2);
print '', "Darstellungszeitraum ...", '';
$navTab->newCol(); helpLink(-1, "?", "displayPeriod", 0); $navTab->newRow(3);
print '', "Vom ";
print textfield(-name => "startDay",
-class=>"navTabCurText",
-default => $locStartDay,
-size => "2",
-maxlength=>2) ,
" - ",
textfield(-name => "startMonth",
-class=>"navTabCurText",
-default => $locStartMon,
-size => "2",
-maxlength=>2) ,
" - ",
textfield(-name => "startYear",
-class=>"navTabCurText",
-default => $locStartYear,
-size => "4",
-maxlength=>4);
print "\n", "bis: ";
print textfield(-name => "endDay",
-class=>"navTabCurText",
-default => $locEndDay,
-size => "2",
-maxlength=>2),
" - ",
textfield(-name => "endMonth",
-class=>"navTabCurText",
-default => $locEndMon,
-size => "2",
-maxlength=>2),
" - ",
textfield(-name => "endYear",
-class=>"navTabCurText",
-default => $locEndYear,
-size => "4",
-maxlength=>4);
print " ", submit(-class=>"navTabCurText",-name=>'Anzeigen');
print "";
$navTab->newCol(); $navTab->newCol();
print '', "Zeitraum:", '';
$navTab->newCol();
print '',
" $locStartDay.$locStartMon.$locStartYear - " .
"$locEndDay.$locEndMon.$locEndYear",
'';
if( $timeIsGMT ){
print " (GMT)\n";
}else{
print "\n";
}
# In the statistics mode display there is no MMA choice to display
if( $statisticsMode == 0 ){
$navTab->newRow(2);
print '', "Min/Max/Avg-Anzeige ...", '';
$navTab->newCol(); helpLink(-1, "?", "mma", 0); $navTab->newRow();
print a({-class=>"navTabLink", href=>$mmaLinkmma},"Zeige MMA aktuell") , br,
a({-class=>"navTabLink", href=>$mmaLinkP2mma},"Zeige MMA Monat"), br
a({-class=>"navTabLink", href=>$mmaLinkP3mma},"Zeige MMA alles"), "\n";
$navTab->newCol();
print a({-class=>"navTabLink", href=>$mmaLink__a},"Zeige --A aktuell"), br,
a({-class=>"navTabLink", href=>$mmaLinkP2__a},"Zeige --A Monat"), br,
a({-class=>"navTabLink", href=>$mmaLinkP3__a},"Zeige --A alles") ;
$navTab->newCol();
print a({-class=>"navTabLink", href=>$mmaLink___},"Keine MMA-Anzeige"), "\n";
$navTab->newCol();$navTab->newCol(2);
$tmpTab=simpleTable->new({"cols"=>"2", "auto"=>"0"},
'border="0" cellspacing="1" cellpadding="1"', "");
$tmpTab->startTable(1,0);
print '', "MMA:
";$tmpTab->newCol();
if( !$refDoPlotMma->{"min"} && !$refDoPlotMma->{"max"} && !$refDoPlotMma->{"avg"} ){
print '',
"Keine MMA-Graphiken \n" ;
}else{
print '';
print "Minimum " if( $refDoPlotMma->{"min"} );
print "Maximum " if( $refDoPlotMma->{"max"} );
print "Average " if( $refDoPlotMma->{"avg"} );
print "(ber die Originaldaten)\n";
print "\n";
}
$tmpTab->newRow(); print '', "MMA-Basis: ", '';
$tmpTab->newCol();
print '',
"$locMmaStartDay.$locMmaStartMon.$locMmaStartYear - " .
"$locMmaEndDay.$locMmaEndMon.$locMmaEndYear",
" \n";
$tmpTab->endTable(); undef $tmpTab;
}# if ($statisticsMode)
$navTab->newRow(2);
print '', "Quicknavigation für Darstellung...", '';
$navTab->newCol(); helpLink(-1, "?", "quicknavi", 0); $navTab->newRow();
# ***** Day links
# +++ Period links
# When statisticsmode is active and show the +day, -day, ... links only when
# the daterange of the ststisticsdisplay is days else this would not make sense
if( $sampleTime=~/^[d]/o || $statisticsMode==0 ){
print 'Tage: ';
print a({-class=>"navTabLink", href=>$pUrls{"day"}}, $links{"day"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"day2"}}, $links{"day2"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"day3"}},
$links{"day3"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"day4"}}, $links{"day4"}->{"tag"} );
$navTab->newCol();
# +++ "prev"-links
print a({-class=>"navTabLink", href=>$urls{"last_day"}}, "-".$links{"day"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_day2"}}, "-".$links{"day2"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_day3"}},
"-".$links{"day3"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_day4"}}, "-".$links{"day4"}->{"tag"});
$navTab->newCol();
# +++ "next"-links
print a({-class=>"navTabLink", href=>$urls{"next_day"}}, "+".$links{"day"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_day2"}}, "+".$links{"day2"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_day3"}},
"+".$links{"day3"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_day4"}}, "+".$links{"day4"}->{"tag"});
$navTab->newRow();
}
# ***** Week links
# +++ Period links
# When statisticsmode is active and show the +week, -week, ... links only when
# the daterange of the statisticsdisplay is weeks or days else this would not make sense
if( $sampleTime=~/^[dw]/o || $statisticsMode==0 ){
print 'Wochen: ';
print a({-class=>"navTabLink", href=>$pUrls{"week"}}, $links{"week"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"week2"}}, $links{"week2"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"week3"}}, $links{"week3"}->{"tag"} );
$navTab->newCol();
# +++ "prev"-links
print a({-class=>"navTabLink", href=>$urls{"last_week"}}, "-".$links{"week"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_week2"}}, "-".$links{"week2"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_week3"}}, "-".$links{"week3"}->{"tag"});
$navTab->newCol();
# +++ "next"-links
print a({-class=>"navTabLink", href=>$urls{"next_week"}}, "+".$links{"week"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_week2"}}, "+".$links{"week2"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_week3"}}, "+".$links{"week3"}->{"tag"});
$navTab->newRow();
}
# ***** Month links
# +++ Period links
print 'Monate: ';
print a({-class=>"navTabLink", href=>$pUrls{"month"}}, $links{"month"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"month2"}}, $links{"month2"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"month3"}}, $links{"month3"}->{"tag"} );
$navTab->newCol();
# +++ "prev"-links
print a({-class=>"navTabLink", href=>$urls{"last_month"}}, "-".$links{"month"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_month2"}}, "-".$links{"month2"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_month3"}}, "-".$links{"month3"}->{"tag"}), " ";
$navTab->newCol();
# +++ "next"-links
print a({-class=>"navTabLink", href=>$urls{"next_month"}}, "+".$links{"month"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_month2"}}, "+".$links{"month2"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_month3"}}, "+".$links{"month3"}->{"tag"}), " ";
$navTab->newRow();
# ***** Year links
# +++ Period links
print 'Jahre: ';
print a({-class=>"navTabLink", href=>$pUrls{"year"}}, $links{"year"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"year2"}}, $links{"year2"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"year3"}}, $links{"year3"}->{"tag"} ), ", ";
print a({-class=>"navTabLink", href=>$pUrls{"year4"}}, $links{"year4"}->{"tag"} );
$navTab->newCol();
# +++ "prev"-links
print a({-class=>"navTabLink", href=>$urls{"last_year"}}, "-".$links{"year"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_year2"}}, "-".$links{"year2"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_year3"}}, "-".$links{"year3"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"last_year4"}}, "-".$links{"year4"}->{"tag"});
$navTab->newCol();
# +++ "next"-links
print a({-class=>"navTabLink", href=>$urls{"next_year"}}, "+".$links{"year"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_year2"}}, "+".$links{"year2"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_year3"}}, "+".$links{"year3"}->{"tag"}), " ";
print a({-class=>"navTabLink", href=>$urls{"next_year4"}}, "+".$links{"year4"}->{"tag"});
$navTab->newCol();
$navTab->newRow(2);
print '', "Nutze für die Darstellung ...", '';
$navTab->newCol(); helpLink(-1, "?", "sampleTime", 0); $navTab->newRow();
# Statistics mode does not allow to select Minima/Maxima as base data, raw data is used
if( $statisticsMode == 0 ){
print '', a({href=>$sampleTimeAllLink},"Originaldaten"), "";
if( $sampleTime !~ /^0/o ){
$navTab->newCol();
print '', " oder ...", '';
$navTab->newRow();
print a({-class=>"navTabLink", href=>$sampleDataTypeLinkAvg}, "Mittelwerte"); $navTab->newCol();
print a({-class=>"navTabLink", href=>$sampleDataTypeLinkMin}, "Minima"); $navTab->newCol();
print a({-class=>"navTabLink", href=>$sampleDataTypeLinkMax}, "Maxima"); $navTab->newCol();
print '', "auf...", '';
}else{
$navTab->newCol(2);
print '', "oder Mittelwerte auf ...", '';
}
$navTab->newRow();
print a({-class=>"navTabLink", href=>$sampleTimeHourLink}, "Stundenbasis"); $navTab->newCol();
}else{
$navTab->newRow();
print 'Abschnitte auf ...';
$navTab->newCol();
}
print a({-class=>"navTabLink", href=>$sampleTimeDayLink}, "Tagesbasis"); $navTab->newCol();
print a({-class=>"navTabLink", href=>$sampleTimeWeekLink},"Wochenbasis");
$navTab->newRow();
print a({-class=>"navTabLink", href=>$sampleTimeMonthLink},"Monatsbasis"); $navTab->newCol();
print a({-class=>"navTabLink", href=>$sampleTimeYearLink},"Jahresbasis");
$navTab->newCol(); print " ";
$navTab->newCol(); print " ";
$navTab->newCol(); print " ";
print '', "Datenbasis: ", '';
$navTab->newCol();
print '';
print "Original-Daten\n" if( $sampleTime =~ /^0/o );
if( $statisticsMode == 0 ){
if( ($plotsSelected && $plots=~/RA/io && $rainSumMode ) ){
%sampleTypeLabels=("Avg"=>'Summe', "Min"=>'Minima', "Max"=>'Maxima');
}else{
%sampleTypeLabels=("Avg"=>'Mittelwerte', "Min"=>'Minima', "Max"=>'Maxima');
}
}else{
%sampleTypeLabels=("Avg"=>'Abschnitte', "Min"=>'Abschnitte', "Max"=>'Abschnitte');
}
$tmp=$sampleTypeLabels{$sampleDataType};
print "$tmp auf Stundenbasis\n" if( $sampleTime =~ /^h/o );
print "$tmp auf Tagesbasis\n" if( $sampleTime =~ /^d/o );
print "$tmp auf Wochenbasis\n" if( $sampleTime =~ /^w/o );
print "$tmp auf Monatsbasis\n" if( $sampleTime =~ /^m/o );
print "$tmp auf Jahresbasis\n" if( $sampleTime =~ /^y/o );
#
print '';
if( !$statisticsMode && !$plotsSelected && $rainSumMode && $sampleTime !~ /^0/o ){
print '';
print "
(Summen für Regensensor)";
print '';
}
if( ($statisticsMode == 0) && $sampleTime !~ /^0/o &&
( !$plotsSelected || ($plotsSelected && $plots=~/RA/io))
) {
$navTab->newRow(3);
print '', checkbox(-name=>'rainSum',
-checked=>1-$rainSumMode,
-value=>"1",
-label=>"Mittelwerte für Regensonsor (statt Summen...)");
print '';
}
#
$navTab->newRow();
print '', "Darstellen als: ", '';
$navTab->newRow();
if( $statisticsMode ){
print a({-class=>"navTabLink", href=>$nonStatisticsUrl}, "Graphik Display");
}else{
print a({-class=>"navTabLink", href=>$statisticsUrl}, "Statistik (Auto)");
$navTab->newCol();
print a({-class=>"navTabLink", href=>$statistics_1YM_Url}, "Statistik J:M");
}
#$navTab->newCol(); print " ";
$navTab->newCol(); print " ";
$navTab->newCol(); print " ";
$navTab->newCol(); print " ";
print '', "Darstellung: ", '';
$navTab->newCol(0, 'endTable();
$frameTab->endTable();
print end_form;
}
#
# Display the grafixs overview showing all sensors or the more
# detailed grafic of only one sensor
#
sub showGrafixPanel{
my($dbh, $sensorData,
$plotsSelected, $plots, $plotsTypeSerial,
$rainSumMode, $sampleTime, $sampleTimeUser,
$startDate, $startTime, $endDate, $endTime,
$mmaStartDate, $mmaStartTime, $mmaEndDate, $mmaEndTime,
$locMmaStartDay, $locMmaStartMon, $locMmaStartYear,
$locMmaEndDay, $locMmaEndMon, $locMmaEndYear,
$xScaleFactor, $yScaleFactor,
$url, $startLink,
$refDoPlotMma,
$mmaUrlParm, $scaleMode, $scaleFactor)=@_;
my($i, $j, $k, $tmp, $tmpCnt,
@tmp,
$refSensor, $typeSerial, $firstRun,
$seenErrCodes, $allErrMsg, $errCode, $errMsg,
$xscale, $yscale, $theSampleTime,
$gfxSensTab, $imgUrl, $dataManager, $textUrl );
$seenErrCodes="";
$allErrMsg="";
$refSensor=$sensorData->getFirstSensor("graphics");
# If not a single sensor was selected but the overview
# Create a new table for all the sensors to be displayed
if( !$plotsSelected ){
# Give user a hint ...
print '', "
Zur genaueren Ansicht, bitte auf " .
"gewünschtes Bild klicken ...\n", '';
# Create a table for output of graphics
$gfxSensTab = simpleTable->new(
{ "cols" => $colGrfxTable, "auto" => "1" },
'border="1" width="100%" cellspacing="2" cellpadding="5" class="grfxContainer"',
""
);
$gfxSensTab->setRowOptions("VALIGN='TOP'");
$gfxSensTab->startTable(1,0);
}
$firstRun=1; # needed below
# Now iterate over the sensors defined and marked plottable
while( defined(%{$refSensor}) ){
$typeSerial=${$refSensor}{"typeSerial"};
# Do plot only if ${$refSensor}{"doPlot"} or if
# either $plotsSelected is false or
# it is true and the sensor in question has actually been selected to be plotted
# by the user which can be seen in the list of sensorTypes in $plots
if( ${$refSensor}{"doPlot"} && (
!$plotsSelected || ( $plots =~ /${$refSensor}{"sensType"}/
&& $typeSerial == $plotsTypeSerial )) ){
if( $plotsSelected ){
$xscale=${$refSensor}{"xNormalScale"} * $xScaleFactor;
$yscale=${$refSensor}{"yNormalScale"} * $yScaleFactor;
}else{
$xscale=${$refSensor}{"xSmallScale"} * $xScaleFactor;
$yscale=${$refSensor}{"ySmallScale"} * $yScaleFactor;
}
$theSampleTime=$sampleTime;
if( (${$refSensor}{"sensType"} =~/RA/ &&
$sampleTime !~ /^0/o && $rainSumMode) ||
(${$refSensor}{"sensType"} =~/LD/ && $sampleTime !~ /^0/o) ){
# For rain sensor user may want to see summary values instead of
# average values (default) if $sampleTime is day, week, month ....
# This is marked by appending a capital S to the value of $sampleTime
$theSampleTime=~s/,/S,/;
}
# Create a new Data Object for one sensor.
$dataManager=dataManager->new($dbh, $sensorData, $refSensor,
\%dstRange);
# Set options needed for the work the dataManger Class does
$dataManager->setOptions( {"sampleTime"=>"$theSampleTime",
"startDate" => "$startDate",
"startTime" => "$startTime",
"endDate" => "$endDate",
"endTime" => "$endTime",
"mmaStartDate"=>$mmaStartDate,
"mmaStartTime"=>$mmaStartTime,
"mmaEndDate" =>$mmaEndDate,
"mmaEndTime" =>$mmaEndTime,
"xscale" => "$xscale", # scaling for graphics
"yscale" => "$yscale",
"dataFilename" => "/tmp/wetterData_$$.txt",
"gnuplotFilename" => "/tmp/wetterGnuplot_$$.txt",
"bgColorAverage" => $bgColorAverage ,
"bgColorNormal" => $bgColorNormal,
"gnuplotBinary" => "$gnuplot",
"refDoPlotMma" => $refDoPlotMma});
# At the moment we ty the plotting of MMA values of virtual sensors
# to the settings of the real sensor. So if MMA values are plotted for
# a real sensor they also will be plotted for its virtual sensors
# An exception to this rule is if the mma daterange is different
# from the datrange of the graphics display. In this case we cannot display
# virtsens MMA data, since we only have them for the daterange of the display
$errCode=$dataManager->checkVirtMma($refSensor);
# Do all needed preparation work. This function also gets MMA values
# The are stored in
# $dataManager->{"results"}->{
" if( length($allErrMsg) );
$seenErrCodes.="$errCode "; # Note this code as "seen"
$allErrMsg.=$main::errMsg ;
}
}
# Now we need to distinguish wheater the user selected one particular sensor
# to be displayed or if he wants to see the overview with several sensors
# in which case $plotSelected is 0
if( !$plotsSelected ){
# User wants see the sensor overview
# Start next HTML table column or row if this is not the very first run
$gfxSensTab->newCol() if( ! $firstRun );
$firstRun=0;
# e.g: TH0
$tmp=${$refSensor}{"sensType"} . ${$refSensor}{"typeSerial"};
$url=addUrlParm($scriptUrl, "pl=$tmp",
"sd=${startDate}_$startTime;ed=${endDate}_$endTime", "$mmaUrlParm",
"sm=$scaleMode", "sf=$scaleFactor", "st=$sampleTime",
"rst=$rainSumMode");
if( $sampleTimeUser ){
$url=addUrlParm($url, "stuser=$sampleTimeUser");
}
$imgUrl=$sensorData->getSensImgUrl($refSensor);
# Title of grafics
print '',$refSensor->{"grfxName"} , '';
if( $refSensor->{"sensType"}=~/WI/ || $refSensor->{"sensType"} =~ /WD/ ){
print " ", helpLink(-2, "?", "sensorGraphicsWind", 1), "
";
}elsif( $refSensor->{"sensType"}=~/RA/ ){
print " ", helpLink(-2, "?", "sensorGraphicsRain", 1), "
";
}elsif( $refSensor->{"sensType"}=~/LD/ ){
print " ", helpLink(-2, "?", "sensorGraphicsLD", 1), "
";
}else{
print " ", helpLink(-2, "?", "sensorGraphics", 1), "
";
}
if( $dataManager->{"results"}->{"gnuplotHasPlots"} ){
print a({href=>$url, target=>"_blank"},
img {src=>"$imgUrl", align=>"TOP"});
}else{
print "
— Keine Daten —\n";
}
# Print out the URL to select textual output
$textUrl=$url; $textUrl=~s/pl=/tp=/;
if( ($refSensor->{"sensType"} eq "RA" || $refSensor->{"sensType"} eq "LD" ) &&
$sampleTimeUser==0 ){
# Since the rain sensor default display for min/Max/Avg is based on hours
# We show the table values for this sensor also based on hours by default.
# We only do this if the user has not preselected a
# certain sampleTime ($sampleTimeUser==0)
$textUrl=~s/st=0,Avg/st=h,Avg/;
}
print "
";
print a({-class=>"tiny",href=>$textUrl, target=>"_blank"}, "Als Tabelle ...");
# Now create a list with the mma-names to be displayed
# eg temp0, hum0
if( ${$refSensor}{"displayMMA"} ){
print hr;
undef @tmp;
$tmpCnt=0;
foreach $i (@{${$refSensor}{"mmaNames"}}){
$tmp[$tmpCnt++]="$i".${$refSensor}{"typeSerial"};
}
$tmp=${$refSensor}{"mmaHeight"};
}
}else{ # if plotsSelected
print '
',$refSensor->{"grfxName"} , '';
if( $refSensor->{"sensType"} =~ /WI/ || $refSensor->{"sensType"} =~ /WD/ ){
print " ", helpLink(-2, "?", "sensorGraphicsWind", 1), "
";
}elsif( $refSensor->{"sensType"}=~/RA/ ){
print " ", helpLink(-2, "?", "sensorGraphicsRain", 1), "
";
}elsif( $refSensor->{"sensType"}=~/LD/ ){
print " ", helpLink(-2, "?", "sensorGraphicsLD", 1), "
";
}else{
print " ", helpLink(-2, "?", "sensorGraphics", 1), "
";
}
# If there is nothing to plot, avoid "broken image" icon
if( $dataManager->{"results"}->{"gnuplotHasPlots"} ){
print '', " (Zurück zur ",
a({href=>"$startLink"},"Übersicht"),
" aller Sensoren.)
\n", '';
print "
";
# Assemble image URL for this sensor
$imgUrl=$sensorData->getSensImgUrl($refSensor);
print img {src=>"$imgUrl"};
}else{
print "
— Keine Daten —\n";
}
# Print Link to access the raw text data
$tmp=${$refSensor}{"sensType"} . ${$refSensor}{"typeSerial"};
$url=addUrlParm($scriptUrl, "pl=$tmp",
"sd=${startDate}_$startTime;ed=${endDate}_$endTime", "$mmaUrlParm",
"sm=$scaleMode", "sf=$scaleFactor", "st=$sampleTime",
"rst=$rainSumMode");
$textUrl=$url; $textUrl=~s/pl=/tp=/;
print "
";
print a({-class=>"tiny",href=>$textUrl, target=>"_blank"}, "Als Tabelle ....");
if( ${$refSensor}{"displayMMA"} ){
print h4("Maximal/Minimal-Werte vom " .
"$locMmaStartDay.$locMmaStartMon.$locMmaStartYear - " .
"$locMmaEndDay.$locMmaEndMon.$locMmaEndYear" );
# Now create a list with the mma-names to be displayed
# eg temp0, hum0
undef @tmp;
$tmpCnt=0;
foreach $i (@{${$refSensor}{"mmaNames"}}){
$tmp[$tmpCnt++]="$i$plotsTypeSerial";
}
$tmp=${$refSensor}{"mmaHeight"};
}
}# end if plotsSelected
# Now print the MMA values
if( ${$refSensor}{"displayMMA"} ){
$tmp=${$refSensor}{"mmaHeight"};
printMmaValues($dataManager, $refSensor,
'width="100%"', # width
$tmp!=0?"height=$tmp":"", # height
$plotsSelected?2:-2, # Fontsize
$plotsSelected, # Print virtual sensors
$theSampleTime # MMA or not
);
}
} # end if doPlot
# Keep the MMA values stored in $dataManager for the display below
undef $dataManager;
# Get next
$refSensor=$sensorData->getNextSensor("graphics");
} # end while
$gfxSensTab->endTable() if( ! $plotsSelected );
# print errors/warning that might have been collected in plotData();
if( length($allErrMsg) ){
print '
';
print $allErrMsg, "\n";
print "
";
}
}
#
# Display the Textgrafixs overview showing all sensors or the more
# detailed grafic of only one sensor
#
sub showTextPanel{
my($dbh, $sensorData,
$plotsSelected, $plots, $plotsTypeSerial,
$rainSumMode, $sampleTime,
$startDate, $startTime, $endDate, $endTime,
$mmaStartDate, $mmaStartTime, $mmaEndDate, $mmaEndTime,
$locMmaStartDay, $locMmaStartMon, $locMmaStartYear,
$locMmaEndDay, $locMmaEndMon, $locMmaEndYear,
$xScaleFactor, $yScaleFactor,
$url, $startLink,
$refDoPlotMma,
$mmaUrlParm, $scaleMode, $scaleFactor)=@_;
my($i, $j, $k, $tmp, $tmpCnt,
@tmp, $modeUrl,
$refSensor, $typeSerial, $firstRun,
$seenErrCodes, $allErrMsg, $errCode, $errMsg,
$theSampleTime,
$imgUrl, $dataManager );
$seenErrCodes="";
$allErrMsg="";
$refSensor=$sensorData->getFirstSensor("graphics");
$firstRun=1; # needed below
# Now iterate over the sensors defined and marked plottable
while( defined(%{$refSensor}) ){
$typeSerial=${$refSensor}{"typeSerial"};
# Do plot only if ${$refSensor}{"doPlot"} or if
# either $plotsSelected is false or
# it is true and the sensor in question has actually been selected to be plotted
# by the user which can be seen in the list of sensorTypes in $plots
if( ${$refSensor}{"doPlot"} && (
!$plotsSelected || ( $plots =~ /${$refSensor}{"sensType"}/
&& $typeSerial == $plotsTypeSerial )) ){
$theSampleTime=$sampleTime;
if( (${$refSensor}{"sensType"} =~/RA/ && $sampleTime !~ /^0/o
&& $rainSumMode) ||
(${$refSensor}{"sensType"} =~/LD/ && $sampleTime !~ /^0/o )){
# For rain sensor user may want to see summary values instead of
# average values (default) if $sampleTime is day, week, month ....
# This is marked by appending a capital S to the value of $sampleTime
$theSampleTime=~s/,/S,/;
}
# Create a new Data Object for one sensor.
$dataManager=dataManager->new($dbh, $sensorData, $refSensor,
\%dstRange);
# Set options needed for the work the dataManger Class does
$dataManager->setOptions( {"sampleTime"=>"$theSampleTime",
"startDate" => "$startDate",
"startTime" => "$startTime",
"endDate" => "$endDate",
"endTime" => "$endTime",
"mmaStartDate"=>$mmaStartDate,
"mmaStartTime"=>$mmaStartTime,
"mmaEndDate" =>$mmaEndDate,
"mmaEndTime" =>$mmaEndTime,
"xscale" => "$xscale", # scaling for graphics
"yscale" => "$yscale",
"dataFilename" => "/tmp/wetterData_$$.txt",
"gnuplotFilename" => "/tmp/wetterGnuplot_$$.txt",
"bgColorAverage" => $bgColorAverage ,
"bgColorNormal" => $bgColorNormal,
"gnuplotBinary" => "$gnuplot",
"refDoPlotMma" => $refDoPlotMma});
# At the moment we ty the plotting of MMA values of virtual sensors
# to the settings of the real sensor. So if MMA values are plotted for
# a real sensor they also will be plotted for its virtual sensors
# An exception to this rule is if the mma daterange is different
# from the datrange of the graphics display. In this case we cannot display
# virtsens MMA data, since we only have them for the daterange of the display
$dataManager->checkVirtMma($refSensor);
# Do all needed preparation work. This function also gets MMA values
# The are stored in
# $dataManager->{"results"}->{
\
\n", '';
print '', "Tabellarische Datenbersicht:", '';
helpLink(-1, " ?", "tableView", 0);
print "
\
\n";
# print tabular output
$errCode=$dataManager->runTextplot($sampleTime);
# Unlink temp files and SQL result data (MMA data are left untouched)
# This is done to save memory since the complete results of one
# sql query are kept in main memory
$dataManager->unlinkTmpData();
# If there was an error/warning that should be displayed to the user
# Note this message. To avoid double warning of the same type
# we uses an errorType that has a n associated message.
# Each errcode that was found is noted in $seenErrCodes so a second error
# of the same type can be skipped.
if( $errCode ){
if( $seenErrCodes !~ /$errCode/i ){
$allErrMsg.="
" if( length($allErrMsg) );
$seenErrCodes.="$errCode "; # Note this code as "seen"
$allErrMsg.="$main::errMsg";
}
}
if( ${$refSensor}{"displayMMA"} ){
print h4("Maximal/Minimal-Werte vom " .
"$locMmaStartDay.$locMmaStartMon.$locMmaStartYear - " .
"$locMmaEndDay.$locMmaEndMon.$locMmaEndYear" );
# Now create a list with the mma-names to be displayed
# eg temp0, hum0
undef @tmp;
$tmpCnt=0;
foreach $i (@{${$refSensor}{"mmaNames"}}){
$tmp[$tmpCnt++]="$i$plotsTypeSerial";
}
$tmp=${$refSensor}{"mmaHeight"};
}
# Now print the MMA values
if( ${$refSensor}{"displayMMA"} ){
$tmp=${$refSensor}{"mmaHeight"};
printMmaValues($dataManager, $refSensor,
'width="100%"', # width
$tmp!=0?"height=$tmp":"", # height
$plotsSelected?2:-2, # Fontsize
$plotsSelected, # Print virtual sensors
$theSampleTime # MMA or not
);
}
} # end if doPlot
# Keep the MMA values stored in $dataManager for the display below
undef $dataManager;
# Get next
$refSensor=$sensorData->getNextSensor("graphics");
} # end while
# print errors/warning that might have been collected in plotData();
if( length($allErrMsg) ){
print '
';
print $allErrMsg, "\n";
print "
";
}
}
# ============================================================
# ----- main -------------------------------------------------
# ============================================================
# Check if impPath is writable for the script (and gnuplot)
imgpathWriteTest();
# If the url contains the parameter "days=1" then display only data of
# the given number of days (here 1).
$days=url_param('days');
if( $days > 0 ){
$initialDisplayDays=$days;
}
$hours=url_param('hours');
if( $hours > 0 ){
$initialDisplayHours=$hours;
}else{
$initialDisplayHours=0;
}
# defaults for scaling
$defScaleMode="x";
$defScaleFactor="1";
$scaleMode=$defScaleMode;
$scaleFactor=$defScaleFactor;
$defSampleTime="0";
$sampleTime=$defSampleTime;
$defSampleDataType="Avg";
$sampleDataType=$defSampleDataType;
$rainSumMode=1; # For rain sensor we plot average not sum value if
# $sampleTime != "0"
$defaultStartTime="00:00:00"; # Given in local time
$defaultEndTime="23:59:59"; # Given in local time, if changed look at
# #**# below! Needs also to be changed then.
# Get todays date in local time
($tYear, $tMonth, $tDay, $tHour, $tMin, $tSec)=Today_and_Now(0);
$today=sprintf("%4d-%02d-%02d", $tYear,$tMonth,$tDay);
if( $initialDisplayHours == 0 ){
# Normal End time is $defaultEndtime (in GMT)
# this usually is the end of the current day.
($endHour, $endMin, $endSec)=split(/:/o, $defaultEndTime);
($endYear, $endMon, $endDay)=split(/-/o, $today);
# used below in Add_Delta_DHMS call
$dh=0;
}else{
# if $initialDisplayHours is != 0 Endtime is "Now"
# And we want to display only the last
\n";
# Default *time* values for mma calculation
$mmaStartDate=$startDate;
$mmaStartTime=$startTime;
$mmaEndDate=$endDate;
$mmaEndTime=$endTime;
# Get sensors value from URL
$plots="";
$plots=url_param('pl'); # Flags that a particular sensor is to be plotted
$textPl=url_param('tp'); # Flags that text output of data is wanted for a sensor
if( !length($plots) && !length($textPl) ){
$plotsSelected=0;
$plots=$latestSens; # Temp/hum, Pressure, Wind, Light,
# Rain, Pyranometer
$plotsTypeSerial=0;
}else{
if( length($textPl) ){
$textPlots=1 ; # Flag for Text output instead of graphics
$plots=$textPl; # Use $plots variable for further processing
}
$plotsSelected=1;
$plotsTypeSerial=$plots;
# Identify type serial id of sensor (eg which of several TH
# sensor graphics this is
$plotsTypeSerial=~s/^[A-Z]+//; # eg. "TH1": Result is "1"
$plots=~s/[0-9]+//;
}
# Print Latest data only in overview mode with all sensor values
$printLatestData=1;
$printLatestData=0 if( $plotsSelected);
# Define CCS Stylesheet used for document text font sizes etc.
$docCss=<
");
a.setAttribute("tiptitle", newTitle);
a.removeAttribute("title");
a.onmouseover = function() {tooltip.show(this.getAttribute('tiptitle'))};
a.onmouseout = function() {tooltip.hide()};
}
}
}
tooltip.move = function (evt) {
var x=0, y=0;
if (document.all) {//IE
x = (document.documentElement && document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft;
y = (document.documentElement && document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
x += window.event.clientX;
y += window.event.clientY;
} else {//Good Browsers
x = evt.pageX;
y = evt.pageY;
}
this.tip.style.left = (x + this.offsetX) + "px";
this.tip.style.top = (y + this.offsetY) + "px";
}
tooltip.show = function (text) {
if (!this.tip) return;
this.tip.innerHTML = text;
this.tip.style.display = "block";
}
tooltip.hide = function () {
if (!this.tip) return;
this.tip.innerHTML = "";
this.tip.style.display = "none";
}
window.onload = function () {
tooltip.init ();
}
EOF
;
#
# Decide from where to take the cascading style sheets
if( !length($externalCssUrl) ){
$cssTag="-code"; $cssValue="$docCss";
}else{
$cssTag="-src"; $cssValue="$externalCssUrl";
}
# print html stuff
# start htmlpage for all cases
print header(-type =>'text/html', -expires =>'+1m'),
start_html(-title =>$pageTitle,
-encoding =>'UTF-8',
-style =>{ $cssTag => $cssValue },
-script => $toolTipCode,
-author =>$pageAuthors,
-dtd => '-//W3C//DTD HTML 4.01 Transitional//EN',
-base =>'true',
-meta =>{'keywords' => $pageMetaKeywords,
'description'=> $pageDescription},
-BGCOLOR=>$pageBackgroundColor, -TEXT => $pageTextColor, -LINK =>$pageLinkColor,
-background=>$pageBackgroundPicture,
-VLINK =>$pageVisitedLinkColor, -ALINK =>'black'), "\n";
# Marks that we have started the http header. Used in doDie(), doWarn()
$preHtmlDocInit=0;
# Script was called to display help ?
# sub printHelp does not return.
$help=url_param('help');
printHelp($help) if( length($help) );
$dbh=connectDb(); # Connect with Database
if( !$dbh ){
print "Keine Verbindung zum Datenbank-Server. Abbruch";
print end_html, "\n";
}
# Find out which version the server has (SELECT VERSION(); )
$MysqlVersion=getMysqlVersion($dbh);
if( $MysqlVersion >= 5.0 ){
# Use subqueries for Min/Max/Avgh determination
# if this varaiable has not already been set elsewhere
$useSqlSubQueries=1 if( ! defined($useSqlSubQueries) );
}else{
$useSqlSubQueries=0 if( ! defined($useSqlSubQueries) );
}
# Get the date of first Dataset.
@first=getFirstTimeDateSet($dbh, $sensorData);
$firstDate="$first[0]-$first[1]-$first[2]";
$firstYear=$first[0];
$firstMon=$first[1];
$firstDay=$first[2];
# Get date and time of last existant dataset
# needed below
@now=getLastTimeDateSet($dbh, $sensorData);
# Extract sensor Names from database and enter values into sensor configuration data
$sensorData->getSensorNames($dbh);
# Get date values from HTML form or from url
# If there is a date received from the form parameters this as well as
# other parameters from the form will be
# taken. Else we look for a date in the url, so we can evaluate links
# containing a date entry (sd=2003-06-25;ed=xxxxxxx)
$selsDay=param('startDay');
if( length($selsDay) ){
$selsMon=param('startMonth');
$selsYear=param('startYear');
$seleDay=param('endDay');
$seleMon=param('endMonth');
$seleYear=param('endYear');
# Scaling for images
$scaleMode=param('scaling');
$scaleMode=$defScaleMode if( $scaleMode ne "x" && $scaleMode ne "y"
&& $scaleMode ne "x+y" );
$scaleFactor=param('scaleFactor');
$scaleFactor=$defScaleFactor if( $scaleFactor !~ /[0-9.]+/o );
# sample time average data display
# we have to take this val from the url cause there is no
# form element to define it but only a link
# $sampletime encodes the time as well as the value to display
# (Avg, Min, Max). It looks like eg "d,Min"
$sampleTimeBase=url_param('st');
$sampleDataType=$sampleTimeBase;
$sampleDataType=~s/[0a-zA-Z],//o; # eg $sampleTime=="d,Avg"
$sampleTimeBase=~s/,.*$//o;
$sampleTimeUser=url_param('stuser');
$sampleTimeUser=0 if( ! length($sampleTimeUser));
# Parameter if rain data is to be displayed as average or a summary
# if $sampleTime != "0"
#$rainSumMode=param('rainSum');
$rainSumMode=0 if( param('rainSum') eq "1" );
# Construct new start an end date
$startDate="$selsYear-$selsMon-$selsDay";
$startTime=$defaultStartTime;
($startDate, $startTime)=timeConvert($startDate, $startTime, "GMT");
$endDate="$seleYear-$seleMon-$seleDay";
$endTime=$defaultEndTime;
($endDate, $endTime)=timeConvert($endDate, $endTime, "GMT");
}else{
$sDate=url_param('sd');
$eDate=url_param('ed');
if( length($sDate) && length($eDate) ){
($startDate,$startTime)=split(/_/o, $sDate);
($endDate,$endTime)=split(/_/o, $eDate);
# Take care that date has correct format
($startYear, $startMon, $startDay)=split(/-/o, $startDate);
($startHour, $startMin, $startSec)=split(/:/o, $startTime);
($endYear, $endMon, $endDay)=split(/-/o, $endDate);
($endHour, $endMin, $endSec)=split(/:/o, $endTime);
$startDate=sprintf("%04d-%02d-%02d", $startYear,$startMon, $startDay);
$startTime=sprintf("%02d:%02d:%02d", $startHour,$startMin, $startSec);
$endDate=sprintf("%04d-%02d-%02d", $endYear,$endMon, $endDay);
$endTime=sprintf("%02d:%02d:%02d", $endHour,$endMin, $endSec);
}
# Scaling for images
$scaleMode=url_param('sm');
$scaleFactor=url_param('sf');
$scaleFactor=$defScaleFactor if( $scaleFactor !~ /[0-9.]+/o );
$scaleMode=$defScaleMode if( $scaleMode ne "x" && $scaleMode ne "y"
&& $scaleMode ne "x+y" );
# sample time average data display
# $sampletime encodes the time as well as the value to display
# (Avg, Min, Max). It looks like eg "d,Min"
# The value to be displayed is stored in $sampleDataType
$sampleTimeBase=url_param('st');
$sampleDataType=$sampleTimeBase;
$sampleDataType=~s/[0a-zA-Z],//o; # eg $sampleTime=="d,Avg"
$sampleTimeBase=~s/,.*$//o;
$sampleTimeUser=url_param('stuser');
$sampleTimeUser=0 if( ! length($sampleTimeUser));
# Parameter if rain data is to be displayed as average or a summary
# if $sampleTime != "0"
$rainSumMode=url_param('rst') if( length(url_param('rst')));
$rainSumMode=0 if( $rainSumMode ne "1" );
}
# Determine scaling factors
$xScaleFactor=1;
$yScaleFactor=1;
if( $scaleMode =~ /x\+y/ ){
$xScaleFactor=$scaleFactor;
$yScaleFactor=$scaleFactor;
}elsif( $scaleMode =~ /^x/ ){
$xScaleFactor=$scaleFactor;
}elsif( $scaleMode =~ /^y/ ){
$yScaleFactor=$scaleFactor;
}
# Check sampleTimeBase Mode. May be "h","d", "w", "m", "y" (hour,day, week, moth, year)
# or "0" (off==use all data available, which is the default mode)
# $sampletime encodes the time as well as the value to display
# (Avg, Min, Max). It looks like eg "d,Min"
# Here we add the value ($sampleDataType) to the time period (d,w,m,y) contained in
# $sampleTime already
if( $sampleTimeBase !~/^[hdwmy0]/io ){
$sampleTimeBase=$defSampleTime;
$sampleTime="$sampleTimeBase,$defSampleDataType";
$sampleDataType="$defSampleDataType";
}else{
if( length($sampleDataType) ){
$sampleTime="$sampleTimeBase,$sampleDataType";
}
}
# Correct single variables to corrected startDate, endDate
($startYear, $startMon, $startDay)=split(/-/o, $startDate);
($startHour, $startMin, $startSec)=split(/:/o, $startTime);
($endYear, $endMon, $endDay)=split(/-/o, $endDate);
($endHour, $endMin, $endSec)=split(/:/o, $endTime);
# Check if statisticsMode is active
$statisticsMode=url_param('statMode');
if( length($statisticsMode) && $statisticsMode =~ /1/o ){
$statisticsMode="1";
$delta=Delta_Days($startYear,$startMon,$startDay,
$endYear,$endMon,$endDay);
# Set default sampleTime according to the date range selected
if( ! $sampleTimeUser ){
if( $delta <=7 ){ $sampleTime=~s/^[0a-zA-Z]/d/o; }
if( $delta > 7 && $delta <28 ){ $sampleTime=~s/^[0a-zA-Z]/w/o;}
if( $delta >=28 && $delta <=365){ $sampleTime=~s/^[0a-zA-Z]/m/o;}
if( $delta > 365 ){ $sampleTime=~s/^[0a-zA-Z]/y/o;}
}else{
# The has preselected a sampleTime but "h"
# is not allowed for statistics mode
if( $sampleTime=~/^[0h].*/ ){
$sampleTime=~s/^[0a-zA-Z]/w/o;
}
}
}else{
$statisticsMode=0;
}
#
# Check dates
$dateIsValid=1;
# ***
($startDate, $startTime, $endDate, $endTime, $dateIsValid, $errStr)=
checkDate($firstYear, $firstMon, $firstDay,
$startDate, $startTime, $endDate, $endTime,
$sampleTime, \@now, \@first, $statisticsMode);
# Doesn't need to be done if output is in GMT. Probably save some time...
if (!$timeIsGMT) {
# Now we calculate for each year from start to end the
# time range for DST and store this in a global hash. It is needed in
# buildSqlCommand() since MYSQL does not yet support DST conversion
# We have to start at $startYear -1 since the user supplied startYear may be
# corrected to the year befor if the user select year average. The the
# startdate is eg for 2004 corrected to 01.01.2004 and then converted
# into gmt which is 31.12.2003 23:00:00
for($i=$startYear-1; $i<=$endYear; $i++){
($dstStart,$dstEnd, $deltaIsDst, $deltaNoDst)=getDSTStartEnd($i);
$dstRange{$i}->{"dstStart"}=$dstStart;
$dstRange{$i}->{"dstEnd"}=$dstEnd;
$dstRange{$i}->{"deltaIsDst"}=$deltaIsDst;
$dstRange{$i}->{"deltaNoDst"}=$deltaNoDst;
}
# Get dst info for current year if not already there
$tmp=(Today_and_Now(1))[0]; # year of today
if( ! defined($dstRange{$tmp}) ){
($dstStart,$dstEnd, $deltaIsDst, $deltaNoDst)=getDSTStartEnd($tmp);
$dstRange{$tmp}->{"dstStart"}=$dstStart;
$dstRange{$tmp}->{"dstEnd"}=$dstEnd;
$dstRange{$tmp}->{"deltaIsDst"}=$deltaIsDst;
$dstRange{$tmp}->{"deltaNoDst"}=$deltaNoDst;
}else{
# Global variables to hold dst info for current year needed eg by timeConvert
$dstStart=$dstRange{$tmp}->{"dstStart"};
$dstEnd=$dstRange{$tmp}->{"dstEnd"};
$deltaIsDst=$dstRange{$tmp}->{"deltaIsDst"};
$deltaNoDst=$dstRange{$tmp}->{"deltaNoDst"};
}
}
#print "$startDate _ $startTime, $endDate _ $endTime
\n";
# Check how many days we will display and decide if we
# display hour based average values instead of original
# data values to minimize the processing time
$delta=Delta_Days($startYear,$startMon,$startDay,
$endYear,$endMon,$endDay);
#
if( !$statisticsMode && $doAutoBaseData && (! $sampleTimeUser) && ($delta >= $doAutoBaseData) ){
if( $delta >= 365 ){
$sampleDataType=$sampleTimeBase=$sampleTime="d,$sampleDataType";
}else{
$sampleDataType=$sampleTimeBase=$sampleTime="h,$sampleDataType";
}
$sampleDataType=~s/[0a-zA-Z],//o;
$sampleTimeBase=~s/,.*$//o;
}
# Start a table column, that surrounds the whole page, so the single
# Elements will have the same width
$pageTab=simpleTable->new({"cols"=>"1", "auto"=>"0"},
'border="0" cellspacing="0" cellpadding="0"', "");
$pageTab->startTable(1,0);
#
# Define and write the latest data overview to the webpage if wanted
#
showLatestDataPanel($plots, $sensorData, $pageTab, \@now)
if( $printLatestData );
# get MMA date parameters from URL
($mmaStartDate, $mmaStartTime,
$mmaEndDate, $mmaEndTime,
$locMmaStartYear, $locMmaStartMon, $locMmaStartDay,
$locMmaStartHour, $locMmaStartMin, $locMmaStartSec,
$locMmaEndYear, $locMmaEndMon, $locMmaEndDay,
$locMmaEndHour, $locMmaEndMin, $locMmaEndSec,
$mmaUrlParm)
= calcMmaDates($startDate, $endDate, $startTime, $endTime,
$defaultStartTime, $defaultEndTime, \%doPlotMma);
#
# Now create and write the navigation panel into the webpage
#
if( $navPanelPos eq "top" ){
showNavigationPanel(
$startDate, $endDate, $startTime, $endTime,
$defaultStartTime, $defaultEndTime,
$mmaStartDate, $mmaStartTime,
$mmaEndDate, $mmaEndTime,
$locMmaStartYear, $locMmaStartMon, $locMmaStartDay,
$locMmaStartHour, $locMmaStartMin, $locMmaStartSec,
$locMmaEndYear, $locMmaEndMon, $locMmaEndDay,
$locMmaEndHour, $locMmaEndMin, $locMmaEndSec,
$mmaUrlParm,
$sampleTime, $sampleTimeBase, $sampleTimeUser,
$defSampleTime,
$defSampleDataType, $sampleDataType,
$plots, $plotsSelected, $textPlots,
$rainSumMode, $scaleMode, $defScaleMode,
$defScaleFactor, $scaleFactor,
\%doPlotMma, $plotsTypeSerial, \@now, \@first,
$statisticsMode );
}
# Link to reach the overview page from any detailed plot page
$startLink=addUrlParm($url, "sd=$startDate;ed=$endDate");
if( !$dateIsValid ){
print "
",
'
",
$errStr,
"
\n";
}
# Check if we should display the statistics dialog
if( $statisticsMode ){
# -----------------------------------------------------
#print join(", ", keys(%$sensorData)), "\n";
# Now get and siplay statistical data
$statistics=statistics->new($sensorData, $startDate, $startTime,
$endDate, $endTime, $sampleTime, $dbh,
# dst infos # date of latest dataset
\%dstRange, \@now, \@first);
$statistics->getPrintStats();
}elsif( $textPlots ){
# -----------------------------------------------------
# Now set the rest of data to create the textual output
showTextPanel($dbh, $sensorData,
$plotsSelected, $plots, $plotsTypeSerial,
$rainSumMode, $sampleTime,
$startDate, $startTime, $endDate, $endTime,
$mmaStartDate, $mmaStartTime, $mmaEndDate, $mmaEndTime,
$locMmaStartDay, $locMmaStartMon, $locMmaStartYear,
$locMmaEndDay, $locMmaEndMon, $locMmaEndYear,
$xScaleFactor, $yScaleFactor,
$url, $startLink,
\%doPlotMma,
$mmaUrlParm, $scaleMode, $scaleFactor);
}else{
# -----------------------------------------------------
# Now set the rest of data to create the graphics, and
# create plots (images) for all defined sensors
showGrafixPanel($dbh, $sensorData,
$plotsSelected, $plots, $plotsTypeSerial,
$rainSumMode, $sampleTime, $sampleTimeUser,
$startDate, $startTime, $endDate, $endTime,
$mmaStartDate, $mmaStartTime, $mmaEndDate, $mmaEndTime,
$locMmaStartDay, $locMmaStartMon, $locMmaStartYear,
$locMmaEndDay, $locMmaEndMon, $locMmaEndYear,
$xScaleFactor, $yScaleFactor,
$url, $startLink,
\%doPlotMma,
$mmaUrlParm, $scaleMode, $scaleFactor);
}
#
# Now create and write the navigation panel into the webpage
#
if( $navPanelPos eq "bottom" ){
print "
\n";
showNavigationPanel(
$startDate, $endDate, $startTime, $endTime,
$defaultStartTime, $defaultEndTime,
$mmaStartDate, $mmaStartTime,
$mmaEndDate, $mmaEndTime,
$locMmaStartYear, $locMmaStartMon, $locMmaStartDay,
$locMmaStartHour, $locMmaStartMin, $locMmaStartSec,
$locMmaEndYear, $locMmaEndMon, $locMmaEndDay,
$locMmaEndHour, $locMmaEndMin, $locMmaEndSec,
$mmaUrlParm,
$sampleTime, $sampleTimeBase, $sampleTimeUser,
$defSampleTime,
$defSampleDataType, $sampleDataType,
$plots, $plotsSelected, $textPlots,
$rainSumMode, $scaleMode, $defScaleMode,
$defScaleFactor, $scaleFactor,
\%doPlotMma, $plotsTypeSerial, $statisticsMode );
}
# TEST
# print "Ja ID : $jaid";
# print "Nein ID : $rainid";
# print "Regenbeginn ID $rainingid";
# print "Abfrageergebnis : $ergebnis";
# print "Max ID : $id";
# print "Rainingdate: $rainingdate";
# print "DAs Ergebnis der Auswahl ist: $ergebnis";
# print "Das Datum ist $tag.$monat.$jahr um $locstunde:$minute";
# print "Ist sommer: $Sommerzeit";
print "Letzter Regen : $lastrainstunde";
print hr, '';
print "Die Daten stammen von einer IPWE-1 Wetter-Station und werden unter ";
print "Linux mit dem Spript wetter.cgi der Software ";
print
a({href=>"http://userpages.uni-koblenz.de/~krienke/ftp/unix/ws2500/"},"ws2500");
print " aufbereitet. Alle Angaben erfolgen ohne
Gewähr auf ihre Vollständigkeit oder Richtigkeit.
\n";
print '', "\n";
$pageTab->endTable();
# End html Stuff
print end_html, "\n";
#unlink $thImgName;
closeDb($dbh);
exit 0;