various improvements
Cleaned up code, improved logging, fixed an issue where forecast time would show UTC time instead of local time, improved layout on dynamic heights. More evenly distributed rows, simplified some code, removed non-required validate function.
This commit is contained in:
parent
598d2b2614
commit
19baf57c6c
@ -45,37 +45,31 @@ class Weather(inkycal_module):
|
||||
"round_temperature": {
|
||||
"label":"Round temperature to the nearest degree?",
|
||||
"options": [True, False],
|
||||
"default" : True
|
||||
},
|
||||
|
||||
"round_windspeed": {
|
||||
"label":"Round windspeed?",
|
||||
"options": [True, False],
|
||||
"default": True
|
||||
},
|
||||
|
||||
"forecast_interval": {
|
||||
"label":"Please select the forecast interval",
|
||||
"options": ["daily", "hourly"],
|
||||
"default": "daily"
|
||||
},
|
||||
|
||||
"units": {
|
||||
"label": "Which units should be used?",
|
||||
"options": ["metric", "imperial"],
|
||||
"default": "metric"
|
||||
},
|
||||
|
||||
"hour_format": {
|
||||
"label": "Which hour format do you prefer?",
|
||||
"options": [12, 24],
|
||||
"default": 24
|
||||
"options": [24, 12],
|
||||
},
|
||||
|
||||
"use_beaufort": {
|
||||
"label": "Use beaufort scale for windspeed?",
|
||||
"options": [True, False],
|
||||
"default": True
|
||||
},
|
||||
|
||||
}
|
||||
@ -115,30 +109,6 @@ class Weather(inkycal_module):
|
||||
print(f"{filename} loaded")
|
||||
|
||||
|
||||
def _validate(self):
|
||||
|
||||
if not isinstance(self.api_key, str):
|
||||
print(f'api_key should be a string, not {self.api_key}')
|
||||
|
||||
if not isinstance(self.round_temperature, bool):
|
||||
print(f'round_temperature should be a boolean, not {self.round_temperature}')
|
||||
|
||||
if not isinstance(self.round_windspeed, bool):
|
||||
print(f'round_windspeed should be a boolean, not {self.round_windspeed}')
|
||||
|
||||
if not isinstance(self.forecast_interval, int):
|
||||
print(f'forecast_interval should be a boolean, not {self.forecast_interval}')
|
||||
|
||||
if not isinstance(self.units, str):
|
||||
print(f'units should be a boolean, not {self.units}')
|
||||
|
||||
if not isinstance(self.hour_format, int):
|
||||
print(f'hour_format should be a int, not {self.hour_format}')
|
||||
|
||||
if not isinstance(self.use_beaufort, bool):
|
||||
print(f'use_beaufort should be a int, not {self.use_beaufort}')
|
||||
|
||||
|
||||
def generate_image(self):
|
||||
"""Generate image for this module"""
|
||||
|
||||
@ -156,7 +126,8 @@ class Weather(inkycal_module):
|
||||
if internet_available() == True:
|
||||
logger.info('Connection test passed')
|
||||
else:
|
||||
raise Exception('Network could not be reached :(')
|
||||
logger.exception('Network could not be reached :(')
|
||||
raise
|
||||
|
||||
def get_moon_phase():
|
||||
"""Calculate the current (approximate) moon phase"""
|
||||
@ -209,6 +180,7 @@ class Weather(inkycal_module):
|
||||
size = 8
|
||||
font = ImageFont.truetype(font.path, size)
|
||||
text_width, text_height = font.getsize(text)
|
||||
|
||||
while (text_width < int(box_width * 0.9) and
|
||||
text_height < int(box_height * 0.9)):
|
||||
size += 1
|
||||
@ -247,14 +219,16 @@ class Weather(inkycal_module):
|
||||
# Calculate size rows and columns
|
||||
col_width = im_width // 7
|
||||
|
||||
if (im_height // 3) > col_width//2:
|
||||
row_height = (im_height // 4)
|
||||
# Ratio width height
|
||||
image_ratio = im_width / im_height
|
||||
|
||||
if image_ratio >= 4:
|
||||
row_height = im_height // 3
|
||||
else:
|
||||
row_height = (im_height // 3)
|
||||
logger.info('Please consider decreasing the height.')
|
||||
row_height = int( (im_height* (1-im_height/im_width)) / 3 )
|
||||
|
||||
|
||||
# Adjust the fontsize to make use of most free space
|
||||
# self.font = auto_fontsize(self.font, row_height)
|
||||
logger.debug(f"row_height: {row_height} | col_width: {col_width}")
|
||||
|
||||
# Calculate spacings for better centering
|
||||
spacing_top = int( (im_width % col_width) / 2 )
|
||||
@ -275,12 +249,28 @@ class Weather(inkycal_module):
|
||||
col7 = col6 + col_width
|
||||
|
||||
# Calculate the y-axis position of each row
|
||||
row1 = spacing_left
|
||||
row2 = row1 + row_height
|
||||
row3 = row2 + row_height
|
||||
line_gap = int((im_height - spacing_top - 3*row_height) // 4)
|
||||
|
||||
row1 = line_gap
|
||||
row2 = row1 + line_gap + row_height
|
||||
row3 = row2+ line_gap + row_height
|
||||
|
||||
# Draw lines on each row and border
|
||||
############################################################################
|
||||
## draw = ImageDraw.Draw(im_black)
|
||||
## draw.line((0, 0, im_width, 0), fill='red')
|
||||
## draw.line((0, im_height-1, im_width, im_height-1), fill='red')
|
||||
## draw.line((0, row1, im_width, row1), fill='black')
|
||||
## draw.line((0, row1+row_height, im_width, row1+row_height), fill='black')
|
||||
## draw.line((0, row2, im_width, row2), fill='black')
|
||||
## draw.line((0, row2+row_height, im_width, row2+row_height), fill='black')
|
||||
## draw.line((0, row3, im_width, row3), fill='black')
|
||||
## draw.line((0, row3+row_height, im_width, row3+row_height), fill='black')
|
||||
############################################################################
|
||||
|
||||
|
||||
# Positions for current weather details
|
||||
weather_icon_pos = (col1, row1)
|
||||
weather_icon_pos = (col1, 0)
|
||||
temperature_icon_pos = (col2, row1)
|
||||
temperature_pos = (col2+icon_small, row1)
|
||||
humidity_icon_pos = (col2, row2)
|
||||
@ -297,29 +287,31 @@ class Weather(inkycal_module):
|
||||
|
||||
# Positions for forecast 1
|
||||
stamp_fc1 = (col4, row1)
|
||||
icon_fc1 = (col4, row2)
|
||||
icon_fc1 = (col4, row1+row_height)
|
||||
temp_fc1 = (col4, row3)
|
||||
|
||||
# Positions for forecast 2
|
||||
stamp_fc2 = (col5, row1)
|
||||
icon_fc2 = (col5, row2)
|
||||
icon_fc2 = (col5, row1+row_height)
|
||||
temp_fc2 = (col5, row3)
|
||||
|
||||
# Positions for forecast 3
|
||||
stamp_fc3 = (col6, row1)
|
||||
icon_fc3 = (col6, row2)
|
||||
icon_fc3 = (col6, row1+row_height)
|
||||
temp_fc3 = (col6, row3)
|
||||
|
||||
# Positions for forecast 4
|
||||
stamp_fc4 = (col7, row1)
|
||||
icon_fc4 = (col7, row2)
|
||||
icon_fc4 = (col7, row1+row_height)
|
||||
temp_fc4 = (col7, row3)
|
||||
|
||||
# Create current-weather and weather-forecast objects
|
||||
if self.location.isdigit():
|
||||
logging.debug('looking up location by ID')
|
||||
weather = self.owm.weather_at_id(int(self.location)).weather
|
||||
forecast = self.owm.forecast_at_id(int(self.location), '3h')
|
||||
else:
|
||||
logging.debug('looking up location by string')
|
||||
weather = self.owm.weather_at_place(self.location).weather
|
||||
forecast = self.owm.forecast_at_place(self.location, '3h')
|
||||
|
||||
@ -333,12 +325,16 @@ class Weather(inkycal_module):
|
||||
elif self.units == 'imperial':
|
||||
temp_unit = 'fahrenheit'
|
||||
|
||||
logging.debug(f'temperature unit: {temp_unit}')
|
||||
logging.debug(f'decimals temperature: {dec_temp} | decimals wind: {dec_wind}')
|
||||
|
||||
# Get current time
|
||||
now = arrow.utcnow()
|
||||
|
||||
if self.forecast_interval == 'hourly':
|
||||
|
||||
logger.debug("getting hourly forecasts")
|
||||
|
||||
# Forecasts are provided for every 3rd full hour
|
||||
# find out how many hours there are until the next 3rd full hour
|
||||
if (now.hour % 3) != 0:
|
||||
@ -364,8 +360,8 @@ class Weather(inkycal_module):
|
||||
fc_data['fc'+str(forecasts.index(forecast)+1)] = {
|
||||
'temp':temp,
|
||||
'icon':icon,
|
||||
'stamp': forecast_timings[forecasts.index(forecast)].format('H.00'
|
||||
if self.hour_format == 24 else 'h a')
|
||||
'stamp': forecast_timings[forecasts.index(forecast)].to(
|
||||
get_system_tz()).format('H.00' if self.hour_format == 24 else 'h a')
|
||||
}
|
||||
|
||||
elif self.forecast_interval == 'daily':
|
||||
@ -425,11 +421,15 @@ class Weather(inkycal_module):
|
||||
sunrise_raw = arrow.get(weather.sunrise_time()).to(self.timezone)
|
||||
sunset_raw = arrow.get(weather.sunset_time()).to(self.timezone)
|
||||
|
||||
logger.debug(f'weather_icon: {weather_icon}')
|
||||
|
||||
if self.hour_format == 12:
|
||||
logger.debug('using 12 hour format for sunrise/sunset')
|
||||
sunrise = sunrise_raw.format('h:mm a')
|
||||
sunset = sunset_raw.format('h:mm a')
|
||||
|
||||
elif self.hour_format == 24:
|
||||
logger.debug('using 24 hour format for sunrise/sunset')
|
||||
sunrise = sunrise_raw.format('H:mm')
|
||||
sunset = sunset_raw.format('H:mm')
|
||||
|
||||
@ -441,20 +441,22 @@ class Weather(inkycal_module):
|
||||
elif self.use_beaufort == False:
|
||||
|
||||
if self.units == 'metric':
|
||||
logging.debug('getting windspeed in metric unit')
|
||||
wind = str(weather.wind(unit='meters_sec')['speed']) + 'm/s'
|
||||
|
||||
elif self.units == 'imperial':
|
||||
logging.debug('getting windspeed in imperial unit')
|
||||
wind = str(weather.wind(unit='miles_hour')['speed']) + 'miles/h'
|
||||
|
||||
dec = decimal.Decimal
|
||||
moonphase = get_moon_phase()
|
||||
|
||||
# Fill weather details in col 1 (current weather icon)
|
||||
draw_icon(im_colour, weather_icon_pos, (icon_large, icon_large),
|
||||
draw_icon(im_colour, weather_icon_pos, (col_width, im_height),
|
||||
weathericons[weather_icon])
|
||||
|
||||
# Fill weather details in col 2 (temp, humidity, wind)
|
||||
draw_icon(im_colour, temperature_icon_pos, (row_height, row_height),
|
||||
draw_icon(im_colour, temperature_icon_pos, (icon_small, row_height),
|
||||
'\uf053')
|
||||
|
||||
if is_negative(temperature):
|
||||
@ -464,7 +466,7 @@ class Weather(inkycal_module):
|
||||
write(im_black, temperature_pos, (col_width-icon_small, row_height),
|
||||
temperature, font = self.font)
|
||||
|
||||
draw_icon(im_colour, humidity_icon_pos, (row_height, row_height),
|
||||
draw_icon(im_colour, humidity_icon_pos, (icon_small, row_height),
|
||||
'\uf07a')
|
||||
|
||||
write(im_black, humidity_pos, (col_width-icon_small, row_height),
|
||||
@ -480,33 +482,38 @@ class Weather(inkycal_module):
|
||||
draw_icon(im_colour, moonphase_pos, (col_width, row_height), moonphase)
|
||||
|
||||
draw_icon(im_colour, sunrise_icon_pos, (icon_small, icon_small), '\uf051')
|
||||
write(im_black, sunrise_time_pos, (col_width-icon_small, icon_small),
|
||||
write(im_black, sunrise_time_pos, (col_width-icon_small, row_height),
|
||||
sunrise, font = self.font)
|
||||
|
||||
draw_icon(im_colour, sunset_icon_pos, (icon_small, icon_small), '\uf052')
|
||||
write(im_black, sunset_time_pos, (col_width-icon_small, icon_small), sunset,
|
||||
write(im_black, sunset_time_pos, (col_width-icon_small, row_height), sunset,
|
||||
font = self.font)
|
||||
|
||||
# Add the forecast data to the correct places
|
||||
for pos in range(1, len(fc_data)+1):
|
||||
stamp = fc_data['fc'+str(pos)]['stamp']
|
||||
icon = weathericons[fc_data['fc'+str(pos)]['icon']]
|
||||
temp = fc_data['fc'+str(pos)]['temp']
|
||||
stamp = fc_data[f'fc{pos}']['stamp']
|
||||
|
||||
write(im_black, eval('stamp_fc'+str(pos)), (col_width, row_height),
|
||||
icon = weathericons[fc_data[f'fc{pos}']['icon']]
|
||||
temp = fc_data[f'fc{pos}']['temp']
|
||||
|
||||
write(im_black, eval(f'stamp_fc{pos}'), (col_width, row_height),
|
||||
stamp, font = self.font)
|
||||
draw_icon(im_colour, eval('icon_fc'+str(pos)), (col_width, row_height),
|
||||
draw_icon(im_colour, eval(f'icon_fc{pos}'), (col_width, row_height+line_gap*2),
|
||||
icon)
|
||||
write(im_black, eval('temp_fc'+str(pos)), (col_width, row_height),
|
||||
write(im_black, eval(f'temp_fc{pos}'), (col_width, row_height),
|
||||
temp, font = self.font)
|
||||
|
||||
|
||||
border_h = row3 + row_height
|
||||
border_w = col_width - 3 #leave 3 pixels gap
|
||||
|
||||
# Add borders around each sub-section
|
||||
draw_border(im_black, (col1, row1), (col_width*3, im_height),
|
||||
shrinkage=(0.02,0.1))
|
||||
draw_border(im_black, (col4, row1), (col_width, im_height))
|
||||
draw_border(im_black, (col5, row1), (col_width, im_height))
|
||||
draw_border(im_black, (col6, row1), (col_width, im_height))
|
||||
draw_border(im_black, (col7, row1), (col_width, im_height))
|
||||
draw_border(im_black, (col1, row1), (col_width*3 - 3, border_h),
|
||||
shrinkage=(0,0))
|
||||
|
||||
for _ in range(4,8):
|
||||
draw_border(im_black, (eval(f'col{_}'), row1), (border_w, border_h),
|
||||
shrinkage=(0,0))
|
||||
|
||||
# return the images ready for the display
|
||||
return im_black, im_colour
|
||||
|
Loading…
Reference in New Issue
Block a user