121 lines
4.6 KiB
Python
121 lines
4.6 KiB
Python
import time
|
|
import board
|
|
import busio
|
|
import random
|
|
from digitalio import DigitalInOut
|
|
import neopixel
|
|
from adafruit_esp32spi import adafruit_esp32spi
|
|
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
|
|
import adafruit_requests as requests
|
|
import adafruit_fancyled.adafruit_fancyled as fancy
|
|
|
|
print("ESP32 Open Weather API demo")
|
|
|
|
# Use cityname, country code where countrycode is ISO3166 format.
|
|
# E.g. "New York, US" or "London, GB"
|
|
LOCATION = "Manhattan, US"
|
|
|
|
# Get wifi details and more from a secrets.py file
|
|
try:
|
|
from secrets import secrets
|
|
except ImportError:
|
|
print("WiFi secrets are kept in secrets.py, please add them there!")
|
|
raise
|
|
|
|
# Set up where we'll be fetching data from
|
|
DATA_SOURCE = "http://api.openweathermap.org/data/2.5/weather?q="+LOCATION
|
|
DATA_SOURCE += "&appid="+secrets['openweather_token']
|
|
|
|
# If you are using a board with pre-defined ESP32 Pins:
|
|
esp32_cs = DigitalInOut(board.ESP_CS)
|
|
esp32_ready = DigitalInOut(board.ESP_BUSY)
|
|
esp32_reset = DigitalInOut(board.ESP_RESET)
|
|
|
|
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
|
|
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
|
|
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards
|
|
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
|
|
pixels = neopixel.NeoPixel(board.D2, 16, brightness=1.0, auto_write=False)
|
|
pixels.fill(0x050505)
|
|
pixels.show()
|
|
|
|
# clouds palette
|
|
cloudy_palette = [fancy.CRGB(1.0, 1.0, 1.0), # White
|
|
fancy.CRGB(0.5, 0.5, 0.5), # gray
|
|
fancy.CRGB(0.5, 0.5, 1.0)] # blue-gray
|
|
# sunny palette
|
|
sunny_palette = [fancy.CRGB(1.0, 1.0, 1.0), # White
|
|
fancy.CRGB(1.0, 1.0, 0.0),# Yellow
|
|
fancy.CRGB(1.0, 0.5, 0.0),] # Orange
|
|
# thunderstorm palette
|
|
thunder_palette = [fancy.CRGB(0.0, 0.0, 1.0), # blue
|
|
fancy.CRGB(0.5, 0.5, 0.5), # gray
|
|
fancy.CRGB(0.5, 0.5, 1.0)] # blue-gray
|
|
last_thunder_bolt = None
|
|
|
|
palette = None # current palette
|
|
pal_offset = 0 # Positional offset into color palette to get it to 'spin'
|
|
levels = (0.25, 0.3, 0.15) # Color balance / brightness for gamma function
|
|
raining = False
|
|
thundering = False
|
|
|
|
weather_refresh = None
|
|
weather_type = None
|
|
while True:
|
|
# only query the weather every 10 minutes (and on first run)
|
|
if (not weather_refresh) or (time.monotonic() - weather_refresh) > 600:
|
|
try:
|
|
response = wifi.get(DATA_SOURCE).json()
|
|
print("Response is", response)
|
|
weather_type = response['weather'][0]['main']
|
|
weather_type = 'Thunderstorm' # manually adjust weather type for testing!
|
|
|
|
print(weather_type) # See https://openweathermap.org/weather-conditions
|
|
# default to no rain or thunder
|
|
raining = thundering = False
|
|
if weather_type == 'Clouds':
|
|
palette = cloudy_palette
|
|
if weather_type == 'Rain':
|
|
palette = cloudy_palette
|
|
raining = True
|
|
if weather_type == 'Sunny':
|
|
palette = sunny_palette
|
|
if weather_type == 'Thunderstorm':
|
|
palette = thunder_palette
|
|
raining = thundering = True
|
|
# pick next thunderbolt time now
|
|
next_bolt_time = time.monotonic() + random.randint(1, 5)
|
|
weather_refresh = time.monotonic()
|
|
except RuntimeError as e:
|
|
print("Some error occured, retrying! -", e)
|
|
time.sleep(5)
|
|
continue
|
|
|
|
if palette:
|
|
for i in range(len(pixels)):
|
|
color = fancy.palette_lookup(palette, pal_offset + i / len(pixels))
|
|
color = fancy.gamma_adjust(color, brightness=levels)
|
|
pixels[i] = color.pack()
|
|
pixels.show()
|
|
pal_offset += 0.01 # Bigger number = faster spin
|
|
|
|
if raining:
|
|
# don't have a droplet every time
|
|
if (random.randint(0, 25) == 0): # 1 out of 25 times
|
|
pixels[random.randint(0, len(pixels)-1)] = 0xFFFFFF # make a random pixel white
|
|
pixels.show()
|
|
|
|
# if its time for a thunderbolt
|
|
if thundering and (time.monotonic() > next_bolt_time):
|
|
print("Ka Bam!")
|
|
# fill pixels white, delay, a few times
|
|
for i in range(random.randint(1, 3)): # up to 3 times...
|
|
pixels.fill(0xFFFFFF) # bright white!
|
|
pixels.show()
|
|
time.sleep(random.uniform(0.01, 0.2)) # pause
|
|
pixels.fill(0x0F0F0F) # gray
|
|
pixels.show()
|
|
time.sleep(random.uniform(0.01, 0.3)) # pause
|
|
# pick next thunderbolt time now
|
|
next_bolt_time = time.monotonic() + random.randint(5, 15) # between 5 and 15 s
|
|
|