Zweites Update: Wetterbericht im JSON Format auslesen und verarbeiten

Da Darksky von Apple übernommen wurde, kann man keine neuen kostenlosen Accounts mehr anlegen. Deshalb hier das zweite Update, diesmal mit dem kostenfreien Service Openweathermap.

Update vom 2. Update:

April 2024: Die API Version 2.5 läuft im Juni 2024 aus und wird mit Version 3.0 ersetzt. Der Service ist bis zu 1000 Abrufen/Tag immer noch kostenlos, aber man muss den Service trotzdem mit einer Kreditkarte abonnieren (subscribe). Wenn man unter den 1000 Abrufen/Tag bleibt, wird die Karte nicht belastet. Funktionell bleibt alles beim Alten. d.h. im Aufruf muss lediglich die API  Version von 2.5 auf 3.0 geändert werden. Der API Key bleibt unverändert. Dieser Beitrag wurde daher insgesamt auf den neuesten Stand gebracht.

Also zum Beispiel: https://api.openweathermap.org/data/<strong>3.0</strong>/onecall?lat={lat}&lon={lon}&exclude={part}&appid={API key}

Nach der Subscription dauert es u.U. ein paar Stunden, bis der API Key umgestellt ist und die Abrufe mit 3.0 klappen.

-.-.-.-.-.-.-.-.-.-.-.-.-

In meine Webcam möchte ich einen Wetterbericht mit einigen Tagen Vorausschau einblenden.

Die bisher von mir verwendete Webservices von Weather Underground und Darksky.net  stellen keine neuen kostenfreien APIs mehr zur Verfügung. Ich bin deshalb auf Openweathermap umgestiegen, in der Hoffnung, dass der Service etwas länger bestehen bleibt.

Openweathermap.org ist ein sehr mächtiger Service mit aktuellem Wetter, stundengenauer 4 Tage Vorhersage, 16 Tage Vorhersage, Klimavorhersage über 30 Tage und inzwischen gibt es auch die sogenannte "One Call API" mit vielen kostenfreien Features wie minutengenauer Vorhersage für die nächste Stunde, 7 Tage Vorhersage, 5 Tages Rückschau etc. Die Wettertexte sind leider nicht ganz so ausführlich wie die von Darksky.

Die 7 Tage Vorhersage aus der One Call API ist genau das, was ich brauche.

Mondphasen gibt es hier leider keine: vielleicht etwas nerdig, aber ich will sowieso eine möglichst genaue Anzeige der Mondphase und der sichtbaren Mondoberfläche in Prozent. Ich errechne deshalb die Mondphase selbst.

Update April 2024: Wie ich beim Ansehen der neuen API gemerkt habe, wird jetzt auch die Montphase als numerischer Wert ausgegeben.

Schritt 1: Account anlegen

Surft zu https://home.openweathermap.org/users/sign_in und klickt den Button "Create an account" an.

Die Registrierung ist selbsterklärend. Am Schluss erhaltet ihr euren eigenen geheimen API Schlüssel [key] der Art "700416988c7436cd5abc92c328d2b320". Mit diesem Schlüssel müsst ihr euch bzw. euer Programm bei künftigen Abfragen ausweisen.

Seit 2024 muss man sich mit einer Kreditkarte registrieren. Bleibt man unter der 1000er Freigrenze, wird die Karte nicht belastet.

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:

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 Entwicklerpaket 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 Openweathermap angebotenen Daten und deren Struktur gibt es eine gute Dokumentation auf deren Site  https://openweathermap.org/api/one-call-api.

a: Das JSON Format anschauen

Um das Prinzip zu verdeutlichen, nehmen wir uns für den Anfang den allgemeinen Wetterüberblick vor.

Gebt zuerst einmal folgende Zeile in euren Browser ein:

Nach dem Fragezeichen werden die Aufrufparameter übergeben. Zuerst kommen die  Geokoordinaten (lan/lon bzw. Breite und Länge) für den Ort, für den ihr die heutigen Wetterdaten wissen wollt – in diesem Beispiel ist es der Hauptbahnhof München. Die weiteren Parameter werden dann untereinander durch ein Ampersand "&" getrennt werden. Beim obigen Beispiel ist das die Sprache (lang=de) sowie metrische Einheiten ( &units=metric) und zum Schluss anstatt DeinenGeheimenKey natürlich euer eigener, vorhin generierter Key.

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. In einem kleinen Popup unten auf der Karte werden dann die Geokoordinaten schon im richtigen Format angezeigt. Diese einfach übernehmen und in die Codezeile eintragen.

Ich arbeite praktisch nur mit dem Firefox Browser, da weiß ich wenigstens, dass mein Surfverhalten nicht weiterverkauft wird – anders als bei Chrome oder Edge. Firefox hat eine sehr gute eingebaute Darstellung des empfangenen JSON Objekts. Edge und Chome können das übrigens von Haus aus nicht.

Das im Firefox Browser angezeigte Ergebnis für den 23. Oktober 2020 ist dann wie folgt, wobei ich hier der Übersichtlichkeit halber die Daten für minutely und hourly eingeklappt habe:

Diese wunderschön strukturierten Informationen können wir in Python jetzt ganz elegant verarbeiten.

Exkurs: Auch eine schön 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 ErweiterungenJSON ViewerFormat JSON anklicken. Et voilà, JSON ist so noch besser anzusehen.
Ganz toll ist auch der Online JSON Editor bei http://jsoneditoronline.org/

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

Anschließend wird die soeben installierte Requests Bibliothek importiert

Zunächst einmal müssen wir den Webservice mit dem oben ausprobierten Aufruf ansprechen und den gelieferten Output einem Python Objekt [hier: r] zuweisen.

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:

und hier der Output davon:

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 daily dann die fortlaufende Nummer, wobei 0 für den aktuellen Tag steht und schließlich das Element
sunrise
In Python ausgedrückt sieht das so aus:

Die Zeit wird allerdings als UNIX Zeitstempel, eine 10stellige Zahl,  ausgegeben. Zur lesbaren Darstellung kann man diesen Wert mittels strftime natürlich gleich konvertieren. Hierzu muss allerdings noch "datetime" aus der datetime Bibliothek  importiert werden.
from datetime import datetime as dt
Die darin steckenden Routinen brauchen wir später auch noch für die Anzeige des Wochentags. Das as dt ist nur eine wahlfreie Abkürzung zur Vermeidung von Schreibarbeit.

Hinweis: Openweathermap bezieht sich bei den Zeitangaben immer auf die Zeit des Ortes, dessen Koordinaten man eingegeben hat. Es ist also keine Konversion von UTC (Universal Time Coordinated) nötig. Die Zeitstempel für die einzelnen Tages-Wetterberichte beziehen sich immer auf 0 Uhr Ortszeit.

d: Iteration

Bei iterativen Daten, z.B. der Wettervorhersage für heute und die nächsten 7 Tage kann man das natürlich auch per Schleife auslesen. Die Schleife läuft über den Wert 'day' in der zweiten Ebene
['daily'][day]
also die Stelle, bei der wir vorhin nur die "0" verwendet haben.

Beim requests Statement habe ich noch einen 120 Sekunden Timeout eingebaut, damit das Programm bei einem Abrufproblem nicht ewig hängt. Am besten fängt man Zugriffsfehler mit try:  except:  Blöcken ab.

Der Array fcst[x] enthält die Wettervorhersage für den Tag 0 bis 7, also acht Tage. Diese Daten könnt ihr nach Belieben in euren Programmen weiterverwenden.

Ich persönlich verwende nur die ersten vier Tage des Wetterberichts. Hier ist die Eintrittswahrscheinlichkeit noch relativ groß.

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.

Bei Interesse einfach tiefer bei Openweathermap graben, es gibt da alle möglichen Wetter-Informationen.

Dieser Beitrag wurde inspiriert von der wirklich gut gemachten Site http://www.pythonforbeginners.com/scraping/scraping-wunderground wobei auch diese Seite jetzt veraltet sein dürfte.

Schreibe einen Kommentar

Ich freue mich über Lob und Kritik.
Falls du Probleme mit der hier vorgestellten Anleitung hast und nicht weiter kommst:
Bitte das Problem oder die Fehlermeldung(en) möglichst genau beschreiben, auch an welcher Stelle (z.B. in welchem Node oder Befehl) und unter welchen Umständen der Fehler auftritt.
Gerne kannst du mir auch ein Mail schreiben. Die Adresse findest du im Impressum.
Ich gebe mir viel Mühe, meinen Lesern weiterzuhelfen. Je konkreter du bist, desto einfacher und schneller kann ich versuchen zu helfen.
Deine E-Mail-Adresse wird nicht veröffentlicht.
Erforderliche Felder sind mit * markiert