Tutorials von wetterbinningen.ch

Willkommen auf dem Tutorial Blog von der Wetterseite wetterbinningen.ch.

Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:


http://www.pscl.ch

Für Fragen, Kommentare und Kritik bin ich immer Dankbar.

Viel Spass und Grüsse




Tutorial - Wetterdaten und Datenbanken - Teil 1 - Einleitung

Wetterdaten und Datenbanken 


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Einleitung


Datenbanken eignen sich für die Ablage von Wetterdaten besonders gut. Diese wurden entwickelt, um große Datenmengen zu verwalten. Vereinfacht kann man sich Datenbanken wie eine Tabelle aus zB. Excel vorstellen. Oft enthalten Datenbanken mehrere solcher Tabellen, welche zudem miteinander verknüpft sein können.


Einige Vorteile


  • Schneller Zugriff
  • Filter / Sortierung
  • Berechnungen wie sum/min/max/avg
  • Datumsfunktionen
  • geringer Platzbedarf
  • komfortable Verwaltung


Tabellen


Hier ein Beispiel einer Tabelle:


MySQL Tabellen Inhalt angezeigt von phpMyAdmin



Für jede Spalte muss mindestens ein Name und Typ angegeben werden. Gewisse Typen verlangen zusätzliche Parameter wie z.B die maximale Grösse/Länge.


MySQL Tabellen Struktur angezeigt von phpMyAdmin


Speicherbedarf 


Gehen wir von einem 5 Minuten Speicherinterval aus., dann sind das 288 Datenzeilen pro Tag. Das sind pro Monat bereits 8640 und im Jahr schon über 105'000. Gehen wir von ca. 15 Spalten aus, sind das über 1.5 Millionen Einzelwerte pro Jahr. (So eine Tabelle mit Wetterdaten, belegt bei mir ca. 6 MByte im Jahr.)

Diese Datenmengen aufzunehmen, sollte für MySQL aber kein Problem darstellen. Die Zugriffszeiten hängen aber von der Abfrage selbst, sowie der Leistungsfähigkeit und Auslastung des Servers ab. 


Verwaltung:


Als Graphische Oberfläche dient uns das Tool phpMyAdmin. Es ist bei den meisten Providern vorinstalliert und erlaubt das einfache Verwalten von MySQL. Ansonsten bedient man eine Datenbank mit sogenannten sql-Befehlen. Dazu aber Später mehr.




Tutorial - Wetterdaten und Datenbanken - Teil 2 - Tabelle erstellen

Teil 2 - Tabelle erstellen


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Die Wetterdaten werden in einer Tabelle gespeichert. Jede Zeile enthält Datum, Zeit und die Werte der Sensoren zum jeweiligen Zeitpunkt.

(Frühe Versionen dieses Tutorials enthielten noch die Spalte dateid. Diese wurde in einem Update entfernt.)




1. Neue Tabelle erzeugen


Zuerst in phpMyAdmin einloggen. Dann eine neue Tabelle erzeugen:




2. Spalten der Tabelle


Name, Typ und Länge wie im Bild ausfüllen und zusätzlich für die Spalte "datetime" PRIMARY aktivieren: 



3. Speichern


Jetzt "speichern" um die Tabelle anzulegen. Diese ist jetzt für das Eintragen von Daten vorbereitet.


Weiter mit Teil 3 - Tabelle füllen

Optional: Kurze Beschreibung der Spalten und Typen


Name: datetime
Typ: "datetime" für Datum und Zeit im Format "2013-11-25 00:00:00"
Verwendung:  Das Datum und die Zeit. Für diese Spalte aktivieren wir PRIMARY unter Index.

Name: temp, hum, pressure, etc.
Typ: "decimal" für Dezimalzahlen mit Kommastellen. Benötigt max. Länge inklusive Anzahl Kommastellen. (Bei Länge (5,1) wären also die Werte  -9999.9 bis 9999.9 erlaubt. Passen Sie diese gegebenenfalls an Ihre Bedürfnisse an. z.B: 2 Kommastellen (6,2) für 9999.99)
Verwendung: Die decimal Spalten nehmen die Wetterdaten auf.

Optimierung: (Besten Dank für den Tipp im Kommentar):
Die Wetterwerte könnte man auch in SMALLINT speichern (dann mit zb. 10 multiplizieren). Die Tabelle würde dann einiges weniger Speicherplatz belegen.

Tutorial - Wetterdaten und Datenbanken - Teil 3 - Tabelle füllen

Teil 3 - Tabelle mit Daten füllen

Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch

Unsere Tabelle enthält noch keine Daten. Es gibt nun diverse Möglichkeiten, unsere Wetterdaten in die Tabelle zu bekommen. Sehen wir uns einige Wege an.



Mit phpMyAdmin


Mit phpMyAdmin lassen sich Daten über ein Formular einfügen.

1. Einfügen öffnen und einen ersten Datensatz wie im Bild eingeben. Dann auf "OK" klicken.




2. Um den Datensatz anzusehen, "Anzeigen" wählen:







Achtung: Die Tabelle lässt keine doppelten Einträge in der Spalte "datetime" zu. (Die "datetime" jeweils ändern, um einen neuen Datensatz anzulegen)


Ein wenig SQL ?


SQL ist die "Sprache" der Datenbanken. phpMyAdmin bietet einen Bereich wo man sql-Befehle direkt ausführen kann. Wir sehen uns das mal an:

In phpMyAdmin "SQL" öffnen und folgenden Text in das Fenster schreiben/kopieren:


1. Zuerst unsere Tabelle auswählen ...

INSERT INTO wettertabelle


2. ... dann die Spaltennamen ...

(`datetime`,`temp`,`hum`,`pressure`) 


3. ... und die eigentlichen Werte. (in gleicher Reihenfolge wie die Spaltennamen):

VALUES
('2013-11-25 00:05:00','11.9','87','999.4')


Hier der sql-Befehl nochmals komplett:

INSERT INTO wettertabelle 
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('2013-11-25 00:05:00','11.9','87','999.4')






4. Jetzt auf "Ok" klicken, und der Datensatz sollte unter "Anzeigen" zu sehen sein.




Jetzt mit PHP


1. Eine neue php Datei mit folgendem Inhalt erstellen. (z.B. eintragen.php).

2. Zuerst mit der Datenbank verbinden:

$link = mysqli_connect("Hostname", "Username", "Password", "DBname");
(Mit Ihren Zugangsdaten ersetzen)


3. Der $query weisen wir die sql-Befehle von vorhin zu:

$query = "

INSERT INTO wettertabelle
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('2013-11-25 00:10:00','11.9','87','999.4')

";


4. $query noch ausführen:

mysqli_query($link,$query);



Nochmals die komplette php Datei:

<?php

//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");


$query = "
INSERT INTO wettertabelle 
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('2013-11-25 00:10:00','11.9','87','999.4')
";


mysqli_query($link,$query);

?>



5. Nun die erstellte php Datei auf den Server übertragen und im Browser öffnen. (Achtung: Die Datei erzeugt keinerlei Ausgabe)



6. Zur Kontrolle in phpMyAdmin unter "Anzeigen" nachschauen ob der Eintrag geglückt ist.



Weiter mit Teil 3.1 - Archiv importieren (wswin)



Tutorial - Wetterdaten und Datenbanken - Teil 3.1 - Tabelle mit Archiv füllen

Teil 3.1 - Tabelle mit Archivdaten füllen


Wetterdaten einzeln von Hand einzupflegen, mag teilweise nötig sein, ist aber nicht sehr aufregend. Mit ein wenig php, kann man aber ganze Archive, ohne großen Aufwand in eine Datenbank übertragen.

Als Beispiel dient hier eine (Monats-) Export Datei von WsWin.


Datenquelle: Exportdateien von WsWin


Hier ein Beispiel einer (Monats)Exportdatei von WsWin:


(Beachten: Die Datenzeilen beginnen in meiner Datei erst mit Zeile 4)

Die php Datei:


Beachte: Es gibt einige Methoden für diese Aufgabe. Der hier aufgezeigte Weg ist vermutlich nicht der optimalste und schnellste, aber m.M. nach einfach nachzuvollziehen und anzupassen. Für einen einmaligen Import großer Datenmengen ist Performance auch nicht unbedingt so wichtig.


1. Die Import Datei


Zuerst die WsWin Export Datei auf den Server laden. (z.B. EXP201311A.CSV)



2. Die php Datei


Wir erstellen zuerst ein php Script, welches den Inhalt unserer WsWin Datei mit echo anzeigt.
Eine php Datei mit folgendem Inhalt erstellen, und auf den Server laden:

(Die Variablen $dateiname und $startzeile an Ihre Exportdatei anpassen).

<?php

//Dateiname der Importdatei
$dateiname = "EXP201311A.CSV";

//Anzahl Anfang Zeilen überspringen
$startzeile = 4;


//Die Import Datei öffnen
if (($handle = fopen("$dateiname", "r")) !== FALSE) 
{

  //zeilenzähler auf 0
  $counter = 0;

  //Jede Zeile abarbeiten
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
  {

    //counter rauf
    $counter++;

    //die ersten zeilen überspringen
    if($counter >= $startzeile) 
    {

      //das echo (ausgabe)
      echo $data[0].", ".$data[1].", ".$data[3].", ".$data[10]. ", ".$data[11]."<br>\n";
   

    }
   
  }

  //Import Datei schliessen
  fclose($handle);
}
?>


Wird diese php Datei im Browser geöffnet, sollten Inhalte der Import Datei etwa so angezeigt werden:

Beachte: Datum/Zeit Format und evtl. falsche Spalten

Vermutlich werden aber noch nicht alle benötigten Felder richtig ausgegeben und das Datumformat stimmt auch nicht.


3. Die richtigen Felder ausgeben


Die Spaltennummern sind aber vermutlich nicht bei allen Benutzern gleich wie bei mir.
Im echo Teil des Scripts wird das array "$data" ausgegeben. Die Zahlen in den [] Klammern dahinter, entsprechen der Reihenfolge der Spalten in der Importdatei.

echo $data[0].", ". $data[1].", ".$data[3].", ".$data[10]. ", ".$data[11]."<br>\n";

(Das Datum ist bei mir in Spalte [0], Zeit in Spalte [1], Temperatur in Spalte [3] etc.)


4. Das Datum formatieren:


Für die Datenbank benötigen wir das Datum im Format "2013-11-25 00:00"

Wir zerlegen das Datum und die Zeit der Import Datei und bauen diese in den Variablen $d1 wieder zusammen.

$splitDate = explode(".", $data[0]);  //Das Datum zerlegen 
$splitTime = explode(":", $data[1]);  //Die Zeit zerlegen


//Das Datum für Spalte datetime (2013-11-25 00:00)
$d1 = $splitDate[2]."-".$splitDate[1]."-".$splitDate[0]." ".$splitTime[0].":".$splitTime[1];


Das echo entsprechend anpassen. Zuerst das Datum $d1, dann wieder die Werte der Spalten:

echo $d1.", ".$data[3].", ".$data[10]. ", ".$data[11]. "<br>\n";


Unsere php Datei sollte nun folgenden Inhalt haben:

<?php

//Dateiname der Importdatei
$dateiname = "EXP201311A.CSV";

//Anzahl Anfang Zeilen überspringen
$startzeile = 4;


//Die Import Datei öffnen
if (($handle = fopen("$dateiname", "r")) !== FALSE) 
{

  //zeilenzähler auf 0
  $counter = 0;

  //Jede Zeile abarbeiten
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
  {

    //zeilenzähler rauf
    $counter++;

    //erst ab dieser Zeile ausgeben
    if($counter >= $startzeile) 
    {

   
   // datum und Zeit zerlegen und neu zusammenbauen
   $splitDate = explode(".", $data[0]);
   $splitTime = explode(":", $data[1]);

   $d1 = $splitDate[2]."-".$splitDate[1]."-".$splitDate[0]." ".$splitTime[0].":".$splitTime[1] ;
   
   

     //das echo (ausgabe)
     echo $d1.", ".$data[3].", ".$data[10]. ", ".$data[11]."<br>\n";
   

    }
   
  }

//Import Datei schliessen
fclose($handle);
}
?>


5. Die Ausgabe kontrollieren:




Jetzt sieht die Sache schon besser aus.


6. Vom echo zum SQL-Insert


Statt die Daten nur auszugeben, wollen wir sie jetzt in die Datenbank Tabelle importieren. Zuerst die Datenbank Verbindung am Anfang des Scripts.

//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");
(Mit Ihren Zugangsdaten ersetzen)


Wir erinnern uns an den SQL-Insert Befehl in Teil 3:

$query = "
INSERT INTO wettertabelle 
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('2013-11-25 00:05:00','11.9','87','999.4')
";


Die Wetterdaten nach "VALUES" mit unseren Variablen (aus dem echo) ersetzen:

$query = "
INSERT INTO wettertabelle 
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('$d1','$data[3]','$data[10]','$data[11]')
";

mysqli_query($link,$query);


7. Zusammenfassung:


Hier nochmals das ganze Script:

<?php

//Dateiname der Importdatei
$dateiname = "EXP201311A.CSV";

//Anzahl Anfang Zeilen überspringen
$startzeile = 4;


//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");


//Die Import Datei öffnen
if (($handle = fopen("$dateiname", "r")) !== FALSE) 
{

  //zeilenzähler auf 0
  $counter = 0;

  //Jede Zeile abarbeiten
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
  {

    //counter rauf
    $counter++;

    //erst ab dieser Zeile ausgeben
    if($counter >= $startzeile) 
    {

   
   // datum und Zeit zerlegen und neu zusammenbauen
   $splitDate = explode(".", $data[0]);
   $splitTime = explode(":", $data[1]);
   
   $d1 = $splitDate[2]."-".$splitDate[1]."-".$splitDate[0]." ".$splitTime[0].":".$splitTime[1] ;
   


   //das echo (ausgabe)
     echo $d1.", ".$data[3].", ".$data[10]. ", ".$data[11]."<br>\n";
   
   
   //die db query
   $query = "
   INSERT INTO wettertabelle 
   (`datetime`,`temp`,`hum`,`pressure`) 
   VALUES
   ('$d1','$data[3]','$data[10]','$data[11]')
   ";
   
   //db query noch ausführen
   mysqli_query($link,$query);
   

    }
   
  }

//Import Datei schließen
fclose($handle);
}
?>

Wird diese Datei nun im Browser geöffnet, wird jede Zeile einzeln in die Datenbank importiert. Sie können die neuen Einträge in phpMyAdmin unter "Anzeigen" kontrollieren.

(Die echo Ausgabe können Sie auch entfernen, Sie wird für den Import nicht benötigt.)





(Optional) Mehrere Dateien Importieren


Je nach Umfang der Archive kann es komfortabel sein, mehrere WsWin Monatsdateien auf einmal zu importieren. Sie können dazu das php Script leicht ändern, um ein ganzes Verzeichnis abzuarbeiten.

Vorsicht: Dieses, für große Datenmengen nicht optimale Script, verursacht für einige Sekunden eine hohe Server Auslastung. (Da es jede Zeile einzeln importiert!) Ich würde daher, nicht mehr als ein Jahr auf einmal importieren.


1. Wir ändern zuerst die Variable $dateiname in $dateiordner:

Folgender Bereich ...
//Dateiname der Importdatei
$dateiname = "EXP201311A.CSV";

... ersetzen mit: (Verzeichnisname anpassen):
//Ordner mit Importdateien
$dateiordner = "importdateien";




2. Mit scandir wird neu das Verzeichnis ausgelesen und die Dateinamen im array "$allFiles" abgelegt. Und dann mittels einer foreach-Schleife jede Datei einzeln abgearbeitet:

Folgender Bereich ...
//Die Import Datei öffnen
if (($handle = fopen("$dateiname", "r")) !== FALSE) 
{

.... ersetzen mit:
//verzeichnis scannen und dateinamen in array speichern
$allFiles = scandir($dateiordner);

//die foreach schleife
foreach ($allFiles as $dateiname) { 
 
//jetzt wie bisher die Datei öffnen
if (($handle = fopen("$dateiordner/$dateiname", "r")) !== FALSE) 
{
(Klammern nicht vergessen!)



3. Dann noch am Ende des Scripts, die foreach Schleife mit } schließen:

Folgender Bereich ...
//Import Datei schliessen
fclose($handle);
}

... ersetzen mit:
//Import Datei schliessen
fclose($handle);
}
}



Weiter mit Teil 3.2 - Livedaten importieren (wswin)

Tutorial - Wetterdaten und Datenbanken - Teil 3.2 - Tabelle mit Livedaten füllen

Teil 3.2 - Tabelle mit Livedaten füllen


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Diese Methode unterscheidet sich nur geringfügig vom Beispiel in Teil 3.1. Dieses sollte daher vor dieser Anleitung durchgespielt werden.

Möchte man die Tabelle mit unseren Wetterdaten aktuell halten, gibt es diverse Methoden. Hier sei nur eine erklärt.

Es ist anzumerken das die folgende Methode eine Software benötigt welche Dateien Zeitgesteuert über z.B. FTP übertragen kann. Zudem werden cronjobs benötigt.

Um ein möglichst kleines Transfervolumen erreichen zu können, sollte die Software zudem in der Lage sein, bei erfolgreicher Übertragung die Datei zu löschen.

Leider kann ich diesbezüglich keine Empfehlung abgegeben. Ich für meine Zwecke, habe ein kleines Tool programmiert, welches die oben genannten Aufgaben übernimmt. Evtl. kann ich diese Software später freigeben, falls sich hier keine alternative findet. (Kommentare dazu ?)



1. Voraussetzungen


1. Zeitgesteuerte Übertragung von Dateien

2. Cronjobs


2. Datenquelle


Als Datenquelle eignet sich ws_newdata.csv von WsWin im Besonderen. Durch die Verwendung von dieser Datei lassen sich auch Übertragungsfehler überbrücken. ws_newdata.csv wird ja von WsWin ständig mit den neusten Datenreihen gefüllt. Löscht man diese Datei, wird automatisch eine neue erstellt und wieder weiter aufgefüllt.


ws_newdata.csv von WsWin



(Es können aber auch benutzerdefinierte Dateien von WsWin verwendet werden.) 


3. Datei übertragen


Die Datei, hier ws_newdata.csv, wird auf den Server übertragen. Die Intervalle können Sie prinzipiell frei wählen, ich gehe hier von 5 Minuten aus. Da diese Datei immer grösser wird, empfiehlt es sich, diese nach einer erfolgreichen Übertragung zu löschen. Somit enthält die Datei immer nur die noch nicht übertragenen Zeilen.

Fällt die Übertragung einmal aus, Puffert WsWin die Zeilen in der ws_newdata.csv bis wieder eine erfolgreiche Übertragung zustande kommt.



4. Die Datei importieren


Wir verwenden das selbe Script wie in Teil 3.1. Speichern wir es in einer neuen php Datei erneut ab

In dieser neuen php Datei, müssen wir jedoch noch den Dateinamen (der zu importierenden Datei), die Startzeile und evtl. die Spaltennummern in der Query anpassen:


//Dateiname der Importdatei
$dateiname = "ws_newdata.csv";

//Anzahl Anfang Zeilen überspringen
$startzeile = 3;


Auch die Spaltennummern in der query auf die richtigen Werte überprüfen:
$query = "
INSERT INTO wettertabelle 
(`dateid`,`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('$d1','$data[3]','$data[10]','$data[11]')
";

mysqli_query($link,$query);



5. Die Datei löschen (Optional)


Wir haben sichergestellt das die Tabelle keine doppelten Einträge aufnimmt. Dennoch sollten wir verhindern, dass importierte Dateien nicht noch einmal aufgerufen werden. Wir löschen also nach einem erfolgreichem Import die ws_newdata.csv

//Import Datei schließen
fclose($handle);
unlink('ws_newdata.csv');
?>


6. cronjob/crontab


Unsere neue php Importdatei, muss nun in Intervallen aufgerufen/geöffnet werden.
Wir erstellen daher einen Cronjob, welcher die vorhin erstellte .php Datei, in Intervallen aufruft. Dabei muss sichergestellt sein, das jede Datei importiert wird, bevor jeweils eine neue eintrifft. Wir überprüfen ja die Übertragung, aber nicht das eigentliche Eintragen. Ich führe daher meine Datei jede Minute aus.

Beachte: Die Erstellung von Cronjobs ist nicht bei jedem Host Provider gleich. Kontaktieren Sie bei Unklarheiten Ihren Provider.

Hier ein Beispiel eines cronjobs:



Der Befehl im Detail:
/usr/bin/php5 /home/www/webxx1/html/wetterseite/import/import-live.php >& /dev/null
(Dateiname und Verzeichnis anpassen)


keine Cronjobs möglich ?


Es gibt diverse Software und auch Webdienste, welche das Aufrufen der Datei in Intervallen übernehmen können. Ich möchte dazu aber keine Empfehlung abgeben.






Tutorial - Wetterdaten und Datenbanken - Teil 4 - Datenbank Abfragen

Teil 4 - Datenbank Abfragen


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


In diesem Teil werde ich einige Datenbank Abfragen aufzeigen.


Grundlagen:


In Teil 3 haben wir den sql-Befehl "INSERT INTO" verwendet, um Daten in die Tabelle einzufügen. Um Daten aus der Datenbank "herauszuholen", verwenden wir nun den Befehl "SELECT".

Hier ein Beispiel eines einfachen SELECT-Befehl:

SELECT temp FROM wettertabelle

(Diese Abfrage würde sämtliche Zeilen der Spalte "temp" aus der Tabelle "wettertabelle" ausgeben.)


Ein erster Versuch mit phpMyAdmin:


Wir verwenden für unseren ersten Versuch die SQL Eingabe von phpMyAdmin, und geben die Beispiel Abfrage ein:


1. Testen Sie folgende Abfrage:

SELECT temp FROM wettertabelle


sql-Befehl in phpMyAdmin

Sie sehen nach der Ausführung, dass MySQL die Spalte "temp" ausgegeben hat:





2. Oft werden mehrere Spalten einer Tabelle benötigt. Versuchen Sie mit diesem SQL-Befehl zusätzlich die Spalte "datetime" auszugeben.


SELECT datetime, temp FROM wettertabelle


3. Sie können auch einfach alle Spalten ausgeben lassen:

SELECT * FROM wettertabelle