In dieser Worknote hatte ich ja schon OpenWeatherMap vorgestellt und erklärt, daß ich mich damit beschäftige, weil ich eine eigene, kleine Wetterstation mit deren freien (CC BY-SA 4.0) und über eine JSON-API abrufbaren Wetterdaten basteln wollte. Und voilà, hier ist sie:
Um die JSON-Daten mit Processing.py lesen zu können, kann man auf Pythons Standardbibliotheken zurückgreifen, die einmal mit urllib2
einen einfachen Umgang mit dem Laden von Daten aus dem Netz erlauben und zum anderen mit json
ein Modul mitbringt, das den Umgang mit den JSON-Dateien vereinfacht.
import json
import urllib2
weatherUrl = "http://api.openweathermap.org/data/2.5/weather?q=Berlin%20Tempelhof,DE&units=metric&lang=de&APPID=4711"
weatherData = json.load(urllib2.urlopen(weatherUrl))
Noch einmal: Den API-Key (APPID
) habe ich mir ausgedacht, um den Code-Schnipsel oben zum Laufen zu bekommen, müßt Ihr Euch auf den Seiten von OpenWeatherMap schon einen eigenen API-Key besorgen.
{
u'visibility': 10000,
u'main': {
u'temp': 3,
u'pressure': 1007,
u'temp_max': 3,
u'temp_min': 3,
u'humidity': 74
},
u'clouds': {u'all': 40},
u'sys': {
u'country':
u'DE',
u'sunrise': 1487916142,
u'type': 1,
u'message': 0.0025,
u'sunset': 1487954244,
u'id': 4892
},
u'dt': 1487940600,
u'coord': {u'lon': 13.41, u'lat': 52.48},
u'weather': [{
u'icon': u'13d', u'description': u'm\xe4\xdfiger Schnee', u'main': u'Snow', u'id': 600
}],
u'name': u'Berlin Tempelhof',
u'cod': 200,
u'id': 7290253,
u'base': u'stations',
u'wind': {u'deg': 310, u'speed': 4.6}
}
Laßt Ihr Euch die weatherData
aus obigem Codeschnipsel mal anzeigen (ich habe sie wieder der besseren Lesbarkeit wegen umgebrochen), dann seht Ihr, daß die JSON-Bibliothek die Antwort als Dictionary behandelt und Ihr damit nicht mehr auf die Reihenfolge bauen könnt. Es ist zwar alles vorhanden, was Ihr auch hier gesehen habt, aber in einer völlig anderen Reihenfolge. Außerdem hat die Bibliothek alle Strings als UTF-8-Strings gekennzeichnet.
Nun lassen sich aber die Werte in Dictionaries in Python mit Ihrem Key abfragen und die Keys können miteinander verkettet werden. Wollt Ihr zum Beispiel den Wert des Dictionaries "temp"
, das Teil des Dictionaries "main"
ist, abfragen, so ist dies mit
temp = weatherData["main"]["temp"]
möglich. In einigen Fällen beinhalten die JSON-Objekte aber auch Listen. Diese können aber ebenfalls verkettet werden und werden über ihren Index aufgerufen. Wollt Ihr zum Beispiel die Wetterbeschreibung ("description"
) aus dem Dictionary "weather"
haben, so müßt Ihr folgendes programmieren:
wetter = weatherData["weather"][0]["description"]
So habe ich mir Stück für Stück alle Daten, die ich für mein kleines Wetterfenster haben wollte, zusammengeklaubt.
Schaut Ihr Euch die Daten, die eine Datums- und Zeitangabe betreffen, genauer an, werdet Ihr feststellen (oder in der Dokumentation nachlesen), daß diese – wie international üblich – als UTC-Timestamp kommen. Um dieses zu konvertieren, bildet das Modul datetime
Hilfe an, zum Beispiel:
import datetime
sunrise = weatherData["sys"]["sunrise"]
lokalsunrise = datetime.datetime.fromtimestamp(sunrise).ctime()
Mit fromtimestamp
wird der UTC-Stempel in eine lesbare Zeit verwandelt und das anschließende ctime
sorgt dafür, daß dies in die lokale Rechnerzeit umgewandelt wird (in meinem Fall in UTC+1 oder während der Sommerzeit in UTC+2). Um die Sommerzeit kümmert sich ctime
automatisch, da muß sich der Programmierer nicht weiter sorgen.
Das Wetter-Icon kommt natürlich auch von OpenWeatherMap und kann so geladen und angezeigt werden:
icon = weatherData["weather"][0]["icon"]
weatherIcon = loadImage("http://openweathermap.org/img/w/" + icon + ".png")
image(weatherIcon, 10, 260)
Das ist eigentlich alles, was der Programmierer wissen muß. Für die aktuelle Zeit habe ich ebenfalls das Modul datetime
genutzt und die Berechnungen durchgeführt, die ich auch schon in dem Programm zur Rentenuhr genutzt hatte.
Um den Hauptsketch übersichtlich zu halten, habe ich die beiden Funktionen getWeatherData()
und getNow()
in ein eigenes Modul getWeatherData.py
ausgelagert, das wie folgt aussieht:
# coding=utf-8
import json
import urllib2
import datetime
def getWeatherData():
weatherUrl = "http://api.openweathermap.org/data/2.5/weather?q=Berlin%20Tempelhof,DE&units=metric&lang=de&APPID=4711"
weatherData = json.load(urllib2.urlopen(weatherUrl))
# Temperatur
temp = weatherData["main"]["temp"]
myTemperatur = u"Temperatur: " + str(temp) + u"°C."
text(myTemperatur, 10, 20)
# Wetter-Beschreibung
wetter = weatherData["weather"][0]["description"]
myWetter = u"Wetter: " + wetter + "."
text(myWetter, 10, 42)
# Sonnenauf- und -untergang
sunrise = weatherData["sys"]["sunrise"]
sunset = weatherData["sys"]["sunset"]
mySunrise = "Sonnenaufgang: " + datetime.datetime.fromtimestamp(sunrise).ctime() + "."
mySunset = "Sonnenuntergang: " + datetime.datetime.fromtimestamp(sunset).ctime() + "."
text(mySunrise, 10, 80)
text(mySunset, 10, 102)
# Luftdruck und -feuchtigkeit
pressure = weatherData["main"]["pressure"]
myPressure = "Luftdruck: " + str(pressure) + " hPa."
text(myPressure, 10, 140)
humidity = weatherData["main"]["humidity"]
myHumidity = "Luftfeuchtigkeit: " + str(humidity) + " %."
text(myHumidity, 10, 162)
# Windgeschwindigkeit und Bewölkung
wind = weatherData["wind"]["speed"]
myWind = "Windgeschwindigkeit: " + str(wind) + " m/s."
text(myWind, 10, 200)
clouds = weatherData["clouds"]["all"]
myClouds = u"Bewölkung: " + str(clouds) + " %."
text(myClouds, 10, 222)
# Wetter-Icon
icon = weatherData["weather"][0]["icon"]
weatherIcon = loadImage("http://openweathermap.org/img/w/" + icon + ".png")
image(weatherIcon, 10, 260)
# Abfragezeit und -ort
dt = weatherData["dt"]
station = weatherData["name"]
myDt = "Stand: " + datetime.datetime.fromtimestamp(dt).ctime() + " aus " + station + "."
text(myDt, 10, 360)
def getNow():
myNow = datetime.datetime.now()
myHour = str(myNow.hour)
myMinute = str(myNow.minute).rjust(2, "0")
mySecond = str(myNow.second).rjust(2, "0")
myTime = myHour + ":" + myMinute + ":" + mySecond
text(u"Update: " + myTime, 10, 382)
Zum letzten Mal: Die APPID habe ich mir ausgedacht, mit dieser bekommt Ihr keine Daten von OpenWeatherMap.
Das Modul wirkt auf den ersten Blick schlimmer als es ist, denn eigentlich ist alles straigforward: Die Daten werden aus dem JSON-Objekt ausgelesen, dann wird ein String erzeugt und zum Schluß wird dieser String mit Hilfe der text()
-Funktion angezeigt.
So ist das Hauptprogramm wieder sehr kurz geraten:
from getWeatherData import getWeatherData, getNow
def setup():
size(600, 400)
background(0)
frame.setTitle (u"Jörgs Wetterstation")
font = createFont("American Typewriter", 18)
textFont(font)
getWeatherData()
getNow()
frameRate(1)
def draw():
if(second() == 0):
background(0)
getWeatherData()
getNow()
In der setup()
-Funktion rufe ich zu Initialisierung genau einmal die Wetterdaten ab. Nun darf man in der kostenlosen Lizenz die Daten maximal 60 mal in der Minute abrufen. Mit frameRate(1)
alleine schafft man das nicht (ich habe sie auch nur darauf gesetzt, um den Rechner nicht unnötig zu belasten). Darum werden die weiteren Abfragen nur gestartet, wenn die Sekunde auf Null steht, das heißt es gibt nur einen Aufruf in der Minute. Damit habe ich die Lizenz der API mehr als eingehalten.
Eigentlich könnte man die Daten noch seltener abrufen: Die von mir angefragte Station Berlin Tempelhof gibt nur jede halbe Stunde (um x:20 Uhr und um x:50 Uhr) ihre Daten weiter und es kann noch bis zu einer weiteren halben Stunde dauern, bis die Daten bei OpenWeatherMap eingepflegt und abrufbar sind. Im schlimmsten Fall kann es zu Verzögerungen bis zu einer Stunde kommen, manchmal sind die neuen Daten aber auch überraschend schnell da.
Sicher kann man die Wetterstation optisch noch ein wenig aufpeppen und man kann auch mehrere Wetterstationen abfragen oder die API zur Wettervorhersage nutzen, aber als Beispiel, wie man JSON-Daten per API aus dem Netz holt und aufbereitet, ist dieser Sketch völlig ausreichend. Alles weitere bleibt der Phantasie meiner Leserinnen und Leser überlassen.
Wie bei den bisherigen Processing.py-Tutorials habe ich auch dieses auf meine Site Processing.py lernen hochgeladen. Korrekturen, Änderungen und Ergänzungen wird es nur dort geben.
Über …
Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!
Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.
Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.
Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes
von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.
Werbung