Dieser Artikel ist in Bezug auf Weather Unterground leider überholt. Die Firma bietet keinen kostenlosen Webservice mehr an.
Hier geht es zu einer Alternative mit einer anderen kostenfreien API.
In meine Webcam möchte ich einen Wetterbericht einblenden. Außerdem will ich das Pi Camera Modul so aussteuern, dass Aufnahmen nachts mit längerer Belichtung durchgeführt werden. Die normale Kameraautomatik liefert sonst nur trübe oder schwarze Bilder.
Einen Weg, sich kostenlos mit korrekten Wetter und Astrodaten zu Sonnenaufgang und Untergang zu versorgen, zeige ich euch hier:
Es gibt eine ganze Reihe von Webdiensten, die einem die Wetterdaten etc. zur Verfügung stellen. Manchmal auch kostenlos. Ich verwende hier den amerikanischen Webservice Weather Underground, der bei gemäßigter Nutzung kostenlos ist und tatsächlich ein weltumspannendes Netzwerk an Wetterstationen betreibt. Zudem kann deren API sowohl XML als auch JSON. Ich habe mich für JSON entschieden, da das deutlich flexibler ist, als XML. Englischkenntnisse sind hilfreich, aber davon kann man wohl ausgehen, wenn sich jemand mit Raspberry Pi, Debian Linux und Python beschäftigt.
Anmerkung: In letzter Zeit war der Service eher unzuverässig und oft nicht erreichbar. Jetzt hat sich ergeben: Weather Unterground schickt seine API in den Ruhestand. Das heißt, ab dem 31.12.2018 wird diese Anleitung und alle Anwendungen, die auf der API basieren, nicht mehr funktionieren. Neue Accounts kann man seit ca. Mai 2018 nicht mehr anlegen. Angeblich will Weather Underground ein Angebot an alle Entwickler machen. Lassen wir uns überraschen… Ich bin jetzt dabei, meine Webcam auf eine andere API umzustellen. Anschließend werde ich darüber einen neuen Artikel schreiben.
Schritt 1: Account anlegen
Surft zu http://www.wunderground.com/weather/api/ und klickt den Button "Sign up for free" an.
Geht durch den Registrierungsdialog und tragt die abgefragten Daten ein. Beim "Pricing" Schema reicht fürs Erste der "Stratus Plan" und die Option "Developer" – die ist kostenlos, wenn man nicht mehr als 500 Abfragen pro Tag macht. Am Ende erhaltet ihr einen Schlüssel [key] der Art e5ed74b1ac3758b1 mit dem ihr euch bei künftigen Abfragen ausweist.
Schritt 2: Webservice ansprechen
Irgendwie müssen die Daten aus dem Webservice in Python eingelesen werden. Dafür gibt es in Python Standardmethoden. Mit der standardmäßig vorhandenen urllib2 Library habe ich mich allerdings etwas schwer getan. Die neuere Library "Requests" ist meines Erachtens leichter zu bedienen, enthält netterweise auch die benötigten JSON Funktionen, muss aber erst noch installiert werden. Doch keine Angst, die Installation ist unkompliziert:
Requests is an elegant and simple HTTP library for Python, built for human beings.
Der Entwickler empfiehlt, das Paket mit pip
zu installieren:
sudo pip install requests
Wenn es zu einer Fehlermeldung kommt, weil pip
noch nicht installiert ist, dann muss das pip
Paket ebenfalls installiert werden – am besten gleich noch sicherstellen, dass ein weiteres wichtiges Entwicklerpakets mit installiert wird:
sudo apt-get install python-pip python-dev
anschließend requests
wie oben dargestellt installieren.
Wer tiefer einsteigen will: weitere Info gibts bei Python Requests.
Damit ist euer Pi für die folgenden Schritte gerüstet.
Schritt 3: JSON verarbeiten
Bezüglich der Weather Underground angebotenen Daten und deren Struktur gibt es eine gute Dokumentation auf deren Site http://www.wunderground.com/weather/api/d/docs.
a: Das JSON Format anschauen
Um das Prinzip zu verdeutlichen, nehmen wir uns für den Anfang die Astronomy Daten vor, das ist eine etwas kleinere Datei.
Gebt zuerst einmal folgende Zeile in euren Browser ein:
1 |
http://api.wunderground.com/api/DeinWundergroundKey/astronomy/lang:DL/q/48.140508,11.556856.json |
anstatt DeinWundergroundKey nehmt ihr natürlich euren eigenen, vorhin generierten Key. Die Zahlen am Ende sind die Geokoordinaten für den Ort, für den ihr die heutigen Astrodaten wissen wollt – in diesem Beispiel ist es der Hauptbahnhof München.
Hinweis: Geokoordinaten bekommt ihr heraus, indem ihr bei Google Maps die gewünschte Gegend anzeigt und dann einen Rechtsklick auf die Stelle macht, deren Koordinaten ihr wissen wollt. Dann "was ist hier" auswählen. Oben links werden dann die Geokoordinaten schon im richtigen Format angezeigt. Diese einfach mit Cut&Paste übernehmen und in die Codezeile eintragen. Dabei nicht vergessen, das Leerzeichen nach dem Komma zu entfernen.
Mehrsprachig ist der Dienst auch. Die Sprachkürzel sind allerdings deren Eigenschöpfung, anstatt der ISO Norm z.B. DE für Deutschland wird DL verwendet. Für München sähe der String z.B. so aus:
1 |
http://api.wunderground.com/api/DeinWundergroundKey/astronomy/lang:DL/q/48.140508,11.5568562.json |
Das Ergebnis für den 3. Januar 2015 ist dann wie folgt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
{ "response": { "version":"0.1", "termsofService":"http://www.wunderground.com/weather/api/d/terms.html", "features": { "astronomy": 1 } } , "moon_phase": { "percentIlluminated":"98", "ageOfMoon":"13", "phaseofMoon":"Zweites Viertel", "hemisphere":"North", "current_time": { "hour":"18", "minute":"28" }, "sunrise": { "hour":"8", "minute":"04" }, "sunset": { "hour":"16", "minute":"30" } }, "sun_phase": { "sunrise": { "hour":"8", "minute":"04" }, "sunset": { "hour":"16", "minute":"30" } } } |
Diese wunderschön strukturierten Informationen können wir in Python jetzt ganz elegant verarbeiten.
Exkurs: Eine noch besser lesbare Struktur erhaltet ihr mit meinem Lieblingseditor Notepad++, der allerdings noch über den Plugin Manager die Erweiterung "JSON Viewer" bekommen muss. Notepad++ gibts kostenlos im Internet. Tante Google fragen.
Dazu den Menüpunkt Erweiterungen auswählen und dann auf Plugin Manager gehen. Dort dann unter dem Tab Available den JSON Viewer auswählen und auf Install klicken.
Zum Ansehen, den JSON String aus dem Browser in ein Bearbeitungsfenster von Notepad++ reinkopieren, mit der Maus komplett markieren und dann unter Erweiterungen – JSON Viewer – Format JSON anklicken. Et voilà, JSON ist so noch besser anzusehen.
Ganz toll ist auch der Online JSON Editor bei http://jsoneditoronline.org/
Firefox Quantum (Version 57 und höher) kann ebenfalls eine wunderschöne JSON Darstellung.
b: Ein JSON Ojekt erzeugen
In die erste Zeile unseres Progrämmchens kommt das "Shebang" für Python. Dann noch die Codierung für UTF-8
1 2 |
!/usr/bin/python #coding=UTF-8 |
Anschließend wird die soeben installierte Requests Bibliothek importiert
1 |
import requests |
Zunächst einmal müssen wir den Webservice mit dem oben ausprobierten Aufruf ansprechen und den gelieferten Output einem Python Objekt [hier: r] zuweisen.
1 |
r = requests.get("http://api.wunderground.com/api/DeinWundergroundKey/astronomy/lang:DL/q/48.140508,11.5568562.json") |
Damit kann man allerdings herzlich wenig anfangen. Das Objekt muss noch als JSON String geparsed (d.h. zergliedert) werden:
data = r.json()
data
ist ein Python Dictionary Objekt und enthält den ganzen JSON String , nicht besonders schön anzusehen, aber komplett.
Hier noch das ganze Code Snippet:
1 2 3 4 5 6 7 8 9 10 |
#!/usr/bin/python #coding=UTF-8 import requests # get astro data from location as JSON r = requests.get("http://api.wunderground.com/api/DeinWondergroundKey/astronomy/lang:DL/q/48.140508,11.556856.json") data = r.json() # data contains the parsed JSON string print data # just to check that it worked r.close() # good practice to close files after use |
und hier der Output davon:
1 |
{u'moon_phase': {u'current_time': {u'minute': u'09', u'hour': u'17'}, u'phaseofMoon': u'Vollmond', u'ageOfMoon': u'15', u'hemisphere': u'North', u'sunset': {u'minute': u'34', u'hour': u'16'}, u'percentIlluminated': u'100', u'sunrise': {u'minute': u'03', u'hour': u'8'}}, u'sun_phase': {u'sunset': {u'minute': u'34', u'hour': u'16'}, u'sunrise': {u'minute': u'03', u'hour': u'8'}}, u'response': {u'termsofService': u'http://www.wunderground.com/weather/api/d/terms.html', u'version': u'0.1', u'features': {u'astronomy': 1}}} |
c: Einzelne JSON Elemente ansprechen
Um beispielsweise direkt die Stunde des Sonnenaufgangs anzusprechen und in eine Variable hineinzuschreiben, muss man sich ganz einfach durch die Hierarchie des Directory Elements hangeln. An oberster Stelle kommt sun_phase
dann sunrise
dann hour
.
In Python ausgedrückt sieht das so aus:
sunrise_hour = data['sun_phase']['sunrise']['hour'] #Sunrise Hour
Analog kann man alle anderen Werte einlesen. z.B. die Mondphase
mphase = data['moon_phase']['phaseofMoon'] #Moonphase
Der Astronomy Webservice hat eine ganz flache Struktur, d.h. genau einen Sonnenauf- und Untergang etc. Bei iterativen Daten, z.B. der Wettervorhersage für die nächsten 4 Tage kann man das natürlich auch per Schleife auslesen.
d: Iteration
nehmt hierzu z.B. den "Forecast" Webservice:
1 |
http://api.wunderground.com/DeinWundergroundKey/forecast/astronomy/lang:DL/q/48.140188,11.5585369.json |
Zum Lesen der Wetterdaten hangelt man sich bis zum Knoten forecast-simpleforecast-forecastday vor und lässt dann die Schleife über den Tag [day] laufen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/usr/bin/python #coding=UTF-8 import requests # inits fcast = [] degreeChar = u'\N{DEGREE SIGN}' #get webservice data r = requests.get("http://api.wunderground.com/MeinWundergroundKey/forecast/astronomy/lang:DL/q/48.140188,11.5585369.json") data=r.json() # data contains the parsed JSON string r.close() i=0 for day in data['forecast']['simpleforecast']['forecastday']: x=day['date']['weekday_short'] + ":" y=day['conditions'] z = day['high']['celsius'] + degreeChar+"C/" + day['low']['celsius'] + degreeChar+"C" fcast.append(x + " " + y + " " + z) print fcast[i] i=i+1 |
Der Array fcst[x]
enthält die Wettervorhersage für den Tag 0 bis 3, also vier Tage. Diese Daten könnt ihr nach Belieben in euren Programmen weiterverwenden. Bei öffentlich sichbarer Verwendung von Weather Underground Informationen muss gemäß Lizenzbedingungen ein Hinweis auf Weather Underground gezeigt werden.
Das Gradzeichen ist im normalen Zeichensatz nicht vorhanden und wird über degreeChar = u'\N{DEGREE SIGN}'
erzeugt.
Der Output sieht dann hoffentlich so ähnlich wie hier aus.
1 2 3 4 |
Mo: Teils Wolkig 2°C/-3°C Di: Heiter 2°C/-3°C Mi: Wolkig 3°C/-1°C Do: Teils Wolkig 5°C/2°C |
Bei Interesse einfach tiefer bei Weather Underground graben, es gibt da alle möglichen Wetter-Informationen. Die Doku ist interaktiv und gut gemacht.
Dieser Beitrag wurde inspiriert von der wirklich gut gemachten Site http://www.pythonforbeginners.com/scraping/scraping-wunderground
In weiteren Beiträgen zeige ich, wie man mit der Kamera gemachte Bilder mit den gerade gewonnenen Informationen beschriftet, beschneidet, in der Größe ändert, auf den eigenen Webspace hochlädt und dann noch eine Javascript Slideshow für die gemachten Webcam Aufnahmen erstellt.
Hi Chris,
noch ein Fehler: Bei
degreeChar = u'N{DEGREE SIGN}
fehlt das "\".
degreeChar = u'\N{DEGREE SIGN}
Gruß,
Uli
Peinlich… und da ist über 2 Jahre niemand drauf gekommen. In meinem eigenen code hatte ich das korrekt drin, im Beispiel nicht. Ich habs entsprechend korrigiert. Danke nochmal
Chris
Hi Chris,
leider funktioniert http://api.wunderground.com/api/DeinWundergroundKey/forecast/astronomy/lang:DL/q/Germany/Muenchen.json nicht mehr, ich würde Geodaten verwenden, also z.B. http://api.wunderground.com/MeinWundergroundKey/forecast/astronomy/lang:DL/q/48.140188,11.5585369.json für den Hauptbahnhof München.
Ansonsten eine tolle Anleitung, danke.
…../ )
…..’ /
—‘ (_____
……… ((__)
….. _ ((___)
……. -‘((__)
–.___((_)
Gruß,
Uli
Da kann man nichts machen, manchmal stellen die einfach ihren Service um, ohne dass man Bescheid bekommt. Danke für den Hinweis, ich werd's entsprechend in der Anleitung anpassen.
Gruß
Chris
Hm, einfacher geht das mit jquery.bigWEATHERws (http://bit.ly/jquery_bigWEATHERws_min) zur Zeit in der Version 0.9beta, verwendet auf http://wolframscharnhorst.blogspot.ch. Das funktioniert zumindest.
Nett! Allerdings fürchte ich, dass mit der bit.ly… Seite nur die Cracks was anfangen können. Gefühlt 50 Zeilen Code ohne Umbrüche und Kommentare oder Erklärungen überfordert die meisten User – zumindest für die Noobs die ein Noob wie ich mit diesem Blog hier erreichen will… 🙂 Außerden… wie bindet man sowas in Python ein??
Gruß
Chris
Hi Chris,
Werde deine Anleitung mal für worldweatheronline ausprobieren, da die Wetterstation von unserem Haus bei wunderground zu weit weg sind.
http://api.worldweatheronline.com/free/v2/weather.ashx?key=xxxxxxxxxx&q=48.85,2.35&num_of_days=2&tp=3&format=json
liefert bei worldweatheronline das json Format, mit welchem deine Anleitung weiter verfolgt warden kann.