Raspberry Wetterstation

Projekt: Raspberry Wetterstation

Eine drahlose Wetterstation mit Termperatur-, Luftdruck-, Luftfeuchtigkeits-, Regensensor und Windmesser per USB an demnRaspberry Pi angeschlossen, ermöglicht eine regelmäßige Auswertung der aufgezeichneten Daten mit automatischer Aufbereitung als Webseite mit Grafiken und Übertragung auf den Webspace per FTP.

VERSIONS-HINWEIS:

Dies Anleitung wurde im Herbst 2013 erstellt und bezieht sich auf die zu diesem Zeitpunkt zur Verfügung stehenden Versionen. Es ist empfehlenswert, auf den entsprechenden Internetseiten immer nach der aktuellen Version der Software zu suchen!!!

 


 Inhaltsverzeichnis


 

Infos

Grundlage ist das Python-Softwarepaket pywws (http://jim-easterbrook.github.com/pywws/), das mit einige Wetterstationen zusammenarbeitet. Laut Homepage mit Elecsa AstroTouch 6975, Watson W-8681, WH-1080PC, WH1080, WH1081, WH3080 und anderen, die mit der Software EasyWeather kompatibel sind.

Für mein Projekt habe ich bei www.conrad.at das Modell „Funk-Wetterstation mit USB & Touchscreen“ bestellt (Link), das offenbar dem Modell WH1080 entspricht:

672861_BB_00_FB.EPS_1000

Ausgehend von einer aktuellen Raspian-Distribution habe ich mich bei der Installation an die Anleitung auf der pywws-Seite gehalten.

Die folgenden Befehle können auf der Text-Konsole, in einem Terminal-Fenster der grafischen Benutzeroberfläche oder in einer ssh-Session (z.B. mit putty) eingegeben werden.

Wetterstation anschließen

Bevor die Wetterstation mit dem RaspberryPi verwendet werden kann, muss diese natürlich einmal ordnungsgemäß funktionieren. Dazu siehe Bedienungsanleitung.

Nach dem Anschließen der Wetterstation per USB-Kabel an den RaspberryPi kann man mit den Befehlen lsusb und dmesg überprüfen, ob das Gerät ordnungsgemäß erkannt wurde, sowie die gerätespezifischen Parameter wie Hersteller-ID und Produkt-ID auslesen.

WH1080_lsusb_dmesg

Vorbereitende Installationen

Falls noch nicht vorhanden, müssen die Pakete aus dem Raspian Repository nachinstalliert werden:

  • git (Quellcode-Verwaltungswerkzeug)
  • python-dev (Entwicklerwerkzeuge und Bibliotheken für die Programmiersprache Python)
  • gnu-plot (kommandozeilengesteuertes Plot-Programm für Diagramme)
sudo apt-get install git
sudo apt-get install python-dev
sudo apt-get install gnuplot

Als Voraussetzung benötigen wir folgende Pakete, die nicht Teil des Repositories sind, die wir also extra herunterladen und installieren müssen. Wahrscheinlich müssen die Versionsnummern an die aktuellen Versionen angepasst werden, siehe dazu die angegebenen Web-Adressen:

  • Cython (C-Erweiterung für Python)
  • libusb (C-Bibliothek für den Zugriff auf USB-Geräte)
  • cython-hidapi (Programmierschnittstelle für den USB-Zugriff ohne speziellen Gerätetreiber)

Um die im Folgenden heruntergeladenen Dateien zwischenzuspeichern, empfehle ich im Home-Verzeichnis einen eigenen Ordner downloads anzulegen:

cd ~
mkdir downloads
cd downloads

Cython (http://cython.org/ >> Downloads)

wget http://www.cython.org/release/Cython-0.19.1.tar.gz
tar xvzf Cython-0.19.1.tar.gz
cd ~/downloads/Cython-0.19.1
sudo python setup.py install

libusb (http://sourceforge.net/projects/libusb/files/)

wget http://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-1.0.9/libusb-1.0.9.tar.bz2
tar xvjf libusb-1.0.9.tar.bz2
cd ~/downloads/libusb-1.0.9
./configure
make
sudo make install

cython-hidapi (https://github.com/gbishop/cython-hidapi)
Da ist ein bisschen mehr zu tun:

git clone https://github.com/gbishop/cython-hidapi.git
cd ~/downloads/cython-hidapi

Zuerst sind ein paar Änderungen in der Datei setup.py vorzunehmen, am besten mit dem Editor nano, um die Pfade an die Raspian-Distribution anzupassen.

nano setup.py

Die folgenden Zeilen müssen mit einem #-Zeichen auskommentiert werden:

#os.environ['CFLAGS'] = "-I/usr/include/libusb-1.0"
#os.environ['LDFLAGS'] = "-L/usr/lib/i386-linux-gnu -lusb-1.0 -ludev -lrt"

Dafür werden die folgenden Zeilen ergänzt:

os.environ['CFLAGS'] = "-I/usr/local/include/libusb-1.0"
os.environ['LDFLAGS'] = "-L/usr/lib/arm-linux-gnueabihf -lusb-1.0 -ludev -lrt"

Im nano-Editor sieht das folgenermaßen aus:

cython-hidapi-setup_py

Mit Strg-X wird der nano-Editor beendet, dabei muss man das Speichern bestätigen.

Eine Datei muss noch an die richtige Stelle kopiert werden:

sudo cp /lib/arm-linux-gnueabihf/libudev.so.0 /usr/lib/arm-linuxgnueabihf/libudev.so

Und dann kann das cython-hidapi-Archiv installiert werden:

sudo python setup.py install

Installation von pywws

Jetzt kommen wir zur Installation des eigentlichen Programmes zur Kopplung des RaspberryPi mit der Wetterstation und zur Verarbeitung der Daten.

Die aktuelle Version von pywws findet man unter http://jim-easterbrook.github.com/pywws/.

cd ~/downloads
wget https://pypi.python.org/packages/source/p/pywws/pywws-13.06_r1023.tar.gz
tar xvzf pywws-13.06_r1023.tar.gz
cd ~
mkdir weather
mv pywws-13.06_r1023/ /home/pi/weather

Installation:

cd ~/weather
python setup.py build
sudo python setup.py install

Spätestens jetzt ist es an der Zeit, die Wetterstation per USB anzuschließen, was ja hoffentlich schon geschehen ist. Denn damit können wir unsere Installation einem ersten Test unterziehen:

cd ~/weather/pywws
sudo python -m pywws.TestWeatherStation

Ergebnis ist eine hexadezimale Zahlenkolonne:

TestWeatherstation_py

Damit nicht alle Skripts zum Zugriff auf das USB-Gerät als Administrator, also mit vorangestellten sudo, ausgeführt werden müssen, müssen wir noch die Rechte entsprechend anpassen. Im ersten Schritt legen wir eine Systemgruppe mit der Bezeichnung weather an, dem der Benutzer pi angehören soll.

sudo addgroup --system weather
sudo adduser pi weather

Dieser Gruppe soll der Zugriff auf das USB-Gerät der Wetterstation erlaubt werden. Wir benötigen dazu Product- und Vendor-ID, die wir mit dem Befehl dmesg oder lsusb ermitteln (siehe oben).

WH1080_lsusb_dmesg

Bei meiner Wetterstation lautet die Vendor-ID 1941 und die Product-ID 8021. Damit können wir eine neue Regel anlegen, die als Textdatei im Ordner /etc/udev/rules.d liegt:

sudo nano /etc/udev/rules.d/39-weather-station.rules

Dort wird folgendes eingetragen, wobei eben Product- und Vendor-ID eventuell anzupassen sind:

ACTION!="add|change", GOTO="rpi_end"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1941", ATTRS{idProduct}=="8021", GROUP="weather"
LABEL="rpi_end"

39-weather-station.rules

Zur Erinnerung: mit Strg-X speichern und das Speichern bestätigen.

Nun ist es einmal Zeit für einen Reboot:

sudo reboot

Danach sollten sich die Skripte als „normaler“ Benutzer pi aufrufen lassen, z.B.:

python -m pywws.TestWeatherStation

Damit ist die grundsätzliche Installation der Wetterstation und der Software pywws abgeschlossen. Jetzt gehen wir daran, diese noch einzurichten und an unsere Anforderungen anzupassen.

Logging-Intervall der Wetterstation einstellen

Die Wetterstation zeichnet in der Voreinstellung alle 30 Minuten die Wetterdaten im internen Speicher auf, damit lassen sich die Daten über 11 Wochen halten. Dieses Intervall lässt sich mit dem folgenden Befehl auf 5 Minuten verkürzen, womit immer noch die Daten für 2 Wochen im internen Speicher verbleiben.

python -m pywws.SetWeatherStation -r 5

Einrichten von pywws

Zuerst benötigen wir noch ein paar Verzeichnisse, die anzulegen sind, falls noch nicht vorhanden:

cd ~/weather
mkdir templates
mkdir graph_templates
mkdir data
mkdir temp

Danach können wir erstmalig die Daten von der Wetterstation auf den RaspberryPi holen:

cd ~/weather/pywws
python -m pywws.LogData -vvv ~/weather/data

Danach kann man den Inhalt des Verzeichnisses ~/weather/data/raw begutachten, in den die Daten aus der Wetterstation kopiert wurden.

cd ~/weather/data/raw
ls

Beim Aufrud des letzten Python-Scripts wurden auch eine Konfigurationsdatei namens weather.ini erstellt die wir nun mit dem nano-Editor bearbeiten:

cd ~/weather/data
nano weather.ini

 nano-weather_ini

Im ersten Abschnitt [config] lassen wir das meiste unverändert, wir ergänzen nur eine Zeile mit day end hour = 0, damit die Werte immer im Tagesintervall von 00:00 bis 00:00 berechnet werden, und nicht wie in UK üblich von 09:00 bis 09:00. Die ersten Zeilen dieses Blockes in der Datei weather.ini sollten dann so aussehen:

[config]
ws type = 1080
logdata sync = 1
day end hour = 0

Im Abschnitt [paths] müssen wir die Pfadangaben an unserer Installation anpassen:

[paths]
work = /home/pi/weather/temp/
templates = /home/pi/weather/templates/
graph_templates = /home/pi/weather/graph_templates/
local_files = /home/pi/weather/results/

Nach der Änderung wieder mit Strg-X beenden und das Speichern bestätigen.

Einrichten der periodisch auszuführenden Aufgaben

Grundsätzlich gibt es zwei verschiedene Methoden, wie pywws die Daten auf eine Website schickt. Bei der Methode „hourly“, die ich gewählt habe, wird über einen cron job regelmäßig das Script pywws-hourly.py aufgerufen, entweder stündlich, wie der Name besagt, oder in einem anderen kürzeren Intervall, wobei diese mindestens doppelt so lange sein muss, wie das Logging-Intervall der Wetterstation (bei mir also 10 min). Das Skript holt die aktuellen Daten von der Wetterstation, verarbeitet diese Daten, generiert HTML-Seiten und Diagramm und lädt diese anschließend per FTP hoch.

Eine zweite Methode names „live“ wäre ein nach dem Systemstart gestartetes und dann ständig laufendes Skript pywws-livelog.py, das alle 48 Sekunden Daten aus der Wetterstation ausliest und diese verarbeitet.

Für das Skript pywws-hourly.py muss man in der Datei weather.ini die folgenden Sektionen für Aufgaben nach unterschiedlichen Zeitintervalle befüllen:

  • [logged] … bei jedem Skriktaufruf durchzuführen
  • [hourly] … stündlich auszuführende Aufgaben
  • [12 hourly] … alle 12 Stunden
  • [daily] … alle 24 Stunden

In jeder dieser Sektionen gibt es drei Einträge, die in diesen Intervallen verarbeitet werden:

  • services = [    ] … Upload zu Wetterdiensten per http, diese Dienste müssen zuerst konfiguriert und registriert sein (ich habe diese Services nicht in Verwendung.)
  • plot = [    ] … Erstellen von Diagrammen auf Basis und XML-Vorlagen für gnuplot, die im Ordner ~/weather/graph_templates zu finden sind.
  • text = [    ] … Erstellen von HTML- oder anderen Textdateien auf Basis  von Vorlagen, die im Ordner ~/weather/templates zu finden sin.

Im Normalfall möchte man die Ergebnisse dieser Einträge in plot und text auf einen Webspace hochladen, was mit der Sektion [ftp] konfiguriert wird:

[ftp]
local site = False
secure = False
site = ftp.server.name.at
user = benutzername
password = passwort
directory = pfad/auf/dem/webserver

Am besten bearbeitet man diese Konfigurationsdatei mit dem Editor nano:

cd ~/weather/data
nano weather.ini

Wichtig ist, dass es zu dem Eintrag unter plot auch eine entsprechende Vorlagendatei im Ordner ~/weather/graph_templates geben muss, und zu jedem Eintrag in text eine Vorlagendatei im Ordner ~/weather/templates.

Bei meiner Konfiguration sieht dieser Teil der weather.ini so aus:

nano-weather_ini-2

Jetzt müssen wir dieses Skript pywws-hourly.py nur noch aufrufen, das bei der Installation im Verzeichnis /usr/local/bin abgelegt wurde, und daher von jedem Ordner aus gestartet werden kann. Es benötigt nur mehr die Pfadangabe zu den Wetterdaten und optional einen Parameter -v, -vv oder -vvv, der den Umfang der Rückmeldungen steuert.

pywws-hourly.py -v ~/weather/data

Zu Testzwecken sollte man dieses Skript zuerst händisch auf der Kommandozeile aufrufen, um eventuelle Fehlermeldung zu erhalten.

Vorlagen für automatisch erstelle HTML- und andere Text-Dateien

Wie schon oben beschrieben wird für jeden Eintrag in der weather.ini zu text im jeweiligen Intervall eine HTML- oder eine andere Textdatei erstellt. Dazu muss sich im Ordner ~/weather/templates eine entsprechemde Vorlage befinden. Das Ergebnis wird bei korrekter Syntax per FTP auf die Website hochgeladen. Im Ordner ~/weather/examples/templates findet man Beispieldateien für diese Vorlagen, die man an die eigenen Bedürfnisse anpasst.

Hier ein Beispiel aus meiner Konfiguration, das sich leicht aus einer solchen Beispieldatei erstellen lies, insbesondere Sprache und Einheiten musste ich anpassen:

<h3>Die letzten 6 Stunden</h3>
<table id="t6hrs" class="tab">
  <tr>
    <th colspan="2" rowspan="2">Zeit</th>
    <th rowspan="2">Temp</th>
    <th rowspan="2">gefühlt</th>
    <th rowspan="2">rel. LF</th>
    <th colspan="3">Wind</th>
    <th rowspan="2">Niederschlag</th>
    <th colspan="2" rowspan="2">Luftdruck</th>
  </tr>
  <tr>
    <th>Richtung</th>
    <th>Mittel</th>
    <th>Spitzen</th>
  </tr>
#timezone local#
#roundtime True#
#hourly#
#jump 0#
#loop 7#
<tr>
<td>#idx "%d.%m.%Y" "" "[None, x][x.hour == 0 or loop_count == 7]"#</td>
<td>#idx "%H:%M <small>%Z</small>"#</td>
<td>#temp_out "%.1f <small>°C</small>" "-"#</td>
<td>#calc "apparent_temp(data['temp_out'], data['hum_out'], data['wind_ave'])" "%.1f <small>°C</small>"#</td>
<td>#hum_out "%d<small>%%</small>"#</td>
<td>#wind_dir "%s " "-" "wind_dir_text[x]"#</td>
<td>#wind_ave "%.0f <small>km/h</small>" "-" "wind_kmph(x)"#</td>
<td>#wind_gust "%.0f <small>km/h</small>" "" "wind_kmph(x)"#</td>
<td>#calc "data['rain'] - prevdata['rain']" "%.1f <small>mm</small>"#</td>
<td>#rel_pressure "%.1f <small>hPa</small>"#</td>
<td>#pressure_trend "%s" "" "pressure_trend_text(x)"#</td>
</tr>
#jump -1#
#endloop#
</table>

Im Prinzip handelt es sich dabei meist um Fragmente einer HTML-Datei, in die spezielle Makrobefehle, Felder und Funktionen eingebettet sind, die dann mit Daten aus der Wetterstation befüllt werden. Die Syntax wird auf http://jim-easterbrook.github.io/pywws/doc/en/html/api/pywws.Template.html erklärt.

Vorlagen für automatisch erstellte Grafiken

Auch für jeden Eintrag in der weather.ini zu plot im jeweiligen Intervall muss eine Vorlagendatei in ~/weather/graph_templates existieren. Allerdings handelt es sich dabei um Vorlagen für XML-Dateien, woraus das Programm mit Hilfe von gnuplot Diagramme erstellt. Bei der Verarbeitung werden daraus jpg- oder png-Grafiken, die wieder per FTP hochgeladen werden.

Hier ein Beispiel aus meiner Konfiguration, das wieder aus einer Beispieldatei entstanden ist, für das ich insbesonder Sprache und Einheiten anpassen musste:

<?xml version="1.0" encoding="ISO-8859-1"?>
<graph>
  <size>800, 1000</size>
  <duration>hours=24</duration>
  <xtics>2</xtics>
  <xformat>%H:%M</xformat>
  <dateformat></dateformat>
  <plot>
    <yrange>-10, 35</yrange>
    <source>raw</source>
    <subplot>
      <colour>1</colour>
	  <style>line 2</style>
      <title>Temperatur (°C)</title>
      <ycalc>data['temp_out']</ycalc>
    </subplot>
    <subplot>
      <colour>3</colour>
      <ycalc>dew_point(data['temp_out'], data['hum_out'])</ycalc>
      <title>Taupunkt (°C)</title>
    </subplot>
  </plot>
  <plot>
    <yrange>0, 100</yrange>
    <ylabel>%</ylabel>
    <source>raw</source>
    <subplot>
      <colour>2</colour>
      <ycalc>data['hum_out']</ycalc>
      <title>rel. Luftfeuchtigkeit (%)</title>
    </subplot>
  </plot>
  <plot>
    <title>Windgeschw. (km/h)</title>
    <yrange>0, 30</yrange>
    <source>raw</source>
    <subplot>
      <colour>4</colour>
      <ycalc>data['wind_gust']</ycalc>
      <title>Spitze</title>
    </subplot>
    <subplot>
      <colour>3</colour>
      <ycalc>data['wind_ave']</ycalc>
      <title>Durchschnitt</title>
    </subplot>
  </plot>
  <plot>
    <yrange>0, 5</yrange>
    <source>hourly</source>
    <subplot>
      <colour>5</colour>
      <style>box</style>
      <xcalc>data['idx'].replace(minute=30, second=0)</xcalc>
      <ycalc>data['rain']</ycalc>
      <title>Niederschlag 1h (mm)</title>
    </subplot>
  </plot>
  <plot>
    <source>hourly</source>
    <subplot>
      <colour>2</colour>
      <ycalc>data['rel_pressure']</ycalc>
      <title>Luftdruck (hPa)</title>
    </subplot>
    <yrange>960, 1050</yrange>
  </plot>
</graph>

Im Ordner ~/weather/examples/graph_templates findet man diese Beispieldateien für die XML-Vorlagen, die man an die eigenen Bedürfnisse anpassen kann Eine Erläuterung zur Syntax gibt es unter http://jim-easterbrook.github.io/pywws/doc/en/html/api/pywws.Plot.html oder für Windrosen-Diagramme unter http://jim-easterbrook.github.io/pywws/doc/en/html/api/pywws.WindRose.html.

Automatischer Aufruf des Skripts pywws-hourly.py

Während man die Vorlagendateien anpasst sollte man das folgende Skript zu Testzwecken händisch auf der Kommandozeile aufrufen, um eventuelle Fehlermeldung zu erhalten.

pywws-hourly.py -vvv ~/weather/data

Erst wenn alles klappt, können wir dieses Skript in regelmäßigen Abstände mit Hilfe des cron-Daemons aufrufen. Dazu müssen wir einen entsprechenden cron job als Zeile in der Datei crontab (zu finden im Ordner /etc) eintragen:

0,10,20,30,40,50 * * * * pi pywws-hourly.py /home/pi/weather/data/

Meine crontab sieht folgendermaßen aus:

crontab_pywws

Damit wird alle 10 min dieses Skript aufgerufen, die Daten zu Grafiken und HTML-Dateien verarbeitet und hochgeladen.

Einbinden in die Webseite

Wenn bis hierher alles geklappt hat, dann landen die erstellen HTML-Fragment-Dateien und die erstellten PNG-Grafiken per FTP auf dem Webserver in einem angegebenen Verzeichnis (bei mir data).

Ich habe die HTML-Fragmente mit Hilfe der include-Funktion von PHP in die vorgesehenen HTML-Seite(n) eingefügt. Ob man dieseauf einer Seite oder auf mehreren Seiten verteilt einbindet, wird je nach Website zu entscheiden sein.

include('data/6hrs.txt');

Für das Einbinden der Grafiken reicht zwar grundsätzlich der entsprechende HTML-Befehl:

<img src="data/7days.png" alt="" title=""  />

wobei der Cache des Browser bei eventuellen Änderungen der Grafikdateien dafür sorgt, dass noch alte Versionen der Grafikdateien angezeit werden. Ich hab zu diesem Zweck eine PHP-Funktion geschrieben, die an die URL zur Grafik einen Timestamp der Dateiänderung anhängt:

<?php
function img_include($fne)
{
	if (file_exists($fne))
	{
		$fntime=filemtime($fne);
		return "$fne?t=$fntime";
	}
	else
	return "$fne";
}
?>

Im Image-Tag wird dann diese Funktion aufgerufen:

<img src="<?php img_include('data/7days.png'); ?>" alt="Die letzen 7 Tage" title="Die letzen 7 Tage"  />

Damit sollte das Problem behoben sein und immer die aktuellste Version der Grafik angezeigt werden.

Das Ergebnis meiner Konfiguration ist hier zu sehen: www.ueberall.at/wetter

Dieser Beitrag wurde unter Raspberry Pi veröffentlicht. Setze ein Lesezeichen auf den Permalink.