1
1
# SPDX-FileCopyrightText: 2024 Carter Nelson for Adafruit Industries
2
2
#
3
3
# SPDX-License-Identifier: MIT
4
- # pylint: disable=redefined-outer-name, eval-used, wrong-import-order
4
+ # pylint: disable=redefined-outer-name, eval-used, wrong-import-order, unsubscriptable-object
5
5
6
6
import time
7
7
import terminalio
8
8
import displayio
9
9
import adafruit_imageload
10
10
from adafruit_display_text import label
11
11
from adafruit_magtag .magtag import MagTag
12
- # needed for NTP
13
- import wifi
14
- import socketpool
15
- import adafruit_ntp
16
12
17
13
# --| USER CONFIG |--------------------------
18
- LAT = 47.6 # latitude
19
- LON = - 122.3 # longitude
20
- TMZ = "America/Los_Angeles" # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
21
- METRIC = False # set to True for metric units
14
+ LAT = 47.6 # latitude
15
+ LON = - 122.3 # longitude
16
+ TMZ = "America/Los_Angeles" # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
17
+ METRIC = False # set to True for metric units
18
+ CITY = None # optional
22
19
# -------------------------------------------
23
20
24
21
# ----------------------------
61
58
62
59
# Map the above WMO codes to index of icon in 3x3 spritesheet
63
60
WMO_CODE_TO_ICON = (
64
- (0 ,), # 0 = sunny
65
- (1 ,), # 1 = partly sunny/cloudy
66
- (2 ,), # 2 = cloudy
67
- (3 ,), # 3 = very cloudy
68
- (61 , 63 , 65 ), # 4 = rain
69
- (51 , 53 , 55 , 80 , 81 , 82 ), # 5 = showers
70
- (95 , 96 , 99 ), # 6 = storms
71
- (56 , 57 , 66 , 67 , 71 , 73 , 75 , 77 , 85 , 86 ), # 7 = snow
72
- (45 , 48 ), # 8 = fog and stuff
61
+ (0 ,), # 0 = sunny
62
+ (1 ,), # 1 = partly sunny/cloudy
63
+ (2 ,), # 2 = cloudy
64
+ (3 ,), # 3 = very cloudy
65
+ (61 , 63 , 65 ), # 4 = rain
66
+ (51 , 53 , 55 , 80 , 81 , 82 ), # 5 = showers
67
+ (95 , 96 , 99 ), # 6 = storms
68
+ (56 , 57 , 66 , 67 , 71 , 73 , 75 , 77 , 85 , 86 ), # 7 = snow
69
+ (45 , 48 ), # 8 = fog and stuff
73
70
)
74
71
75
72
magtag = MagTag ()
88
85
# /////////////////////////////////////////////////////////////////////////
89
86
# helper functions
90
87
88
+
91
89
def get_forecast ():
92
- URL = f"https://api.open-meteo.com/v1/forecast?latitude={ LAT } &longitude={ LON } &"
90
+ URL = f"https://api.open-meteo.com/v1/forecast?latitude={ LAT } &longitude={ LON } &"
93
91
URL += "daily=weather_code,temperature_2m_max,temperature_2m_min"
94
92
URL += ",sunrise,sunset,wind_speed_10m_max,wind_direction_10m_dominant"
95
93
URL += "&timeformat=unixtime"
96
94
URL += f"&timezone={ TMZ } "
97
95
resp = magtag .network .fetch (URL )
98
- return resp . json ()
96
+ return resp
99
97
100
98
101
99
def make_banner (x = 0 , y = 0 ):
@@ -168,10 +166,7 @@ def update_today(data):
168
166
s = data ["daily" ]["time" ][0 ] + data ["utc_offset_seconds" ]
169
167
t = time .localtime (s )
170
168
today_date .text = "{} {} {}, {}" .format (
171
- DAYS [t .tm_wday ].upper (),
172
- MONTHS [t .tm_mon - 1 ].upper (),
173
- t .tm_mday ,
174
- t .tm_year
169
+ DAYS [t .tm_wday ].upper (), MONTHS [t .tm_mon - 1 ].upper (), t .tm_mday , t .tm_year
175
170
)
176
171
# weather icon
177
172
w = data ["daily" ]["weather_code" ][0 ]
@@ -194,37 +189,24 @@ def update_future(data):
194
189
"""Update the future forecast info."""
195
190
for i , banner in enumerate (future_banners ):
196
191
# day of week
197
- s = data ["daily" ]["time" ][i + 1 ] + data ["utc_offset_seconds" ]
192
+ s = data ["daily" ]["time" ][i + 1 ] + data ["utc_offset_seconds" ]
198
193
t = time .localtime (s )
199
194
banner [0 ].text = DAYS [t .tm_wday ][:3 ].upper ()
200
195
# weather icon
201
- w = data ["daily" ]["weather_code" ][i + 1 ]
196
+ w = data ["daily" ]["weather_code" ][i + 1 ]
202
197
banner [1 ][0 ] = next (x for x , t in enumerate (WMO_CODE_TO_ICON ) if w in t )
203
198
# temperature
204
- t = data ["daily" ]["temperature_2m_max" ][i + 1 ]
199
+ t = data ["daily" ]["temperature_2m_max" ][i + 1 ]
205
200
banner [2 ].text = temperature_text (t )
206
201
207
202
208
- def get_ntp_time (offset ):
209
- """Use NTP to get current local time."""
210
- pool = socketpool .SocketPool (wifi .radio )
211
- ntp = adafruit_ntp .NTP (pool , tz_offset = offset )
212
- if ntp :
213
- return ntp .datetime
214
- else :
215
- return None
216
-
217
-
218
- def go_to_sleep (current_time ):
203
+ def go_to_sleep (current_time_secs ):
219
204
"""Enter deep sleep for time needed."""
220
- # compute current time offset in seconds
221
- hour = current_time .tm_hour
222
- minutes = current_time .tm_min
223
- seconds = current_time .tm_sec
224
- seconds_since_midnight = 60 * (hour * 60 + minutes ) + seconds
205
+ # work in units of seconds
206
+ seconds_in_a_day = 24 * 60 * 60
225
207
three_fifteen = (3 * 60 + 15 ) * 60
226
208
# wake up 15 minutes after 3am
227
- seconds_to_sleep = (24 * 60 * 60 - seconds_since_midnight ) + three_fifteen
209
+ seconds_to_sleep = (seconds_in_a_day - current_time_secs ) + three_fifteen
228
210
print (
229
211
"Sleeping for {} hours, {} minutes" .format (
230
212
seconds_to_sleep // 3600 , (seconds_to_sleep // 60 ) % 60
@@ -240,7 +222,12 @@ def go_to_sleep(current_time):
240
222
today_date .anchor_point = (0 , 0 )
241
223
today_date .anchored_position = (15 , 14 )
242
224
243
- location_name = label .Label (terminalio .FONT , text = f"({ LAT } ,{ LON } )" , color = 0x000000 )
225
+ location_name = label .Label (terminalio .FONT , color = 0x000000 )
226
+ if CITY :
227
+ location_name .text = f"{ CITY [:16 ]} ({ LAT :.1f} ,{ LON :.1f} )"
228
+ else :
229
+ location_name .text = f"({ LAT } ,{ LON } )"
230
+
244
231
location_name .anchor_point = (0 , 0 )
245
232
location_name .anchored_position = (15 , 25 )
246
233
@@ -301,7 +288,8 @@ def go_to_sleep(current_time):
301
288
# M A I N
302
289
# ===========
303
290
print ("Fetching forecast..." )
304
- forecast_data = get_forecast ()
291
+ resp_data = get_forecast ()
292
+ forecast_data = resp_data .json ()
305
293
306
294
print ("Updating..." )
307
295
update_today (forecast_data )
@@ -313,6 +301,8 @@ def go_to_sleep(current_time):
313
301
time .sleep (magtag .display .time_to_refresh + 1 )
314
302
315
303
print ("Sleeping..." )
316
- go_to_sleep (get_ntp_time (forecast_data ["utc_offset_seconds" ]/ 3600 ))
304
+ h , m , s = (int (t ) for t in resp_data .headers ["date" ].split (" " )[4 ].split (":" ))
305
+ current_time_secs = (h * 3600 ) + (m * 60 ) + (s ) + forecast_data ["utc_offset_seconds" ]
306
+ go_to_sleep (current_time_secs )
317
307
# entire code will run again after deep sleep cycle
318
308
# similar to hitting the reset button
0 commit comments