Skip to content

[weathermatrix] Weather normalize #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions lib/binary_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ mv -v ohmyoled ohmyoled-$VERSION/

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

cp -v lib/weather/ecIcons_utf8.csv ohmyoled-$VERSION

cp -v install.sh ohmyoled-$VERSION

cp -vr fonts/ ohmyoled-$VERSION
Expand Down
50 changes: 0 additions & 50 deletions lib/weather/ecIcons_utf8.csv

This file was deleted.

111 changes: 111 additions & 0 deletions lib/weather/normal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env python3
from typing import Dict, Tuple
from datetime import datetime, timedelta
from lib.weather.openweather.weather import OpenWeatherApi
from lib.run import Caller

class NormalizedWeather():

def __init__(self, api_result) -> None:
self.api_result = api_result

@property
def get_api(self):
return self.api_result.get_api

@property
def get_icon(self):
return self.api_result.get_icon

@property
def get_lat_long(self) -> Tuple[float, float]:
return self.api_result.get_lat_long

@property
def get_wind_speed(self) -> int:
return self.api_result.get_wind_speed

@property
def get_daily(self) -> Dict[str, str]:
return self.api_result.get_daily

@property
def get_wind_deg(self) -> int:
return self.api_result.get_wind_deg

@property
def get_precipitation(self) -> int:
return self.api_result.get_precipitation * 100

@property
def get_uv(self) -> int:
return self.api_result.get_uv

@property
def get_place(self) -> str:
return self.api_result.get_place

@property
def get_weather(self) -> Dict[str, str]:
return self.api_result.get_weather

@property
def get_conditions(self) -> str:
return self.api_result.get_conditions

@property
def get_weather_icon(self) -> str:
return self.api_result.get_weather_icon

@property
def get_temp(self) -> int:
return self.api_result.get_temp

@property
def get_feels_like(self) -> int:
return self.api_result.get_feels_like

@property
def get_min_temp(self) -> int:
return self.api_result.get_min_temp

@property
def get_max_temp(self) -> int:
return self.api_result.get_max_temp

@property
def get_humidity(self) -> None:
return self.api_result.get_humidity

@property
def get_wind(self) -> Dict:
return self.api_result.get_wind

@property
def get_time(self) -> datetime:
return self.api_result.get_time

@property
def get_sunrise(self) -> datetime:
return self.api_result.get_sunrise

@property
def get_sunset(self) -> datetime:
return self.api_result.get_sunset

def calculate_duration_of_daylight(self) -> timedelta:
return self.api_result.get_sunset - self.api_result.get_time

class WeatherApi(Caller):

def __init__(self, config) -> None:
super().__init__()
self.config = config

async def run_weather(self):
if self.config['weather']['api'] == "openweather":
open_weather = OpenWeatherApi(self.config)
result = await open_weather.run()
else:
result = ""
return NormalizedWeather(result)
Empty file.
86 changes: 50 additions & 36 deletions lib/weather/weather.py → lib/weather/openweather/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,11 @@
from typing import Dict, Tuple, List
from datetime import datetime
from datetime import timedelta
import lib.weather.weatherbase as base
from lib.weather.weather_icon import weather_icon_mapping
import csv

def get_weather_csv() -> List[Dict[str, str]]:
csv_path = '/etc/ohmyoled/ecIcons_utf8.csv'
return list(csv.DictReader(open(csv_path)))

def build_weather_icons() -> str:
csv = get_weather_csv()
icon = {}
for icn in csv:
icon.update({icn["OWMCode"]: WeatherIcon(icn['OWMCode'], icn['Description'], icn['fontcode'], icn['font'])})
return icon

class WeatherIcon():
def __init__(self, owm_id: str, description: str, fontcode: str, font: str) -> None:
self.owm_id = owm_id
self.description = description
self.fontcode = fontcode
self.font = font

@property
def get_owm_id(self) -> str:
return self.owm_id
@property
def get_description(self) -> str:
return self.description
@property
def get_fontcode(self) -> str:
return self.fontcode
@property
def get_font(self) -> str:
return self.font



class WeatherApi(Runner):
class OpenWeatherApi(Runner):
"""
Weatherapi object
To parse the config file and
Expand Down Expand Up @@ -127,16 +96,18 @@ async def run(self) -> Dict:
api_data = await self.get_data(args)
current_data = await self.get_current_location()
api_data['name'] = current_data['city']
return api_data
return OpenWeather(api_data)

class Weather(Caller):
class OpenWeather(Caller):
"""
Weather object to describe current Polled data
"""
def __init__(self, api: Dict) -> None:
super().__init__()
self.api = api
self.api_json = api
self._api_caller = base.APIWeather.OPENWEATHER
self._lat_long = (self.api['lat'], self.api['lon'])
self._place = self.api_json.get('name')
self._current = self.api_json.get('current')
self._weather = self._current.get('weather')
Expand Down Expand Up @@ -180,6 +151,49 @@ def __repr__(self) -> str:
joined_attrs = ',\n'.join(attrs)
return f"Weather(\n{joined_attrs})"

@property
def get_icon(self):
owm_wxcode: int = int(self._weather[0]['id'])
if owm_wxcode in range(200,299):
# Thunderstorm Class
owm_icon = weather_icon_mapping[17]
elif owm_wxcode in range(300,399):
# Drizzle Class
owm_icon = weather_icon_mapping[23]
elif owm_wxcode in range(500,599):
# Rain Class
owm_icon = weather_icon_mapping[9]
elif owm_wxcode in range(600,699):
# Snow Class
owm_icon = weather_icon_mapping[13]
elif owm_wxcode in range(700, 780):
owm_icon = weather_icon_mapping[36]
elif owm_wxcode == 800:
# Sunny
if self._sunset > datetime.now():
owm_icon = weather_icon_mapping[0]
else:
owm_icon = weather_icon_mapping[48]

elif owm_wxcode in range(801,805):
# Rain Class
if self._sunset > datetime.now():
owm_icon = weather_icon_mapping[3]
else:
owm_icon = weather_icon_mapping[48]
else:
owm_icon = weather_icon_mapping[0]

return owm_icon

@property
def get_api(self):
return self._api_caller

@property
def get_lat_long(self) -> Tuple[float, float]:
return self._lat_long

@property
def get_wind_speed(self) -> int:
return self._wind_speed
Expand Down
52 changes: 52 additions & 0 deletions lib/weather/weather_icon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import lib.weather.weatherbase as base

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