BlogLinuxPython

openweather

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.