Skip to content

Commit c8d8cba

Browse files
authored
Merge pull request #89 from TheFinalJoke/weather_normalize
[weathermatrix] Weather normalize
2 parents 1bf1097 + a9d78ab commit c8d8cba

File tree

10 files changed

+331
-131
lines changed

10 files changed

+331
-131
lines changed

lib/binary_build.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ mv -v ohmyoled ohmyoled-$VERSION/
1212

1313
cp -v lib/config/ohmyoled.conf ohmyoled-$VERSION
1414

15-
cp -v lib/weather/ecIcons_utf8.csv ohmyoled-$VERSION
16-
1715
cp -v install.sh ohmyoled-$VERSION
1816

1917
cp -vr fonts/ ohmyoled-$VERSION

lib/weather/ecIcons_utf8.csv

Lines changed: 0 additions & 50 deletions
This file was deleted.

lib/weather/normal.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env python3
2+
from typing import Dict, Tuple
3+
from datetime import datetime, timedelta
4+
from lib.weather.openweather.weather import OpenWeatherApi
5+
from lib.run import Caller
6+
7+
class NormalizedWeather():
8+
9+
def __init__(self, api_result) -> None:
10+
self.api_result = api_result
11+
12+
@property
13+
def get_api(self):
14+
return self.api_result.get_api
15+
16+
@property
17+
def get_icon(self):
18+
return self.api_result.get_icon
19+
20+
@property
21+
def get_lat_long(self) -> Tuple[float, float]:
22+
return self.api_result.get_lat_long
23+
24+
@property
25+
def get_wind_speed(self) -> int:
26+
return self.api_result.get_wind_speed
27+
28+
@property
29+
def get_daily(self) -> Dict[str, str]:
30+
return self.api_result.get_daily
31+
32+
@property
33+
def get_wind_deg(self) -> int:
34+
return self.api_result.get_wind_deg
35+
36+
@property
37+
def get_precipitation(self) -> int:
38+
return self.api_result.get_precipitation * 100
39+
40+
@property
41+
def get_uv(self) -> int:
42+
return self.api_result.get_uv
43+
44+
@property
45+
def get_place(self) -> str:
46+
return self.api_result.get_place
47+
48+
@property
49+
def get_weather(self) -> Dict[str, str]:
50+
return self.api_result.get_weather
51+
52+
@property
53+
def get_conditions(self) -> str:
54+
return self.api_result.get_conditions
55+
56+
@property
57+
def get_weather_icon(self) -> str:
58+
return self.api_result.get_weather_icon
59+
60+
@property
61+
def get_temp(self) -> int:
62+
return self.api_result.get_temp
63+
64+
@property
65+
def get_feels_like(self) -> int:
66+
return self.api_result.get_feels_like
67+
68+
@property
69+
def get_min_temp(self) -> int:
70+
return self.api_result.get_min_temp
71+
72+
@property
73+
def get_max_temp(self) -> int:
74+
return self.api_result.get_max_temp
75+
76+
@property
77+
def get_humidity(self) -> None:
78+
return self.api_result.get_humidity
79+
80+
@property
81+
def get_wind(self) -> Dict:
82+
return self.api_result.get_wind
83+
84+
@property
85+
def get_time(self) -> datetime:
86+
return self.api_result.get_time
87+
88+
@property
89+
def get_sunrise(self) -> datetime:
90+
return self.api_result.get_sunrise
91+
92+
@property
93+
def get_sunset(self) -> datetime:
94+
return self.api_result.get_sunset
95+
96+
def calculate_duration_of_daylight(self) -> timedelta:
97+
return self.api_result.get_sunset - self.api_result.get_time
98+
99+
class WeatherApi(Caller):
100+
101+
def __init__(self, config) -> None:
102+
super().__init__()
103+
self.config = config
104+
105+
async def run_weather(self):
106+
if self.config['weather']['api'] == "openweather":
107+
open_weather = OpenWeatherApi(self.config)
108+
result = await open_weather.run()
109+
else:
110+
result = ""
111+
return NormalizedWeather(result)

lib/weather/openweather/__init__.py

Whitespace-only changes.

lib/weather/weather.py renamed to lib/weather/openweather/weather.py

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,11 @@
1010
from typing import Dict, Tuple, List
1111
from datetime import datetime
1212
from datetime import timedelta
13+
import lib.weather.weatherbase as base
14+
from lib.weather.weather_icon import weather_icon_mapping
1315
import csv
1416

15-
def get_weather_csv() -> List[Dict[str, str]]:
16-
csv_path = '/etc/ohmyoled/ecIcons_utf8.csv'
17-
return list(csv.DictReader(open(csv_path)))
18-
19-
def build_weather_icons() -> str:
20-
csv = get_weather_csv()
21-
icon = {}
22-
for icn in csv:
23-
icon.update({icn["OWMCode"]: WeatherIcon(icn['OWMCode'], icn['Description'], icn['fontcode'], icn['font'])})
24-
return icon
25-
26-
class WeatherIcon():
27-
def __init__(self, owm_id: str, description: str, fontcode: str, font: str) -> None:
28-
self.owm_id = owm_id
29-
self.description = description
30-
self.fontcode = fontcode
31-
self.font = font
32-
33-
@property
34-
def get_owm_id(self) -> str:
35-
return self.owm_id
36-
@property
37-
def get_description(self) -> str:
38-
return self.description
39-
@property
40-
def get_fontcode(self) -> str:
41-
return self.fontcode
42-
@property
43-
def get_font(self) -> str:
44-
return self.font
45-
46-
47-
48-
class WeatherApi(Runner):
17+
class OpenWeatherApi(Runner):
4918
"""
5019
Weatherapi object
5120
To parse the config file and
@@ -127,16 +96,18 @@ async def run(self) -> Dict:
12796
api_data = await self.get_data(args)
12897
current_data = await self.get_current_location()
12998
api_data['name'] = current_data['city']
130-
return api_data
99+
return OpenWeather(api_data)
131100

132-
class Weather(Caller):
101+
class OpenWeather(Caller):
133102
"""
134103
Weather object to describe current Polled data
135104
"""
136105
def __init__(self, api: Dict) -> None:
137106
super().__init__()
138107
self.api = api
139108
self.api_json = api
109+
self._api_caller = base.APIWeather.OPENWEATHER
110+
self._lat_long = (self.api['lat'], self.api['lon'])
140111
self._place = self.api_json.get('name')
141112
self._current = self.api_json.get('current')
142113
self._weather = self._current.get('weather')
@@ -180,6 +151,49 @@ def __repr__(self) -> str:
180151
joined_attrs = ',\n'.join(attrs)
181152
return f"Weather(\n{joined_attrs})"
182153

154+
@property
155+
def get_icon(self):
156+
owm_wxcode: int = int(self._weather[0]['id'])
157+
if owm_wxcode in range(200,299):
158+
# Thunderstorm Class
159+
owm_icon = weather_icon_mapping[17]
160+
elif owm_wxcode in range(300,399):
161+
# Drizzle Class
162+
owm_icon = weather_icon_mapping[23]
163+
elif owm_wxcode in range(500,599):
164+
# Rain Class
165+
owm_icon = weather_icon_mapping[9]
166+
elif owm_wxcode in range(600,699):
167+
# Snow Class
168+
owm_icon = weather_icon_mapping[13]
169+
elif owm_wxcode in range(700, 780):
170+
owm_icon = weather_icon_mapping[36]
171+
elif owm_wxcode == 800:
172+
# Sunny
173+
if self._sunset > datetime.now():
174+
owm_icon = weather_icon_mapping[0]
175+
else:
176+
owm_icon = weather_icon_mapping[48]
177+
178+
elif owm_wxcode in range(801,805):
179+
# Rain Class
180+
if self._sunset > datetime.now():
181+
owm_icon = weather_icon_mapping[3]
182+
else:
183+
owm_icon = weather_icon_mapping[48]
184+
else:
185+
owm_icon = weather_icon_mapping[0]
186+
187+
return owm_icon
188+
189+
@property
190+
def get_api(self):
191+
return self._api_caller
192+
193+
@property
194+
def get_lat_long(self) -> Tuple[float, float]:
195+
return self._lat_long
196+
183197
@property
184198
def get_wind_speed(self) -> int:
185199
return self._wind_speed

lib/weather/weather_icon.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import lib.weather.weatherbase as base
2+
3+
weather_icon_mapping = {
4+
0: base.WeatherIcon(condition='Sunny', icon='f00d', font='\uf00d', time_of_day='Day Conditions Only', url=None, owmcode=800),
5+
1: base.WeatherIcon(condition='Mainly Sunny', icon='f00d', font='\uf00d', time_of_day='Day Conditions Only', url=None, owmcode=800),
6+
2: base.WeatherIcon(condition='Partly Cloudy', icon='f002', font='\uf002', time_of_day='Day Conditions Only', url=None, owmcode=801),
7+
3: base.WeatherIcon(condition='Mostly Cloudy', icon='f013', font='\uf013', time_of_day='Day Conditions Only', url=None, owmcode=801),
8+
4: base.WeatherIcon(condition='Light Rain Shower', icon='f008', font='\uf008', time_of_day='Day Conditions Only', url=None, owmcode=500),
9+
5: base.WeatherIcon(condition='Light Rain Shower and Flurries', icon='f006', font='\uf006', time_of_day='Day Conditions Only', url=None, owmcode=300),
10+
6: base.WeatherIcon(condition='Light Flurries', icon='f00a', font='\uf00a', time_of_day='Day Conditions Only', url=None, owmcode=600),
11+
7: base.WeatherIcon(condition='Cloudy', icon='f013', font='\uf013', time_of_day='Day and Night Conditions', url=None, owmcode=801),
12+
8: base.WeatherIcon(condition='Precipitation', icon='f01c', font='\uf01c', time_of_day='Day and Night Conditions', url=None, owmcode=500),
13+
9: base.WeatherIcon(condition='Rain', icon='f019', font='\uf019', time_of_day='Day and Night Conditions', url=None, owmcode=500),
14+
10: base.WeatherIcon(condition='Rain Shower', icon='f01a', font='\uf01a', time_of_day='Day and Night Conditions', url=None, owmcode=500),
15+
11: base.WeatherIcon(condition='Freezing Rain', icon='f0b5', font='\uf0b5', time_of_day='Day and Night Conditions', url=None, owmcode=500),
16+
12: base.WeatherIcon(condition='Rain and Snow', icon='f017', font='\uf017', time_of_day='Day and Night Conditions', url=None, owmcode=600),
17+
13: base.WeatherIcon(condition='Snow', icon='f01b', font='\uf01b', time_of_day='Day and Night Conditions', url=None, owmcode=600),
18+
14: base.WeatherIcon(condition='Snow', icon='f01b', font='\uf01b', time_of_day='Day and Night Conditions', url=None, owmcode=600),
19+
15: base.WeatherIcon(condition='Snow', icon='f01b', font='\uf01b', time_of_day='Day and Night Conditions', url=None, owmcode=600),
20+
16: base.WeatherIcon(condition='Heavy Snow', icon='f01b', font='\uf01b', time_of_day='Day and Night Conditions', url=None, owmcode=600),
21+
17: base.WeatherIcon(condition='Thunderstorm', icon='f01e', font='\uf01e', time_of_day='Day Conditions Only', url=None, owmcode=200),
22+
18: base.WeatherIcon(condition='Haze', icon='f0b6', font='\uf0b6', time_of_day='Day and Night Conditions', url=None, owmcode=721),
23+
19: base.WeatherIcon(condition='Fog', icon='f014', font='\uf014', time_of_day='Day and Night Conditions', url=None, owmcode=741),
24+
20: base.WeatherIcon(condition='Drifting Snow', icon='f064', font='\uf064', time_of_day='Day and Night Conditions', url=None, owmcode=600),
25+
21: base.WeatherIcon(condition='Ice Crystals', icon='f076', font='\uf076', time_of_day='Day and Night Conditions', url=None, owmcode=600),
26+
22: base.WeatherIcon(condition='Hail', icon='f015', font='\uf015', time_of_day='Day and Night Conditions', url=None, owmcode=600),
27+
23: base.WeatherIcon(condition='Drizzle', icon='f01c', font='\uf01c', time_of_day='Day and Night Conditions', url=None, owmcode=300),
28+
24: base.WeatherIcon(condition='Clear', icon='f02e', font='\uf02e', time_of_day='Night Conditions Only', url=None, owmcode=800),
29+
25: base.WeatherIcon(condition='Mainly Clear', icon='f02e', font='\uf02e', time_of_day='Night Conditions Only', url=None, owmcode=800),
30+
26: base.WeatherIcon(condition='Partly Cloudy', icon='f031', font='\uf031', time_of_day='Night Conditions Only', url=None, owmcode=801),
31+
27: base.WeatherIcon(condition='Mostly Cloudy', icon='f041', font='\uf041', time_of_day='Night Conditions Only', url=None, owmcode=801),
32+
28: base.WeatherIcon(condition='Light Rain Shower', icon='f02b', font='\uf02b', time_of_day='Night Conditions Only', url=None, owmcode=500),
33+
29: base.WeatherIcon(condition='Light Rain Shower and Flurries', icon='f026', font='\uf026', time_of_day='Night Conditions Only', url=None, owmcode=300),
34+
30: base.WeatherIcon(condition='Light Flurries', icon='f02a', font='\uf02a', time_of_day='Night Conditions Only', url=None, owmcode=600),
35+
31: base.WeatherIcon(condition='Thunderstorm', icon='f02d', font='\uf02d', time_of_day='Night Conditions Only', url=None, owmcode=200),
36+
32: base.WeatherIcon(condition='Blowing Snow', icon='f064', font='\uf064', time_of_day='Day and Night Conditions', url=None, owmcode=600),
37+
33: base.WeatherIcon(condition='Funnel Cloud', icon='f056', font='\uf056', time_of_day='Day and Night Conditions', url=None, owmcode=781),
38+
34: base.WeatherIcon(condition='Tornado', icon='f056', font='\uf056', time_of_day='Day and Night Conditions', url=None, owmcode=781),
39+
35: base.WeatherIcon(condition='Windy', icon='f021', font='\uf021', time_of_day='Day and Night Conditions', url=None, owmcode=430),
40+
36: base.WeatherIcon(condition='Smoke', icon='f062', font='\uf062', time_of_day='Day and Night Conditions', url=None, owmcode=711),
41+
37: base.WeatherIcon(condition='Blowing Dust', icon='f063', font='\uf063', time_of_day='Day and Night Conditions', url=None, owmcode=761),
42+
38: base.WeatherIcon(condition='Thunderstorm with Hail', icon='f01e', font='\uf01e', time_of_day='Day and Night Conditions', url=None, owmcode=200),
43+
39: base.WeatherIcon(condition='Thunderstorm with Dust Storm', icon='f01e', font='\uf01e', time_of_day='Day and Night Conditions', url=None, owmcode=200),
44+
40: base.WeatherIcon(condition='Waterspout', icon='f056', font='\uf056', time_of_day='Day and Night Conditions', url=None, owmcode=781),
45+
41: base.WeatherIcon(condition='N/A', icon='f07b', font='\uf07b', time_of_day='Day and Night Conditions', url=None, owmcode=900),
46+
42: base.WeatherIcon(condition='Humidity', icon='f07a', font='\uf07a', time_of_day='Day and Night Conditions', url=None, owmcode=901),
47+
43: base.WeatherIcon(condition='Rising', icon='f057', font='\uf057', time_of_day='Day and Night Conditions', url=None, owmcode=902),
48+
44: base.WeatherIcon(condition='Falling', icon='f088', font='\uf088', time_of_day='Day and Night Conditions', url=None, owmcode=903),
49+
45: base.WeatherIcon(condition='Steady', icon='f04d', font='\uf04d', time_of_day='Day and Night Conditions', url=None, owmcode=904),
50+
46: base.WeatherIcon(condition='Clear', icon='f00d', font='\uf00d', time_of_day='Day Conditions Only', url=None, owmcode=800),
51+
47: base.WeatherIcon(condition='Cloudy Periods', icon='f013', font='\uf013', time_of_day='Day Conditions Only', url=None, owmcode=801),
52+
48: base.WeatherIcon(condition='Mainly Clear', icon='f02e', font='\uf02e', time_of_day='Night Conditions Only', url=None, owmcode=806)}

0 commit comments

Comments
 (0)