add daily forecast section to fullscreen weather
This commit is contained in:
parent
4c74094d53
commit
883be28f5a
@ -383,7 +383,7 @@ class Fullweather(inkycal_module):
|
|||||||
|
|
||||||
def addHourlyForecast(self):
|
def addHourlyForecast(self):
|
||||||
"""
|
"""
|
||||||
Adds a plot for temperature and amount of rain for the upcoming hours
|
Adds a plot for temperature and amount of rain for the upcoming hours to the upper right section
|
||||||
"""
|
"""
|
||||||
## Create drawing object for image
|
## Create drawing object for image
|
||||||
image_draw = ImageDraw.Draw(self.image)
|
image_draw = ImageDraw.Draw(self.image)
|
||||||
@ -462,6 +462,117 @@ class Fullweather(inkycal_module):
|
|||||||
plot_y = title_y + 30
|
plot_y = title_y + 30
|
||||||
self.image.paste(hourly_forecast_plot, (plot_x, plot_y))
|
self.image.paste(hourly_forecast_plot, (plot_x, plot_y))
|
||||||
|
|
||||||
|
def addDailyForecast(self):
|
||||||
|
"""
|
||||||
|
Adds daily weather forecasts to the lower right section
|
||||||
|
"""
|
||||||
|
## Create drawing object for image
|
||||||
|
image_draw = ImageDraw.Draw(self.image)
|
||||||
|
|
||||||
|
## Draw daily chart title
|
||||||
|
title_y = int(self.height / 2) # Y-coordinate of the title
|
||||||
|
chartTitleFont = self.get_font(self.font_family, "Bold", self.font_size)
|
||||||
|
image_draw.text((self.left_section_width + 20, title_y), self.weekly_title, font=chartTitleFont, fill=0)
|
||||||
|
|
||||||
|
# Define the parameters
|
||||||
|
number_of_forecast_days = 5 # including today
|
||||||
|
# Spread evenly, starting from title width
|
||||||
|
rectangle_width = int((self.width - (self.left_section_width + 40)) / number_of_forecast_days)
|
||||||
|
# Maximum height for each rectangle (avoid overlapping with title)
|
||||||
|
rectangle_height = int(self.height / 2 - 20)
|
||||||
|
|
||||||
|
# Rain icon is static
|
||||||
|
rainIcon = Image.open(os.path.join(icons_dir, "rain-chance.bmp"))
|
||||||
|
rainIcon.convert("L")
|
||||||
|
rainIcon = ImageOps.invert(rainIcon)
|
||||||
|
weeklyRainIcon = rainIcon.resize((20, 20))
|
||||||
|
|
||||||
|
# Loop through the upcoming days' data and create rectangles
|
||||||
|
for i in range(number_of_forecast_days):
|
||||||
|
x_rect = self.left_section_width + 20 + i * rectangle_width # Start from the title width
|
||||||
|
y_rect = int(self.height / 2 + 30)
|
||||||
|
|
||||||
|
day_data = owm_forecasts.get_forecast_for_day(days_from_today=i, hourly_forecasts=self.hourly_forecasts)
|
||||||
|
rect = Image.new("RGBA", (int(rectangle_width), int(rectangle_height)), (255, 255, 255))
|
||||||
|
rect_draw = ImageDraw.Draw(rect)
|
||||||
|
|
||||||
|
# Date string: Day of week on line 1, date on line 2
|
||||||
|
short_day_font = self.get_font(self.font_family, "ExtraBold", self.font_size + 4)
|
||||||
|
short_month_day_font = self.get_font(self.font_family, "Bold", self.font_size - 4)
|
||||||
|
short_day_name = datetime.fromtimestamp(day_data["datetime"]).strftime("%a")
|
||||||
|
short_month_day = datetime.fromtimestamp(day_data["datetime"]).strftime("%b %d")
|
||||||
|
short_day_name_text = rect_draw.textbbox((0, 0), short_day_name, font=short_day_font)
|
||||||
|
short_month_day_text = rect_draw.textbbox((0, 0), short_month_day, font=short_month_day_font)
|
||||||
|
day_name_x = (rectangle_width - short_day_name_text[2] + short_day_name_text[0]) / 2
|
||||||
|
short_month_day_x = (rectangle_width - short_month_day_text[2] + short_month_day_text[0]) / 2
|
||||||
|
rect_draw.text((day_name_x, 0), short_day_name, fill=0, font=short_day_font)
|
||||||
|
rect_draw.text(
|
||||||
|
(short_month_day_x, 30),
|
||||||
|
short_month_day,
|
||||||
|
fill=0,
|
||||||
|
font=short_month_day_font,
|
||||||
|
)
|
||||||
|
|
||||||
|
## Min and max temperature split into diagonal placement
|
||||||
|
min_temp = day_data["temp_min"]
|
||||||
|
max_temp = day_data["temp_max"]
|
||||||
|
temp_text_min = f"{min_temp:.0f}{self.tempDispUnit}"
|
||||||
|
temp_text_max = f"{max_temp:.0f}{self.tempDispUnit}"
|
||||||
|
rect_temp_font = self.get_font(self.font_family, "ExtraBold", self.font_size + 4)
|
||||||
|
temp_x_offset = 20
|
||||||
|
# this is upper left: max temperature
|
||||||
|
temp_text_max_x = temp_x_offset
|
||||||
|
temp_text_max_y = int(rectangle_height * 0.25)
|
||||||
|
# this is lower right: min temperature
|
||||||
|
temp_text_min_bbox = rect_draw.textbbox((0, 0), temp_text_min, font=rect_temp_font)
|
||||||
|
temp_text_min_x = (
|
||||||
|
int((rectangle_width - temp_text_min_bbox[2] + temp_text_min_bbox[0]) / 2) + temp_x_offset + 7
|
||||||
|
)
|
||||||
|
temp_text_min_y = int(rectangle_height * 0.33)
|
||||||
|
rect_draw.text((temp_text_min_x, temp_text_min_y), temp_text_min, fill=0, font=rect_temp_font)
|
||||||
|
rect_draw.text(
|
||||||
|
(temp_text_max_x, temp_text_max_y),
|
||||||
|
temp_text_max,
|
||||||
|
fill=0,
|
||||||
|
font=rect_temp_font,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Weather icon for the day
|
||||||
|
icon_code = day_data["icon"]
|
||||||
|
icon = get_weather_icon(icon_name=icon_code, size=90)
|
||||||
|
if self.icon_outline:
|
||||||
|
icon = outline(image=icon, size=8, color=(0, 0, 0, 255))
|
||||||
|
icon_x = int((rectangle_width - icon.width) / 2)
|
||||||
|
icon_y = int(rectangle_height * 0.4)
|
||||||
|
# Create a mask from the alpha channel of the weather icon
|
||||||
|
if len(icon.split()) == 4:
|
||||||
|
mask = icon.split()[-1]
|
||||||
|
else:
|
||||||
|
mask = None
|
||||||
|
# Paste the foreground of the icon onto the background with the help of the mask
|
||||||
|
rect.paste(icon, (int(icon_x), icon_y), mask)
|
||||||
|
|
||||||
|
## Precipitation icon and text
|
||||||
|
rain = day_data["precip_mm"]
|
||||||
|
if rain:
|
||||||
|
rain_text = f"{rain:.0f} mm"
|
||||||
|
rain_font = self.get_font(self.font_family, "ExtraBold", self.font_size)
|
||||||
|
# Icon
|
||||||
|
rain_icon_x = int((rectangle_width - icon.width) / 2)
|
||||||
|
rain_icon_y = int(rectangle_height * 0.82)
|
||||||
|
rect.paste(weeklyRainIcon, (rain_icon_x, rain_icon_y))
|
||||||
|
# Text
|
||||||
|
rain_text_y = int(rectangle_height * 0.8)
|
||||||
|
rect_draw.text(
|
||||||
|
(rain_icon_x + weeklyRainIcon.width + 10, rain_text_y),
|
||||||
|
rain_text,
|
||||||
|
fill=0,
|
||||||
|
font=rain_font,
|
||||||
|
align="right",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.image.paste(rect, (int(x_rect), int(y_rect)))
|
||||||
|
|
||||||
def generate_image(self):
|
def generate_image(self):
|
||||||
"""Generate image for this module"""
|
"""Generate image for this module"""
|
||||||
|
|
||||||
@ -495,11 +606,11 @@ class Fullweather(inkycal_module):
|
|||||||
## Add user-configurable section to the bottom left corner
|
## Add user-configurable section to the bottom left corner
|
||||||
self.addUserSection()
|
self.addUserSection()
|
||||||
|
|
||||||
## Add Hourly Forecast
|
## Add Hourly Forecast to the top right section
|
||||||
self.addHourlyForecast()
|
self.addHourlyForecast()
|
||||||
|
|
||||||
## Add Daily Forecast
|
## Add Daily Forecast to the bottom right section
|
||||||
# my_image = addDailyForecast(display=display, image=my_image, hourly_forecasts=hourly_forecasts)
|
self.addDailyForecast()
|
||||||
|
|
||||||
self.image.save("./openweather_full.png")
|
self.image.save("./openweather_full.png")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user