]> ToastFreeware Gitweb - chrisu/seepark.git/blob - owm.py
237c3d771e20fee2098ec64cb68a077ed7439d82
[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, URL
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 deg_to_compass(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 extract_weather_data(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'] = deg_to_compass(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     db_url = URL.create(drivername='mysql+mysqldb', username=user, password=pwd, host=host, database=db)
85     engine = create_engine(db_url, echo=False)
86     with engine.connect() as conn:
87         row = dict(cityid=config.get('openweathermap', 'cityid'), url=url, result=json.dumps(weather_json))
88         row.update(weather_data)
89         for key, value in row.items():
90             if isinstance(value, float) and math.isnan(value):
91                 row[key] = None
92         metadata = sqlalchemy.MetaData()
93         openweathermap_table = Table('openweathermap', metadata, autoload_with=engine)
94         ins = openweathermap_table.insert().prefix_with('IGNORE').values(**row)
95         conn.execute(ins)
96         conn.commit()
97
98
99 def main(configfile, debug):
100     config = configparser.ConfigParser()
101     config.read(configfile)
102     apikey = config.get('openweathermap', 'apikey')
103     cityid = config.get('openweathermap', 'cityid')
104     csvfile = config.get("openweathermap", 'csvfilename')
105
106     url, weather_json = openweathermap_json(apikey, cityid)
107     if debug:
108         pprint(weather_json)
109     weather_data = extract_weather_data(weather_json)
110     if debug:
111         pprint(weather_data)
112
113     # write to db
114     write_db(config, url, weather_json, weather_data)
115
116     # write to csv
117     write_csv(os.path.expanduser(csvfile), weather_data)
118
119
120 if __name__ == '__main__':
121     default_config_file = os.path.expanduser('~/seewasser.ini')
122     parser = argparse.ArgumentParser(description='Get OpenWeathermap data')
123     parser.add_argument('--config', default=default_config_file, help='configuration file')
124     parser.add_argument('--debug', action='store_true', default=False, help='print debug information')
125     args = parser.parse_args()
126     main(args.config, args.debug)