1- import time
2- import random
3- import board
4- import busio
5- from digitalio import DigitalInOut
6- import neopixel
7- from adafruit_esp32spi import adafruit_esp32spi
8- from adafruit_esp32spi import adafruit_esp32spi_wifimanager
9- import adafruit_fancyled .adafruit_fancyled as fancy
10-
11- print ("ESP32 Open Weather API demo" )
12-
13- # Use cityname, country code where countrycode is ISO3166 format.
14- # E.g. "New York, US" or "London, GB"
15- LOCATION = "Manhattan, US"
16-
17- # Get wifi details and more from a secrets.py file
18- try :
19- from secrets import secrets
20- except ImportError :
21- print ("WiFi secrets are kept in secrets.py, please add them there!" )
22- raise
23-
24- # Set up where we'll be fetching data from
25- DATA_SOURCE = "http://api.openweathermap.org/data/2.5/weather?q=" + LOCATION
26- DATA_SOURCE += "&appid=" + secrets ['openweather_token' ]
27-
28- # If you are using a board with pre-defined ESP32 Pins:
29- esp32_cs = DigitalInOut (board .ESP_CS )
30- esp32_ready = DigitalInOut (board .ESP_BUSY )
31- esp32_reset = DigitalInOut (board .ESP_RESET )
32-
33- spi = busio .SPI (board .SCK , board .MOSI , board .MISO )
34- esp = adafruit_esp32spi .ESP_SPIcontrol (spi , esp32_cs , esp32_ready , esp32_reset )
35- status_light = neopixel .NeoPixel (board .NEOPIXEL , 1 , brightness = 0.2 ) # Uncomment for Most Boards
36- wifi = adafruit_esp32spi_wifimanager .ESPSPI_WiFiManager (esp , secrets , status_light )
37- pixels = neopixel .NeoPixel (board .D2 , 16 , brightness = 1.0 , auto_write = False )
38- pixels .fill (0x050505 )
39- pixels .show ()
40-
41- # clouds palette
42- cloudy_palette = [fancy .CRGB (1.0 , 1.0 , 1.0 ), # White
43- fancy .CRGB (0.5 , 0.5 , 0.5 ), # gray
44- fancy .CRGB (0.5 , 0.5 , 1.0 )] # blue-gray
45- # sunny palette
46- sunny_palette = [fancy .CRGB (1.0 , 1.0 , 1.0 ), # White
47- fancy .CRGB (1.0 , 1.0 , 0.0 ),# Yellow
48- fancy .CRGB (1.0 , 0.5 , 0.0 ),] # Orange
49- # thunderstorm palette
50- thunder_palette = [fancy .CRGB (0.0 , 0.0 , 1.0 ), # blue
51- fancy .CRGB (0.5 , 0.5 , 0.5 ), # gray
52- fancy .CRGB (0.5 , 0.5 , 1.0 )] # blue-gray
53- last_thunder_bolt = None
54-
55- palette = None # current palette
56- pal_offset = 0 # Positional offset into color palette to get it to 'spin'
57- levels = (0.25 , 0.3 , 0.15 ) # Color balance / brightness for gamma function
58- raining = False
59- thundering = False
60-
61- weather_refresh = None
62- weather_type = None
63- while True :
64- # only query the weather every 10 minutes (and on first run)
65- if (not weather_refresh ) or (time .monotonic () - weather_refresh ) > 600 :
66- try :
67- response = wifi .get (DATA_SOURCE ).json ()
68- print ("Response is" , response )
69- weather_type = response ['weather' ][0 ]['main' ]
70- weather_type = 'Thunderstorm' # manually adjust weather type for testing!
71-
72- print (weather_type ) # See https://openweathermap.org/weather-conditions
73- # default to no rain or thunder
74- raining = thundering = False
75- if weather_type == 'Clouds' :
76- palette = cloudy_palette
77- if weather_type == 'Rain' :
78- palette = cloudy_palette
79- raining = True
80- if weather_type == 'Sunny' :
81- palette = sunny_palette
82- if weather_type == 'Thunderstorm' :
83- palette = thunder_palette
84- raining = thundering = True
85- # pick next thunderbolt time now
86- next_bolt_time = time .monotonic () + random .randint (1 , 5 )
87- weather_refresh = time .monotonic ()
88- except RuntimeError as e :
89- print ("Some error occured, retrying! -" , e )
90- time .sleep (5 )
91- continue
92-
93- if palette :
94- for i in range (len (pixels )):
95- color = fancy .palette_lookup (palette , pal_offset + i / len (pixels ))
96- color = fancy .gamma_adjust (color , brightness = levels )
97- pixels [i ] = color .pack ()
98- pixels .show ()
99- pal_offset += 0.01 # Bigger number = faster spin
100-
101- if raining :
102- # don't have a droplet every time
103- if random .randint (0 , 25 ) == 0 : # 1 out of 25 times
104- pixels [random .randint (0 , len (pixels )- 1 )] = 0xFFFFFF # make a random pixel white
105- pixels .show ()
106-
107- # if its time for a thunderbolt
108- if thundering and (time .monotonic () > next_bolt_time ):
109- print ("Ka Bam!" )
110- # fill pixels white, delay, a few times
111- for i in range (random .randint (1 , 3 )): # up to 3 times...
112- pixels .fill (0xFFFFFF ) # bright white!
113- pixels .show ()
114- time .sleep (random .uniform (0.01 , 0.2 )) # pause
115- pixels .fill (0x0F0F0F ) # gray
116- pixels .show ()
117- time .sleep (random .uniform (0.01 , 0.3 )) # pause
118- # pick next thunderbolt time now
119- next_bolt_time = time .monotonic () + random .randint (5 , 15 ) # between 5 and 15 s
1+ import time
2+ import audioio
3+ import random
4+ import board
5+ import busio
6+ from digitalio import DigitalInOut
7+ import digitalio
8+ import neopixel
9+ from adafruit_esp32spi import adafruit_esp32spi
10+ from adafruit_esp32spi import adafruit_esp32spi_wifimanager
11+ import adafruit_fancyled .adafruit_fancyled as fancy
12+
13+ print ("ESP32 Open Weather API demo" )
14+
15+ button = digitalio .DigitalInOut (board .A1 )
16+ button .switch_to_input (pull = digitalio .Pull .UP )
17+
18+ wave_file = open ("sound/Rain.wav" , "rb" )
19+ wave = audioio .WaveFile (wave_file )
20+ audio = audioio .AudioOut (board .A0 )
21+
22+
23+ # Get wifi details and more from a secrets.py file
24+ try :
25+ from secrets import secrets
26+ except ImportError :
27+ print ("WiFi secrets are kept in secrets.py, please add them there!" )
28+ raise
29+
30+ # Use cityname, country code where countrycode is ISO3166 format.
31+ # E.g. "New York, US" or "London, GB"
32+ LOCATION = secrets ['timezone' ]
33+
34+ # Set up where we'll be fetching data from
35+ DATA_SOURCE = "http://api.openweathermap.org/data/2.5/weather?q=" + secrets ['timezone' ]
36+ DATA_SOURCE += "&appid=" + secrets ['openweather_token' ]
37+
38+ # If you are using a board with pre-defined ESP32 Pins:
39+ esp32_cs = DigitalInOut (board .ESP_CS )
40+ esp32_ready = DigitalInOut (board .ESP_BUSY )
41+ esp32_reset = DigitalInOut (board .ESP_RESET )
42+
43+ spi = busio .SPI (board .SCK , board .MOSI , board .MISO )
44+ esp = adafruit_esp32spi .ESP_SPIcontrol (spi , esp32_cs , esp32_ready , esp32_reset )
45+ status_light = neopixel .NeoPixel (board .NEOPIXEL , 1 , brightness = 0.2 ) # Uncomment for Most Boards
46+ wifi = adafruit_esp32spi_wifimanager .ESPSPI_WiFiManager (esp , secrets , status_light )
47+ pixels = neopixel .NeoPixel (board .D2 , 150 , brightness = 1.0 , auto_write = False )
48+ pixels .fill (0x050505 )
49+ pixels .show ()
50+
51+ # clouds palette
52+ cloudy_palette = [fancy .CRGB (1.0 , 1.0 , 1.0 ), # White
53+ fancy .CRGB (0.5 , 0.5 , 0.5 ), # gray
54+ fancy .CRGB (0.5 , 0.5 , 1.0 )] # blue-gray
55+ # sunny palette
56+ sunny_palette = [fancy .CRGB (1.0 , 1.0 , 1.0 ), # White
57+ fancy .CRGB (1.0 , 1.0 , 0.0 ),# Yellow
58+ fancy .CRGB (1.0 , 0.5 , 0.0 ),] # Orange
59+ # thunderstorm palette
60+ thunder_palette = [fancy .CRGB (0.0 , 0.0 , 1.0 ), # blue
61+ fancy .CRGB (0.5 , 0.5 , 0.5 ), # gray
62+ fancy .CRGB (0.5 , 0.5 , 1.0 )] # blue-gray
63+ last_thunder_bolt = None
64+
65+ palette = None # current palette
66+ pal_offset = 0 # Positional offset into color palette to get it to 'spin'
67+ levels = (0.25 , 0.3 , 0.15 ) # Color balance / brightness for gamma function
68+ raining = False
69+ snowing = False
70+ thundering = False
71+ has_sound = False
72+
73+ weather_refresh = None
74+ weather_type = None
75+ button_mode = 4
76+ button_select = False
77+
78+ cloud_on = True
79+
80+ while True :
81+ if not button .value :
82+ button_mode = button_mode + 1
83+ print ("Button Pressed" )
84+ if button_mode > 4 :
85+ button_mode = 0
86+ print ("Mode is:" , button_mode )
87+ pressed_time = time .monotonic ()
88+ button_select = True
89+ weather_refresh = None
90+ while not button .value :
91+ audio .stop ()
92+ #print("Debounce")
93+ if (time .monotonic () - pressed_time ) > 4 :
94+ print ("Turning OFF" )
95+ cloud_on = False
96+ pixels .fill (0x000000 ) # bright white!
97+ pixels .show ()
98+ while not cloud_on :
99+ while not button .value :
100+ pass
101+ #print("Debounce")
102+ if not button .value :
103+ pressed_time = time .monotonic ()
104+ print ("Button Pressed" )
105+ cloud_on = True
106+ button_select = False
107+ weather_refresh = None
108+
109+ if button_mode == 0 :
110+ weather_type = 'Sunny'
111+ if button_mode == 1 :
112+ weather_type = 'Clouds'
113+ if button_mode == 2 :
114+ weather_type = 'Rain'
115+ if button_mode == 3 :
116+ weather_type = 'Thunderstorm'
117+ if button_mode == 4 :
118+ weather_type = 'Snow'
119+
120+ # only query the weather every 10 minutes (and on first run)
121+ if (not weather_refresh ) or (time .monotonic () - weather_refresh ) > 600 :
122+ try :
123+ if not button_select :
124+ response = wifi .get (DATA_SOURCE ).json ()
125+ print ("Response is" , response )
126+ weather_type = response ['weather' ][0 ]['main' ]
127+ #weather_type = 'Rain' # manually adjust weather type for testing!
128+ if weather_type == 'Clear' :
129+ weather_type = 'Sunny'
130+ print (weather_type ) # See https://openweathermap.org/weather-conditions
131+ # default to no rain or thunder
132+ raining = snowing = thundering = has_sound = False
133+ if weather_type == 'Sunny' :
134+ palette = sunny_palette
135+ wave_file = open ("sound/Clear.wav" , "rb" )
136+ wave = audioio .WaveFile (wave_file )
137+ has_sound = True
138+ if weather_type == 'Clouds' :
139+ palette = cloudy_palette
140+ wave_file = open ("sound/Clouds.wav" , "rb" )
141+ wave = audioio .WaveFile (wave_file )
142+ has_sound = True
143+ if weather_type == 'Rain' :
144+ palette = cloudy_palette
145+ wave_file = open ("sound/Rain.wav" , "rb" )
146+ wave = audioio .WaveFile (wave_file )
147+ raining = True
148+ has_sound = True
149+ if weather_type == 'Thunderstorm' :
150+ palette = thunder_palette
151+ raining = thundering = True
152+ has_sound = True
153+ # pick next thunderbolt time now
154+ next_bolt_time = time .monotonic () + random .randint (1 , 5 )
155+ if weather_type == 'Snow' :
156+ palette = cloudy_palette
157+ wave_file = open ("sound/Snow.wav" , "rb" )
158+ wave = audioio .WaveFile (wave_file )
159+ snowing = True
160+ has_sound = True
161+ weather_refresh = time .monotonic ()
162+ except RuntimeError as e :
163+ print ("Some error occured, retrying! -" , e )
164+ time .sleep (5 )
165+ continue
166+
167+ if not audio .playing and has_sound :
168+ if not thundering :
169+ audio .play (wave )
170+
171+ if palette :
172+ for i in range (len (pixels )):
173+ color = fancy .palette_lookup (palette , pal_offset + i / len (pixels ))
174+ color = fancy .gamma_adjust (color , brightness = levels )
175+ pixels [i ] = color .pack ()
176+ pixels .show ()
177+ pal_offset += 0.01 # Bigger number = faster spin
178+
179+ if raining :
180+ # don't have a droplet every time
181+ for i in range (random .randint (1 , 5 )): # up to 3 times...
182+ pixels [random .randint (0 , len (pixels )- 1 )] = 0x0000FF # make a random pixel Blue
183+ pixels .show ()
184+
185+ if snowing :
186+ # don't have a droplet every time
187+ for i in range (random .randint (1 , 5 )): # up to 3 times...
188+ pixels [random .randint (0 , len (pixels )- 1 )] = 0xFFFFFF # make a random pixel white
189+ pixels .show ()
190+
191+ # if its time for a thunderbolt
192+ if thundering and (time .monotonic () > next_bolt_time ):
193+ print ("Ka Bam!" )
194+ # fill pixels white, delay, a few times
195+ for i in range (random .randint (1 , 3 )): # up to 3 times...
196+ pixels .fill (0xFFFFFF ) # bright white!
197+ pixels .show ()
198+ time .sleep (random .uniform (0.01 , 0.2 )) # pause
199+ pixels .fill (0x0F0F0F ) # gray
200+ pixels .show ()
201+ time .sleep (random .uniform (0.01 , 0.3 )) # pause
202+ # pick next thunderbolt time now
203+ Thunder = random .randint (0 , 2 )
204+ if Thunder == 0 :
205+ wave_file = open ("sound/Thunderstorm0.wav" , "rb" )
206+ elif Thunder == 1 :
207+ wave_file = open ("sound/Thunderstorm1.wav" , "rb" )
208+ elif Thunder == 2 :
209+ wave_file = open ("sound/Thunderstorm2.wav" , "rb" )
210+ wave = audioio .WaveFile (wave_file )
211+ audio .play (wave )
212+ next_bolt_time = time .monotonic () + random .randint (5 , 15 ) # between 5 and 15 s
0 commit comments