diff --git a/lib/binary_build.sh b/lib/binary_build.sh index f3516c1..6db5c18 100755 --- a/lib/binary_build.sh +++ b/lib/binary_build.sh @@ -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 diff --git a/lib/weather/ecIcons_utf8.csv b/lib/weather/ecIcons_utf8.csv deleted file mode 100755 index a4f1c65..0000000 --- a/lib/weather/ecIcons_utf8.csv +++ /dev/null @@ -1,50 +0,0 @@ -encode,Code,ForecastCode,OWMCode,Description,Represents,fontcode,font -UTF8,0,0,800,Sunny,Day Conditions Only,f00d, -UTF8,1,2,800,Mainly Sunny,Day Conditions Only,f00d, -UTF8,2,1,801,Partly Cloudy,Day Conditions Only,f002, -UTF8,3,4,801,Mostly Cloudy,Day Conditions Only,f013, -UTF8,6,6,500,Light Rain Shower,Day Conditions Only,f008, -UTF8,7,7,300,Light Rain Shower and Flurries,Day Conditions Only,f006, -UTF8,8,8,600,Light Flurries,Day Conditions Only,f00a, -UTF8,10,10,801,Cloudy,Day and Night Conditions,f013, -UTF8,11,13,500,Precipitation,Day and Night Conditions,f01c, -UTF8,12,13,500,Rain,Day and Night Conditions,f019, -UTF8,13,12,500,Rain Shower,Day and Night Conditions,f01a, -UTF8,14,14,500,Freezing Rain,Day and Night Conditions,f0b5, -UTF8,15,15,600,Rain and Snow,Day and Night Conditions,f017, -UTF8,16,16,600,Snow,Day and Night Conditions,f01b, -UTF8,16,17,600,Snow,Day and Night Conditions,f01b, -UTF8,17,17,600,Snow,Day and Night Conditions,f01b, -UTF8,18,17,600,Heavy Snow,Day and Night Conditions,f01b, -UTF8,19,9,200,Thunderstorm,Day Conditions Only,f01e, -UTF8,23,23,721,Haze,Day and Night Conditions,f0b6, -UTF8,24,24,741,Fog,Day and Night Conditions,f014, -UTF8,25,17,600,Drifting Snow,Day and Night Conditions,f064, -UTF8,26,27,600,Ice Crystals,Day and Night Conditions,f076, -UTF8,27,19,600,Hail,Day and Night Conditions,f015, -UTF8,28,28,300,Drizzle,Day and Night Conditions,f01c, -UTF8,30,30,800,Clear,Night Conditions Only,f02e, -UTF8,31,31,800,Mainly Clear,Night Conditions Only,f02e, -UTF8,32,32,801,Partly Cloudy,Night Conditions Only,f031, -UTF8,33,33,801,Mostly Cloudy,Night Conditions Only,f041, -UTF8,36,36,500,Light Rain Shower,Night Conditions Only,f02b, -UTF8,37,37,300,Light Rain Shower and Flurries,Night Conditions Only,f026, -UTF8,38,38,600,Light Flurries,Night Conditions Only,f02a, -UTF8,39,39,200,Thunderstorm,Night Conditions Only,f02d, -UTF8,40,40,600,Blowing Snow,Day and Night Conditions,f064, -UTF8,41,43,781,Funnel Cloud,Day and Night Conditions,f056, -UTF8,42,43,781,Tornado,Day and Night Conditions,f056, -UTF8,43,43,430,Windy,Day and Night Conditions,f021, -UTF8,44,44,711,Smoke,Day and Night Conditions,f062, -UTF8,45,44,761,Blowing Dust,Day and Night Conditions,f063, -UTF8,46,9,200,Thunderstorm with Hail,Day and Night Conditions,f01e, -UTF8,47,9,200,Thunderstorm with Dust Storm,Day and Night Conditions,f01e, -UTF8,48,43,781,Waterspout,Day and Night Conditions,f056, -UTF8,90,29,900,N/A,Day and Night Conditions,f07b, -UTF8,91,91,901,Humidity,Day and Night Conditions,f07a, -UTF8,92,92,902,Rising,Day and Night Conditions,f057, -UTF8,93,93,903,Falling,Day and Night Conditions,f088, -UTF8,94,94,904,Steady,Day and Night Conditions,f04d, -UTF8,1,5,800,Clear,Day Conditions Only,f00d, -UTF8,3,3,801,Cloudy Periods,Day Conditions Only,f013, -UTF8,31,31,806,Mainly Clear,Night Conditions Only,f02e, diff --git a/lib/weather/normal.py b/lib/weather/normal.py new file mode 100644 index 0000000..a00de98 --- /dev/null +++ b/lib/weather/normal.py @@ -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) \ No newline at end of file diff --git a/lib/weather/openweather/__init__.py b/lib/weather/openweather/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/weather/weather.py b/lib/weather/openweather/weather.py similarity index 84% rename from lib/weather/weather.py rename to lib/weather/openweather/weather.py index dec13df..7b17ab6 100755 --- a/lib/weather/weather.py +++ b/lib/weather/openweather/weather.py @@ -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 @@ -127,9 +96,9 @@ 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 """ @@ -137,6 +106,8 @@ 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') @@ -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 diff --git a/lib/weather/weather_icon.py b/lib/weather/weather_icon.py new file mode 100644 index 0000000..dfb7f64 --- /dev/null +++ b/lib/weather/weather_icon.py @@ -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)} \ No newline at end of file diff --git a/lib/weather/weatherbase.py b/lib/weather/weatherbase.py new file mode 100644 index 0000000..003e862 --- /dev/null +++ b/lib/weather/weatherbase.py @@ -0,0 +1,58 @@ +from dataclasses import dataclass +from datetime import datetime +from typing import Tuple, Union +from enum import Enum + +class APIWeather(Enum): + OPENWEATHER = 1 + # National Weather Service + NWS = 2 + +@dataclass(repr=True) +class WeatherIcon: + condition: str + icon: str + font: str + time_of_day: str + url: str = None + owmcode: int = None + + def request_url_icon(self): + pass + +@dataclass(repr=True) +class CurrentWeather(): + conditions: str + temp: Union[int, float] + feels_like: Union[int, float] + wind_speed: int + humidity: int + perciptation_chance: int + uv: int + wind_direction: int = None + weather_icon: WeatherIcon = None + +@dataclass(repr=True) +class DayForcast: + todayhigh: int + todaylow: int + sunrise: datetime + sunset: datetime + +@dataclass(repr=True) +class WeatherBase(): + api: APIWeather + # (lat, lng) + location: Tuple[float, float] + location_name: str + current: CurrentWeather + dayforcast: DayForcast + +@dataclass(repr=True) +class Weather(): + api: APIWeather + # (lat, lng) + location: Tuple[float, float] + location_name: str + current: CurrentWeather + dayforcast: DayForcast \ No newline at end of file diff --git a/lib/weather/weathergov/nws.py b/lib/weather/weathergov/nws.py new file mode 100644 index 0000000..e69de29 diff --git a/main.py b/main.py index 87a3790..0903fb6 100755 --- a/main.py +++ b/main.py @@ -10,7 +10,7 @@ RGBMatrix ) from lib.upgrade.upgrade import Upgrader -from lib.weather.weather import WeatherApi +from lib.weather.normal import WeatherApi from matrix.stock.stockmatrix import StockMatrix from lib.stock.stocks import StockApi from lib.sports.sports import SportApi diff --git a/matrix/weathermatrix.py b/matrix/weathermatrix.py index 466a6cf..e84a817 100755 --- a/matrix/weathermatrix.py +++ b/matrix/weathermatrix.py @@ -5,22 +5,42 @@ from datetime import datetime from PIL import ImageFont from matrix.matrix import Matrix -from lib.weather.weather import ( - Weather, - build_weather_icons -) +import lib.weather.weatherbase as base +from lib.weather.normal import NormalizedWeather class WeatherMatrix(Matrix): def __init__(self, matrix, api: Dict, logger) -> None: self.matrix = matrix self.api = api self.logger = logger - self.icons = build_weather_icons() def __str__(self) -> str: return "WeatherMatrix" - async def poll_api(self) -> Weather: - return Weather(await self.api.run()) + + async def poll_api(self): + result: NormalizedWeather = await self.api.run_weather() + return base.Weather( + api=result.get_api, + location=result.get_lat_long, + location_name=result.get_place, + current=base.CurrentWeather( + conditions=result.get_conditions, + temp=result.get_temp, + feels_like=result.get_feels_like, + wind_speed=result.get_wind_speed, + humidity=result.get_humidity, + perciptation_chance=result.get_precipitation, + uv=result.get_uv, + wind_direction=result.get_wind_deg, + weather_icon=result.get_icon, + ), + dayforcast=base.DayForcast( + todayhigh=result.get_max_temp, + todaylow=result.get_min_temp, + sunrise=result.get_sunrise, + sunset=result.get_sunset + ) + ) def get_temp_color(self, temp: int) -> Tuple[int, int, int]: if temp >= 100: @@ -37,84 +57,81 @@ def get_temp_color(self, temp: int) -> Tuple[int, int, int]: def render_temp(self, api) -> None: font: ImageFont = ImageFont.truetype("/usr/share/fonts/retro_computer.ttf", 7) self.draw_text((0, 8), "T:", font=font) - self.draw_text((10, 8), f"{str(int(api.get_temp))}F", font=font, fill=self.get_temp_color(int(api.get_temp))) + self.draw_text((10, 8), f"{str(int(api.current.temp))}F", font=font, fill=self.get_temp_color(int(api.current.temp))) self.draw_text((30, 8), "R:", font=font) - self.draw_text((40, 8), f"{str(int(api.get_feels_like))}F", font=font, fill=self.get_temp_color(int(api.get_temp))) + self.draw_text((40, 8), f"{str(int(api.current.feels_like))}F", font=font, fill=self.get_temp_color(int(api.current.feels_like))) self.draw_text((1, 18), f"H:", font=font) - self.draw_text((10, 18), f"{str(int(api.get_max_temp))}F", font=font, fill=self.get_temp_color(int(api.get_temp))) + self.draw_text((10, 18), f"{str(int(api.dayforcast.todayhigh))}F", font=font, fill=self.get_temp_color(int(api.dayforcast.todayhigh))) self.draw_text((30, 18), f"L:", font=font) - self.draw_text((40, 18), f"{str(int(api.get_min_temp))}F", font=font, fill=self.get_temp_color(int(api.get_temp))) + self.draw_text((40, 18), f"{str(int(api.dayforcast.todaylow))}F", font=font, fill=self.get_temp_color(int(api.dayforcast.todaylow))) - def render_icon(self, api: Weather) -> None: + def render_icon(self, api) -> None: font: ImageFont = ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 9) - owm_wxcode: int = int(api.get_weather[0]['id']) + owm_wxcode: int = api.current.weather_icon.owmcode if owm_wxcode in range(200,299): # Thunderstorm Class - owm_icon = 200 color: Tuple[int] = (254, 204, 1) elif owm_wxcode in range(300,399): # Drizzle Class - owm_icon = 300 color: Tuple[int] = (220,220,220) elif owm_wxcode in range(500,599): # Rain Class - owm_icon = 500 color: Tuple[int] = (108, 204, 228) elif owm_wxcode in range(600,699): # Snow Class - owm_icon = 600 color: Tuple[int] = (255,255,255) elif owm_wxcode in range(700, 780): - owm_icon = 711 color: Tuple[int] = (192, 192, 192) elif owm_wxcode == 800: # Sunny if api.get_sunset > datetime.now(): - owm_icon = 800 color: Tuple[int] = (220, 149, 3) else: - owm_icon = 806 color: Tuple[int] = (255,255,255) elif owm_wxcode in range(801,805): - # Rain Class - owm_icon = 801 color: Tuple[int] = (220,220,220) else: owm_icon = owm_wxcode - weather_icon = self.icons[str(owm_icon)] - self.draw_text((50, 0), weather_icon.get_font, font, fill=color) + self.draw_text((50, 0), api.current.weather_icon.font, font, fill=color) - def render_location(self, api: Weather) -> None: + def render_location(self, api: base.Weather, xpos) -> None: font = ImageFont.truetype("/usr/share/fonts/04B_03B_.TTF",8) - self.draw_text((2, 1), api.get_place, font, (0, 254, 0)) + self.draw_text((-xpos, 1), api.location_name, font, (0, 254, 0)) - def render_humidity (self, api: Weather) -> None: + def render_humidity (self, api: base.Weather) -> None: font = ImageFont.truetype("/usr/share/fonts/04B_03B_.TTF", 8) self.draw_text((2, 8), "H:", font) - self.draw_text((10, 8), f"{api.get_humidity}%", font, fill=(7, 250, 246)) + self.draw_text((10, 8), f"{api.current.humidity}%", font, fill=(7, 250, 246)) self.draw_text((27, 8), f"P:", font) - self.draw_text((34, 8), f"{int(api.get_precipitation)}%", font, fill=(7, 250, 246)) + self.draw_text((34, 8), f"{int(api.current.perciptation_chance)}%", font, fill=(7, 250, 246)) - def render_wind(self, api: Weather) -> None: + def render_wind(self, api: base.Weather) -> None: font = ImageFont.truetype("/usr/share/fonts/04B_03B_.TTF", 8) - speed = api.get_wind_speed - deg = api.get_wind_deg + speed = api.current.wind_speed + deg = api.current.wind_direction self.draw_text((1, 12), "\uf050", font=ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 9)) self.draw_text((15, 15), f"{str(int(deg))}", font, fill=(201, 1, 253)) - self.draw_text((30, 13), "\uf042", font=ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 9), fill=(201, 1, 253)) + if len(str(int(deg))) == 3: + self.draw_text((30, 13), "\uf042", font=ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 9), fill=(201, 1, 253)) + elif len(str(int(deg))) == 2: + self.draw_text((29, 13), "\uf042", font=ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 9), fill=(201, 1, 253)) + else: + self.draw_text((28, 13), "\uf042", font=ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 9), fill=(201, 1, 253)) self.draw_text((36, 15), f"{str(int(speed))}mph", font, fill=(201, 1, 253)) - def render_time(self, api: Weather) -> None: + def render_time(self, api) -> None: font: ImageFont = ImageFont.truetype("/usr/share/fonts/04B_03B_.TTF", 8) - sunrise: datetime = api.get_sunrise.strftime("%H:%M") - sunset: datetime = api.get_sunset.strftime("%H:%M") + sunrise: datetime = api.dayforcast.sunrise.strftime("%H:%M") + sunset: datetime = api.dayforcast.sunset.strftime("%H:%M") self.draw_text((1, 18), "\uf058", font=ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 11), fill=(255, 255, 0)) self.draw_text((7, 23), sunrise, font=font) self.draw_text((35, 18), "\uf044", font=ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 11), fill=(255, 145, 0)) self.draw_text((40, 23), sunset, font=font) - def render_conditions(self, api: Weather, xpos: int) -> None: - self.draw_text((-xpos, 26), f"Conditions: {api.get_conditions}", font=ImageFont.truetype("/usr/share/fonts/04B_03B_.TTF", 8), fill=(255,255,255)) - async def render(self, api: Weather, loop) -> None: + + def render_conditions(self, api, xpos: int) -> None: + self.draw_text((-xpos, 26), f"Conditions: {api.current.conditions}", font=ImageFont.truetype("/usr/share/fonts/04B_03B_.TTF", 8), fill=(255,255,255)) + + async def render(self, api , loop) -> None: self.logger.info("Rendering Weather Matrix") self.logger.debug("Clearing Image") self.clear() @@ -125,7 +142,7 @@ async def render(self, api: Weather, loop) -> None: self.reload_image() self.render_temp(api) self.render_icon(api) - self.render_location(api) + self.render_location(api, xpos) self.render_conditions(api, xpos) xpos += 1 await self.render_image() @@ -133,14 +150,14 @@ async def render(self, api: Weather, loop) -> None: self.reload_image() self.render_temp(api) self.render_icon(api) - self.render_location(api) + self.render_location(api, 0) self.render_conditions(api, 0) await self.render_image() time.sleep(25) self.clear() self.logger.debug("Reloading Image in matrix") self.reload_image() - self.render_location(api) + self.render_location(api, 0) self.render_icon(api) self.render_humidity(api) self.render_wind(api)