Merge pull request #2355 from adafruit/weather_sprites

Adding code for qt py neopixel weather display
This commit is contained in:
Anne Barela 2022-12-15 11:05:15 -05:00 committed by GitHub
commit bf15ca13aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 374 additions and 0 deletions

View file

@ -0,0 +1,183 @@
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
# SPDX-License-Identifier: MIT
import os
import ssl
import time
import board
import wifi
import socketpool
import fontio
import neopixel
import simpleio
from adafruit_display_text.bitmap_label import Label
from adafruit_bitmap_font import bitmap_font
from displayio import Bitmap
from rainbowio import colorwheel
import adafruit_requests
from weather_codes import weather_codes
# minimum expected temperature
min_temp = 0
# maximum expected temperature
max_temp = 100
# first daylight hour
daytime_min = 7
# last daylight hour
daytime_max = 17
# latitude
lat = 42.36
# longitude
long = -71.06
# temp unit for API request
temperature_unit = "fahrenheit"
# temp unit for display
temp_unit = "F"
# API request to open-meteo
weather_url = "https://api.open-meteo.com/v1/forecast?"
# pass latitude and longitude
weather_url += "latitude=%d&longitude=%d&timezone=auto" % (lat, long)
# pass temperature_unit
weather_url += "&current_weather=true&temperature_unit=%s&windspeed_unit=mph" % temperature_unit
# connect to SSID
wifi.radio.connect(os.getenv('WIFI_SSID'), os.getenv('WIFI_PASSWORD'))
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
# make the API request
response = requests.get(weather_url)
# packs the response into a JSON
response_as_json = response.json()
print()
# prints the entire JSON
print(response_as_json)
print()
# gets current weather code
weather = int(response_as_json['current_weather']['weathercode'])
print(weather)
# gets temperature
temp = response_as_json['current_weather']['temperature']
temp_int = int(temp)
print("%s°%s" % (temp, temp_unit))
# gets time
json_time = response_as_json['current_weather']['time']
new_time = json_time.rsplit("T", 1)[-1]
new_time = int(new_time[:2])
print(new_time)
# font edit code by Jeff Epler
tom_thumb = bitmap_font.load_font("tom-thumb.pcf", Bitmap)
_glyph_keys = ['bitmap', 'tile_index', 'width', 'height', 'dx', 'dy', 'shift_x', 'shift_y']
def patch_glyph(base, **kw):
d = {}
for k in _glyph_keys:
d[k] = kw.get(k, getattr(base, k))
return fontio.Glyph(**d)
class PatchedFont:
def __init__(self, base_font, patches):
self.base_font = base_font
self.patches = patches
def get_glyph(self, glyph):
g = self.base_font.get_glyph(glyph)
patch = self.patches.get(glyph)
if patch is not None:
#print("patching", repr(chr(glyph)), g)
g = patch_glyph(g, **patch)
#print("patched", g)
return g
def get_bounding_box(self):
return self.base_font.get_bounding_box()
font = PatchedFont(tom_thumb,
{
32: {'shift_x': 1, 'dx': 0},
105: {'dx': 0, 'shift_x': 2},
33: {'dx': 0, 'shift_x': 2},
})
# temperature for scrolling text
label = Label(text=" %s°%s " % (temp, temp_unit), font=font)
bitmap = label.bitmap
# create 5x5 neopixels
pixels = neopixel.NeoPixel(board.A3, 5*5, brightness=.08, auto_write=False)
# count for pixels when drawing bitmaps
count = 0
# arrays to pack assets from weather_codes helper
# weather condition code
codes = []
# bitmap for daytime
day_images = []
# bitmap for nighttime
night_images = []
for i in weather_codes:
codes.append(i['code'])
day_images.append(i['day_img'])
night_images.append(i['night_img'])
clock = time.monotonic()
# display current weather sprite & scroll temperature
while True:
# check every hour
if (time.monotonic() - clock) > 3600:
# make the API request
response = requests.get(weather_url)
# packs the response into a JSON
response_as_json = response.json()
print()
# prints the entire JSON
print(response_as_json)
print()
# current weather code
weather = int(response_as_json['current_weather']['weathercode'])
print(weather)
# temperature
temp = response_as_json['current_weather']['temperature']
temp_int = int(temp)
print("%s°%s" % (temp, temp_unit))
# update scrolling text
label.text = " %s°%s " % (temp, temp_unit)
json_time = response_as_json['current_weather']['time']
new_time = json_time.rsplit("T", 1)[-1]
new_time = int(new_time[:2])
print(new_time)
clock = time.monotonic()
# map color to temp range. colder temps are cool colors, warmer temps warm colors
temp_color = simpleio.map_range(temp_int, min_temp, max_temp, 255, 0)
# checks if it's day or night based on hour
if new_time in range(daytime_min, daytime_max):
img = day_images[weather]
else:
img = night_images[weather]
# draw bitmap sprite
for pixel in img:
pixels[count] = pixel
pixels.show()
count+=1
time.sleep(0.001)
time.sleep(5)
hue = 0
count = 0
# draw scrolling text
for v in range(2):
for i in range(bitmap.width):
# Scoot the old text left by 1 pixel
pixels[:20] = pixels[5:]
# adjust color based on temperature
color = colorwheel(temp_color)
# Draw in the next line of text
for y in range(5):
# Select black or color depending on the bitmap pixel
pixels[20+y] = color * bitmap[i,y]
pixels.show()
time.sleep(.1)

View file

@ -0,0 +1,191 @@
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
# SPDX-License-Identifier: MIT
y = (255, 125, 0)
o = (0, 0, 0)
a = (0, 75, 125)
w = (255, 255, 255)
v = (127, 0, 255)
b = (0, 0, 255)
z = (0, 0, 25)
g = (25, 25, 25)
sun_bitmap = [
y,a,y,a,y,
a,y,y,y,a,
y,y,y,y,y,
a,y,y,y,a,
y,a,y,a,y,
]
cloud_bitmap = [
a,a,a,w,a,
a,w,w,w,a,
a,w,w,w,a,
a,a,w,w,a,
a,a,a,w,a,
]
partSun_bitmap = [
a,w,w,w,a,
a,w,w,w,w,
y,y,w,w,a,
a,y,y,w,a,
y,a,y,a,a,
]
rain_bitmap = [
z,z,v,z,b,
v,v,v,b,z,
v,v,v,z,b,
z,v,v,b,z,
z,z,v,z,b,
]
thunder_bitmap = [
z,z,v,z,b,
v,v,v,b,z,
v,v,y,z,y,
z,y,v,y,z,
z,z,v,z,b,
]
snow_bitmap = [
z,z,v,z,w,
v,v,v,w,z,
v,v,v,z,w,
z,v,v,w,z,
z,z,v,z,w,
]
night_bitmap = [
y,g,g,y,g,
g,g,y,g,g,
g,y,g,g,y,
y,y,y,g,g,
g,y,g,g,g,
]
nightCloud_bitmap = [
g,w,w,w,g,
g,w,w,w,g,
y,g,w,w,g,
g,g,g,w,g,
g,g,y,g,g,
]
nightRain_bitmap = [
g,v,v,v,b,
g,v,v,v,g,
y,g,v,v,b,
g,g,g,v,g,
g,g,y,g,g,
]
nightThunder_bitmap = [
g,v,v,v,b,
g,v,v,v,g,
g,g,y,v,y,
v,y,g,y,b,
v,v,b,g,g,
]
nightSnow_bitmap = [
g,v,v,v,w,
g,v,v,v,g,
y,g,v,v,w,
g,g,g,v,g,
g,g,y,g,g,
]
weather_codes = [
{"code" : 0, "day_img" : sun_bitmap, "night_img" : night_bitmap},
{"code" : 1, "day_img" : sun_bitmap, "night_img" : night_bitmap},
{"code" : 2, "day_img" : sun_bitmap, "night_img" : night_bitmap},
{"code" : 3, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 4, "day_img" : partSun_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 5, "day_img" : partSun_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 6, "day_img" : partSun_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 7, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 8, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 9, "day_img" : partSun_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 10, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 11, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 12, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 13, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap},
{"code" : 14, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 15, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 16, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 17, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap},
{"code" : 18, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 19, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap},
{"code" : 20, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 21, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 22, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 23, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 24, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 25, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 26, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 27, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 28, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 29, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap},
{"code" : 30, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 31, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 32, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 33, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 34, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 35, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 36, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 37, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 38, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 39, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 40, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 41, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 42, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 43, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 44, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 45, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 46, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 47, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 48, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 49, "day_img" : cloud_bitmap, "night_img" : nightCloud_bitmap},
{"code" : 50, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 51, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 52, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 53, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 54, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 55, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 56, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 57, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 58, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 59, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 60, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 61, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 62, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 63, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 64, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 65, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 66, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 67, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 68, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 69, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 70, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 71, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 72, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 73, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 74, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 75, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 76, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 77, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 78, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 79, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 80, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 81, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 82, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 83, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 84, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 85, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 86, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 87, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 88, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 89, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 90, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 91, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 92, "day_img" : rain_bitmap, "night_img" : nightRain_bitmap},
{"code" : 93, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 94, "day_img" : snow_bitmap, "night_img" : nightSnow_bitmap},
{"code" : 95, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap},
{"code" : 96, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap},
{"code" : 97, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap},
{"code" : 98, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap},
{"code" : 99, "day_img" : thunder_bitmap, "night_img" : nightThunder_bitmap}
]