Ich war auf der Suche nach einen kostenlosen Onlineservice um Wetterdaten via API abzugreifen. Ziel ist es, ein lokales Chart über das Wetter zu bekommen, welches über Jahre auswertbar ist. Mit den erworbenen Wetterdaten möchte ich vor allem die Windgeschwindigkeiten Vorort im Auge behalten. Fündig geworden bin ich bei Openweather. Um den Service und somit die API abzufragen, benötigt ihr ein Key. Dieser muss bei jeder Abfrage angegeben werden. Den Key erhält man bei der Registrierung im Portal. Ihr könnt dort ebenfalls zur kostenpflichtigen Version wechseln. Diese bietet gegenüber der Kostenfreien mehr Funktionen an. Für mich reicht die kostenlose Variante. Die Wetterdaten werden jede Stunde über die API abgefragt und bei mir lokal in eine Datenbank gespeichert.
Damit der http Request korrekt verläuft, muss unter anderem der vorher erlangte Key in jeder Abfrage verwendet werden.
http://api.openweathermap.org/data/2.5/weather?q=berlin,de&APPID=<key>
Dieser Request gibt ein JSON Packet als Response zurück, der wie folgt aussieht:
{"coord":{"lon":13.39,"lat":52.52},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":279,"feels_like":274.77,"temp_min":277.59,"temp_max":279.82,"pressure":1032,"humidity":75},"visibility":10000,"wind":{"speed":3.6,"deg":300},"clouds":{"all":75},"dt":1577818777,"sys":{"type":1,"id":1262,"country":"DE","sunrise":1577776641,"sunset":1577804447},"timezone":3600,"id":2950159,"name":"Berlin","cod":200}
Die Parameter sind sehr gut auf der Openweather Seite beschrieben. Um mehr darüber zu erfahren, folgt diesen Link:
https://openweathermap.org/weather-data
Nur das JSON Packet alleine reicht natürlich nicht. Es muss ein komplettes Grundgerüst, bestehend aus Datenbank und Code der die Abfrage triggert, aufgebaut werden.
Datenbank Schema
Das Datenbank Schema, welches zurzeit existiert, ist relativ simple aufgebaut. Es besteht aus 3 Tabellen, eine für die Wetterdaten und die anderen beiden dienen zum Erstellen des Requests.
use Weather; SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS CUR_WEATHER; DROP TABLE IF EXISTS WEA_OPENWEATHER; DROP TABLE IF EXISTS WEA_CITY; SET FOREIGN_KEY_CHECKS = 1; CREATE TABLE IF NOT EXISTS WEA_CITY( ID int(10) NOT NULL, CITY_NAME varchar(100) NOT NULL, PRIMARY KEY(ID) ); CREATE TABLE IF NOT EXISTS CUR_WEATHER( ID int(14) NOT NULL auto_increment, C_LON decimal(5,2) NOT NULL, C_LAT decimal(5,2) NOT NULL, W_MAIN varchar(50) NOT NULL, W_DESCRIPTION varchar(100) NOT NULL, W_ICON varchar(50) NOT NULL, M_TEMP decimal(4,2) NOT NULL, M_PRESSURE decimal(7,2) NOT NULL, M_HUMIDITY decimal(7,2) NOT NULL, M_TEMP_MIN decimal(7,2) NOT NULL, W_SPEED decimal(4,2) NOT NULL, W_DEG decimal(5,2) NOT NULL, RAIN_3H decimal(5,2), CLOUDINESS decimal(5,2) NOT NULL, DT_TIMESTAMP datetime NOT NULL, SYS_COUNTRY varchar(4) NOT NULL, SYS_SUNRISE datetime NOT NULL, SYS_SUNSET datetime NOT NULL, TIMEZONE int(15) NOT NULL, CITY_ID int(10) NOT NULL, CREATED_AT datetime NOT NULL, PRIMARY KEY(ID), FOREIGN KEY(CITY_ID) REFERENCES WEA_CITY(ID) ); CREATE TABLE IF NOT EXISTS WEA_OPENWEATHER( ID int(5) NOT NULL auto_increment, QUERY varchar(500) NOT NULL, CITY_ID int(10) NOT NULL, PRIMARY KEY(ID) );
Shell Code
Der Shell Code ist dafür verantwortlich, dass das Python Script angestoßen wird und somit die Wetterdaten in die Datenbank landen.
Dabei wird der Code als Cronjob ausgeführt und jede Stunde getriggert. Die Ausgabe wird dabei in die Weather.log gepiped.
#!/bin/bash echo "`date +%d.%m.%y\ %T` ===weather cronjob execution==== " >> /var/log/Weather.log python3 ~/Projekte/Weather/WEATHER.py >> /var/log/Weather.log exit
Python Code
Die benötigten Pakete für Python habe ich über pip3 installiert:
apt install python3-pip pip3 install requests pip3 install mysql-connector-python pip3 install termcolor pip3 install python-dateutil
Der Python Code versucht zuerst die benötigten Module zu laden und springt in eine Exception, sobald eins davon nicht vorhanden ist. Verwendet wird hier ebenfalls die von mir erstellte Datenbank Klasse PDB, welche ich in diesem Artikel beschrieben habe. Nach dem die Module geladen sind, folgt die Abfrage gegen die Datenbank, um die erforderliche Query für die Openweather API zu erhalten. In die Variable response wird das JSON Objekt geschrieben, welches später mittels json.loads in WeatherVar geschrieben wird. Danach wird mi DB.QueryInsert ein neuer Eintrag in der Datenbank erzeugt und die Verbindung wieder geschlossen.
try: import json import requests import PDB from termcolor import colored from datetime import datetime except: print("Python could not load all required modules") sys.exit(1) DB=OpenweatherQuery=response=WeatherVar = None if DB is None: DB = PDB.databaseconnection('localhost','user','password','Weather') DB.Connect() if OpenweatherQuery is None: OpenweatherQuery = DB.QuerySelect("select QUERY from WEA_OPENWEATHER where CITY_ID = 6552907", None,False) try: if response is None: response = requests.get(OpenweatherQuery[0][0]) except requests.exceptions.RequestException as e: print(e) sys.exit(1) print(colored("[I] + " + OpenweatherQuery[0][0],"green")) print(colored("[I] + " + response.text,"green")) if WeatherVar is None: WeatherVar = json.loads(response.text) if not DB.QueryInsert("insert CUR_WEATHER(%s) VALUES(%s)",{"C_LON":WeatherVar["coord"]["lon"],"C_LAT":WeatherVar["coord"]["lat"],"W_MAIN":WeatherVar["weather"][0]["main"],"W_DESCRIPTION":WeatherVar["weather"][0]["description"],"W_ICON":WeatherVar["weather"][0]["icon"],"M_TEMP":float(WeatherVar["main"]["temp"]) - 273.15,"M_PRESSURE":WeatherVar["main"]["pressure"],"M_HUMIDITY":WeatherVar["main"]["humidity"],"M_TEMP_MIN":float(WeatherVar["main"]["temp_min"]) -273.15,"W_SPEED":float(WeatherVar["wind"]["speed"]) * 3.6,"W_DEG":WeatherVar["wind"]["deg"],"RAIN_3H":"0","CLOUDINESS":WeatherVar["clouds"]["all"],"DT_TIMESTAMP":datetime.utcfromtimestamp(WeatherVar["dt"]).strftime('%Y-%m-%d %H:%M:%S'),"SYS_COUNTRY":WeatherVar["sys"]["country"],"SYS_SUNRISE":datetime.utcfromtimestamp(WeatherVar["sys"]["sunrise"]).strftime('%Y-%m-%d %H:%M:%S'),"SYS_SUNSET":datetime.utcfromtimestamp(WeatherVar["sys"]["sunset"]).strftime('%Y-%m-%d %H:%M:%S'),"TIMEZONE":WeatherVar["timezone"],"CITY_ID":WeatherVar["id"],"CREATED_AT":str(datetime.now())}, True): print("Insert query went wrong for some reason, See Error") DB.Disconnect()
Ein Gedanke zu „openweather“