]> ToastFreeware Gitweb - chrisu/seepark.git/blob - owm.py
1a55892a1cd0ba7bda3beb25b3dc7e186c107ca9
[chrisu/seepark.git] / owm.py
1 #!/usr/bin/python3
2
3 # needs ~/seepark.ini with
4 # [openweathermap]
5 # apikey=...
6 # cityid=..
7 # 3319578 for Obsteig, AT
8
9 # needed packaes: python3-mysqldb python3-sqlalchemy
10
11 import argparse
12 import configparser
13 import csv
14 import datetime
15 import json
16 import math
17 import os
18 from pprint import pprint
19
20 import sqlalchemy
21 from sqlalchemy import create_engine, Table
22
23 from seeparklib.openweathermap import openweathermap_json
24
25
26 def fromtimestamp(timestamp):
27     return datetime.datetime.fromtimestamp(timestamp)
28
29
30 # https://stackoverflow.com/questions/7490660/converting-wind-direction-in-angles-to-text-words
31 def degToCompass(num):
32     if num is None or num is math.nan:
33         return 'N/A'
34     val=int((num/22.5)+.5)
35     arr=["N","NNO","NO","ONO","O","OSO", "SO", "SSO","S","SSW","SW","WSW","W","WNW","NW","NNW"]
36     return arr[(val % 16)]
37
38
39 def extractweatherdata(w):
40     data = dict(
41         datetime = fromtimestamp(w['dt']),
42         sunrise = fromtimestamp(w['sys']['sunrise']),
43         sunset = fromtimestamp(w['sys']['sunset']),
44         temp = w['main']['temp'],
45         pressure = w['main']['pressure'],
46         humidity = w['main']['humidity'],
47         weather = w['weather'][0]['description'],
48         sky = w['weather'][0]['main'],
49         windspeed = w['wind']['speed'],
50         cloudiness = w['clouds']['all'],
51     )
52
53     data['winddegrees'] = w['wind']['deg'] if 'deg' in w['wind'] else math.nan
54     data['winddirection'] = degToCompass(data['winddegrees'])
55     data['precipitation'] = w['rain']['3h'] if 'rain' in w and w['rain'].get('3h') else math.nan
56     data['visibility'] = w.get('visibility', math.nan)
57
58     return data
59
60
61 def write_csv(csv_file, weather_data):
62     """output like wetter.at.pl"""
63     with open(csv_file, "a", newline="") as file:
64         writer = csv.writer(file, dialect="excel", delimiter=';')
65         writer.writerow([
66             weather_data['datetime'].date(),
67             weather_data['datetime'].time(),
68             weather_data['sunrise'].time(),
69             weather_data['sunset'].time(),
70             "{:.2f}".format(weather_data['temp']),
71             "{:.2f} mm/h".format(weather_data['precipitation']),
72             "{:.1f} km/h {}".format(weather_data['windspeed'], weather_data['winddirection']),
73             weather_data['weather'],
74             "{}".format(weather_data['cloudiness'])
75         ])
76
77
78 def write_db(config, url, weather_json, weather_data):
79     user = config.get('database', 'user')
80     pwd = config.get('database','password')
81     host = config.get('database','hostname')
82     db = config.get('database','database')
83
84     engine = create_engine('mysql+mysqldb://{}:{}@{}/{}'.format(user, pwd, host, db), echo=False)
85     with engine.connect() as conn:
86         row = dict(cityid=config.get('openweathermap', 'cityid'), url=url, result=json.dumps(weather_json))
87         row.update(weather_data)
88         for key, value in row.items():
89             if isinstance(value, float) and math.isnan(value):
90                 row[key] = None
91         metadata = sqlalchemy.MetaData()
92         openweathermap_table = Table('openweathermap', metadata, autoload_with=engine)
93         ins = openweathermap_table.insert().prefix_with('IGNORE').values(**row)
94         conn.execute(ins)
95         conn.commit()
96
97
98 def main(configfile, debug):
99     config = configparser.ConfigParser()
100     config.read(configfile)
101     apikey = config.get('openweathermap', 'apikey')
102     cityid = config.get('openweathermap', 'cityid')
103     csvfile = config.get("openweathermap", 'csvfilename')
104
105     url, weather_json = openweathermap_json(apikey, cityid)
106     if debug:
107         pprint(weather_json)
108     weather_data = extractweatherdata(weather_json)
109     if debug:
110         pprint(weather_data)
111
112     # write to db
113     write_db(config, url, weather_json, weather_data)
114
115     # write to csv
116     write_csv(os.path.expanduser(csvfile), weather_data)
117
118
119 if __name__ == '__main__':
120     default_config_file = os.path.expanduser('~/seewasser.ini')
121     parser = argparse.ArgumentParser(description='Get OpenWeathermap data')
122     parser.add_argument('--config', default=default_config_file, help='configuration file')
123     parser.add_argument('--debug', action='store_true', default=False, help='print debug information')
124     args = parser.parse_args()
125     main(args.config, args.debug)