Files
matrix64/weather_icons.py

261 lines
8.7 KiB
Python

"""
Weather icon drawing functions for 64x64 LED matrix.
All icons are designed for a 24x24 pixel area.
"""
from rgbmatrix import graphics
def draw_sunny(canvas, x, y):
"""Draw a sun with rays - clear/sunny weather."""
sun_color = graphics.Color(255, 200, 0)
ray_color = graphics.Color(255, 140, 0)
# Draw sun rays (8 directions)
graphics.DrawLine(canvas, x + 12, y + 2, x + 12, y + 5, ray_color)
graphics.DrawLine(canvas, x + 12, y + 19, x + 12, y + 22, ray_color)
graphics.DrawLine(canvas, x + 2, y + 12, x + 5, y + 12, ray_color)
graphics.DrawLine(canvas, x + 19, y + 12, x + 22, y + 12, ray_color)
graphics.DrawLine(canvas, x + 5, y + 5, x + 7, y + 7, ray_color)
graphics.DrawLine(canvas, x + 17, y + 17, x + 19, y + 19, ray_color)
graphics.DrawLine(canvas, x + 5, y + 19, x + 7, y + 17, ray_color)
graphics.DrawLine(canvas, x + 17, y + 7, x + 19, y + 5, ray_color)
# Draw filled sun
for r in range(6, 0, -1):
graphics.DrawCircle(canvas, x + 12, y + 12, r, sun_color)
def draw_clear_night(canvas, x, y):
"""Draw a crescent moon with stars."""
moon_color = graphics.Color(255, 255, 200)
# Draw moon
for r in range(7, 0, -1):
graphics.DrawCircle(canvas, x + 10, y + 12, r, moon_color)
# Draw stars
canvas.SetPixel(x + 20, y + 6, 255, 255, 255)
canvas.SetPixel(x + 18, y + 10, 255, 255, 255)
canvas.SetPixel(x + 22, y + 14, 255, 255, 255)
canvas.SetPixel(x + 19, y + 18, 255, 255, 255)
def _draw_cloud_shape(canvas, x, y, color):
"""Helper to draw a cloud shape."""
for r in range(4, 0, -1):
graphics.DrawCircle(canvas, x + 4, y + 4, r, color)
for r in range(5, 0, -1):
graphics.DrawCircle(canvas, x + 10, y + 3, r, color)
for r in range(4, 0, -1):
graphics.DrawCircle(canvas, x + 15, y + 5, r, color)
for r in range(3, 0, -1):
graphics.DrawCircle(canvas, x + 6, y + 7, r, color)
for r in range(3, 0, -1):
graphics.DrawCircle(canvas, x + 12, y + 7, r, color)
def draw_partly_cloudy(canvas, x, y, cloud_offset=0):
"""Draw sun partially covered by cloud. Cloud can be animated."""
sun_color = graphics.Color(255, 200, 0)
ray_color = graphics.Color(255, 140, 0)
cloud_color = graphics.Color(220, 220, 220)
# Draw partial sun (stays in place)
graphics.DrawLine(canvas, x + 8, y + 2, x + 8, y + 4, ray_color)
graphics.DrawLine(canvas, x + 2, y + 8, x + 4, y + 8, ray_color)
graphics.DrawLine(canvas, x + 3, y + 3, x + 5, y + 5, ray_color)
for r in range(4, 0, -1):
graphics.DrawCircle(canvas, x + 8, y + 8, r, sun_color)
# Draw cloud (with animation offset)
_draw_cloud_shape(canvas, x + 6 + cloud_offset, y + 10, cloud_color)
def draw_partly_cloudy_night(canvas, x, y, cloud_offset=0):
"""Draw moon partially covered by cloud."""
moon_color = graphics.Color(255, 255, 200)
cloud_color = graphics.Color(180, 180, 200)
for r in range(4, 0, -1):
graphics.DrawCircle(canvas, x + 8, y + 8, r, moon_color)
_draw_cloud_shape(canvas, x + 6 + cloud_offset, y + 10, cloud_color)
def draw_cloudy(canvas, x, y):
"""Draw overcast clouds."""
cloud_light = graphics.Color(200, 200, 200)
cloud_dark = graphics.Color(150, 150, 150)
_draw_cloud_shape(canvas, x + 2, y + 6, cloud_dark)
_draw_cloud_shape(canvas, x + 6, y + 10, cloud_light)
def draw_rainy(canvas, x, y):
"""Draw cloud with rain drops."""
cloud_color = graphics.Color(150, 150, 170)
rain_color = graphics.Color(100, 150, 255)
_draw_cloud_shape(canvas, x + 4, y + 4, cloud_color)
for i in range(4):
x_start = x + 6 + i * 4
graphics.DrawLine(canvas, x_start, y + 16, x_start - 2, y + 20, rain_color)
graphics.DrawLine(canvas, x_start + 1, y + 18, x_start - 1, y + 22, rain_color)
def draw_pouring(canvas, x, y):
"""Draw cloud with heavy rain."""
cloud_color = graphics.Color(100, 100, 120)
rain_color = graphics.Color(80, 130, 255)
_draw_cloud_shape(canvas, x + 4, y + 2, cloud_color)
for i in range(5):
x_start = x + 4 + i * 4
graphics.DrawLine(canvas, x_start, y + 14, x_start - 3, y + 22, rain_color)
def draw_snowy(canvas, x, y):
"""Draw cloud with snowflakes."""
cloud_color = graphics.Color(180, 180, 200)
_draw_cloud_shape(canvas, x + 4, y + 4, cloud_color)
for i in range(3):
sx = x + 8 + i * 5
sy = y + 18 + (i % 2) * 3
canvas.SetPixel(sx, sy, 255, 255, 255)
canvas.SetPixel(sx - 1, sy, 255, 255, 255)
canvas.SetPixel(sx + 1, sy, 255, 255, 255)
canvas.SetPixel(sx, sy - 1, 255, 255, 255)
canvas.SetPixel(sx, sy + 1, 255, 255, 255)
def draw_thunderstorm(canvas, x, y):
"""Draw cloud with lightning bolt."""
cloud_color = graphics.Color(80, 80, 100)
lightning_color = graphics.Color(255, 255, 0)
_draw_cloud_shape(canvas, x + 4, y + 2, cloud_color)
graphics.DrawLine(canvas, x + 12, y + 12, x + 10, y + 16, lightning_color)
graphics.DrawLine(canvas, x + 10, y + 16, x + 14, y + 16, lightning_color)
graphics.DrawLine(canvas, x + 14, y + 16, x + 10, y + 22, lightning_color)
def draw_foggy(canvas, x, y):
"""Draw horizontal fog lines."""
fog_color = graphics.Color(180, 180, 180)
for i in range(5):
y_pos = y + 6 + i * 3
graphics.DrawLine(canvas, x + 2, y_pos, x + 20, y_pos, fog_color)
def draw_windy(canvas, x, y):
"""Draw wind lines."""
wind_color = graphics.Color(150, 200, 255)
graphics.DrawLine(canvas, x + 2, y + 8, x + 18, y + 8, wind_color)
graphics.DrawLine(canvas, x + 18, y + 8, x + 20, y + 6, wind_color)
graphics.DrawLine(canvas, x + 4, y + 12, x + 22, y + 12, wind_color)
graphics.DrawLine(canvas, x + 22, y + 12, x + 23, y + 10, wind_color)
graphics.DrawLine(canvas, x + 2, y + 16, x + 16, y + 16, wind_color)
graphics.DrawLine(canvas, x + 16, y + 16, x + 18, y + 14, wind_color)
def draw_hail(canvas, x, y):
"""Draw cloud with hail."""
cloud_color = graphics.Color(140, 140, 160)
hail_color = graphics.Color(200, 220, 255)
_draw_cloud_shape(canvas, x + 4, y + 4, cloud_color)
for i in range(3):
hx = x + 8 + i * 5
hy = y + 18 + (i % 2) * 2
graphics.DrawCircle(canvas, hx, hy, 2, hail_color)
def draw_unknown(canvas, x, y):
"""Draw question mark for unknown weather."""
color = graphics.Color(255, 255, 255)
graphics.DrawCircle(canvas, x + 12, y + 8, 4, color)
canvas.SetPixel(x + 12, y + 14, 255, 255, 255)
canvas.SetPixel(x + 12, y + 17, 255, 255, 255)
# Weather state to icon function mapping
WEATHER_ICONS = {
'sunny': draw_sunny,
'clear-day': draw_sunny,
'clear-night': draw_clear_night,
'partlycloudy': draw_partly_cloudy,
'partly-cloudy-day': draw_partly_cloudy,
'partly-cloudy-night': draw_partly_cloudy_night,
'cloudy': draw_cloudy,
'overcast': draw_cloudy,
'rainy': draw_rainy,
'rain': draw_rainy,
'showers': draw_rainy,
'pouring': draw_pouring,
'snowy': draw_snowy,
'snow': draw_snowy,
'snowy-rainy': draw_snowy,
'sleet': draw_snowy,
'hail': draw_hail,
'lightning': draw_thunderstorm,
'lightning-rainy': draw_thunderstorm,
'thunderstorm': draw_thunderstorm,
'fog': draw_foggy,
'foggy': draw_foggy,
'mist': draw_foggy,
'hazy': draw_foggy,
'windy': draw_windy,
'windy-variant': draw_windy,
'exceptional': draw_unknown,
}
def draw_weather_icon(canvas, x, y, weather_state, cloud_offset=0):
"""Draw weather icon based on state string.
Args:
canvas: The LED matrix canvas
x, y: Position to draw at
weather_state: Weather condition string
cloud_offset: Animation offset for cloud movement (optional)
"""
weather_lower = weather_state.lower() if weather_state else ''
# Icons with cloud animation support
ANIMATED_ICONS = {
'partlycloudy': draw_partly_cloudy,
'partly-cloudy-day': draw_partly_cloudy,
'partly-cloudy-night': draw_partly_cloudy_night,
}
# Try animated icons first
if weather_lower in ANIMATED_ICONS:
ANIMATED_ICONS[weather_lower](canvas, x, y, cloud_offset)
return
# Try exact match for static icons
if weather_lower in WEATHER_ICONS:
WEATHER_ICONS[weather_lower](canvas, x, y)
return
# Try partial match
for key, draw_func in ANIMATED_ICONS.items():
if key in weather_lower or weather_lower in key:
draw_func(canvas, x, y, cloud_offset)
return
for key, draw_func in WEATHER_ICONS.items():
if key in weather_lower or weather_lower in key:
draw_func(canvas, x, y)
return
draw_unknown(canvas, x, y)