11# SPDX-FileCopyrightText: 2024 Carter Nelson for Adafruit Industries
22#
33# 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
55
66import time
77import terminalio
88import displayio
99import adafruit_imageload
1010from adafruit_display_text import label
1111from adafruit_magtag .magtag import MagTag
12- # needed for NTP
13- import wifi
14- import socketpool
15- import adafruit_ntp
1612
1713# --| 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
2219# -------------------------------------------
2320
2421# ----------------------------
6158
6259# Map the above WMO codes to index of icon in 3x3 spritesheet
6360WMO_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
7370)
7471
7572magtag = MagTag ()
8885# /////////////////////////////////////////////////////////////////////////
8986# helper functions
9087
88+
9189def 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 } &"
9391 URL += "daily=weather_code,temperature_2m_max,temperature_2m_min"
9492 URL += ",sunrise,sunset,wind_speed_10m_max,wind_direction_10m_dominant"
9593 URL += "&timeformat=unixtime"
9694 URL += f"&timezone={ TMZ } "
9795 resp = magtag .network .fetch (URL )
98- return resp . json ()
96+ return resp
9997
10098
10199def make_banner (x = 0 , y = 0 ):
@@ -168,10 +166,7 @@ def update_today(data):
168166 s = data ["daily" ]["time" ][0 ] + data ["utc_offset_seconds" ]
169167 t = time .localtime (s )
170168 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
175170 )
176171 # weather icon
177172 w = data ["daily" ]["weather_code" ][0 ]
@@ -194,37 +189,24 @@ def update_future(data):
194189 """Update the future forecast info."""
195190 for i , banner in enumerate (future_banners ):
196191 # 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" ]
198193 t = time .localtime (s )
199194 banner [0 ].text = DAYS [t .tm_wday ][:3 ].upper ()
200195 # weather icon
201- w = data ["daily" ]["weather_code" ][i + 1 ]
196+ w = data ["daily" ]["weather_code" ][i + 1 ]
202197 banner [1 ][0 ] = next (x for x , t in enumerate (WMO_CODE_TO_ICON ) if w in t )
203198 # temperature
204- t = data ["daily" ]["temperature_2m_max" ][i + 1 ]
199+ t = data ["daily" ]["temperature_2m_max" ][i + 1 ]
205200 banner [2 ].text = temperature_text (t )
206201
207202
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 ):
219204 """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
225207 three_fifteen = (3 * 60 + 15 ) * 60
226208 # 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
228210 print (
229211 "Sleeping for {} hours, {} minutes" .format (
230212 seconds_to_sleep // 3600 , (seconds_to_sleep // 60 ) % 60
@@ -240,7 +222,12 @@ def go_to_sleep(current_time):
240222today_date .anchor_point = (0 , 0 )
241223today_date .anchored_position = (15 , 14 )
242224
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+
244231location_name .anchor_point = (0 , 0 )
245232location_name .anchored_position = (15 , 25 )
246233
@@ -301,7 +288,8 @@ def go_to_sleep(current_time):
301288# M A I N
302289# ===========
303290print ("Fetching forecast..." )
304- forecast_data = get_forecast ()
291+ resp_data = get_forecast ()
292+ forecast_data = resp_data .json ()
305293
306294print ("Updating..." )
307295update_today (forecast_data )
@@ -313,6 +301,8 @@ def go_to_sleep(current_time):
313301time .sleep (magtag .display .time_to_refresh + 1 )
314302
315303print ("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 )
317307# entire code will run again after deep sleep cycle
318308# similar to hitting the reset button
0 commit comments