Skip to content

Commit 88f2a58

Browse files
committed
Add IO Time Service demo for CircuitPython day
1 parent 1e62b17 commit 88f2a58

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries
2+
# SPDX-FileCopyrightText: 2024 Tyeth Gundry for Adafruit Industries
3+
#
4+
# SPDX-License-Identifier: MIT
5+
6+
import os
7+
import time
8+
import wifi
9+
import board
10+
import displayio
11+
import microcontroller
12+
import adafruit_connection_manager
13+
import adafruit_requests
14+
from adafruit_io.adafruit_io import IO_HTTP
15+
from adafruit_bitmap_font import bitmap_font
16+
from adafruit_display_text import bitmap_label
17+
from adafruit_ticks import ticks_ms, ticks_add, ticks_diff
18+
19+
## See TZ Identifier column at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
20+
## If you want to set the timezone, you can do so with the following line:
21+
timezone = "GB"
22+
#timezone = None # Or instead rely on automatic timezone detection based on IP Address
23+
24+
25+
# The time of the thing!
26+
EVENT_YEAR = 2024
27+
EVENT_MONTH = 8
28+
EVENT_DAY = 6 # 16
29+
EVENT_HOUR = 13 # 0
30+
EVENT_MINUTE = 11 # 0
31+
# we'll make a python-friendly structure
32+
event_time = time.struct_time((EVENT_YEAR, EVENT_MONTH, EVENT_DAY,
33+
EVENT_HOUR, EVENT_MINUTE, 0, # we don't track seconds
34+
-1, -1, False)) # we dont know day of week/year or DST
35+
36+
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
37+
38+
# Initialize a requests session using the newer connection manager
39+
# See https://adafruit-playground.com/u/justmobilize/pages/adafruit-connection-manager
40+
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
41+
ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio)
42+
requests = adafruit_requests.Session(pool, ssl_context)
43+
44+
# Create an instance of the Adafruit IO HTTP client
45+
io = IO_HTTP(os.getenv("ADAFRUIT_AIO_USERNAME"), os.getenv("ADAFRUIT_AIO_KEY"), requests)
46+
47+
display = board.DISPLAY
48+
group = displayio.Group()
49+
font = bitmap_font.load_font("/Helvetica-Bold-16.pcf")
50+
blinka_bitmap = displayio.OnDiskBitmap("/cpday_tft.bmp")
51+
blinka_grid = displayio.TileGrid(blinka_bitmap, pixel_shader=blinka_bitmap.pixel_shader)
52+
scrolling_label = bitmap_label.Label(font, text=" ", y=display.height - 13)
53+
54+
group.append(blinka_grid)
55+
group.append(scrolling_label)
56+
display.root_group = group
57+
display.auto_refresh = False
58+
59+
refresh_clock = ticks_ms()
60+
refresh_timer = 3600 * 1000 # 1 hour
61+
clock_clock = ticks_ms()
62+
clock_timer = 1000
63+
scroll_clock = ticks_ms()
64+
scroll_timer = 50
65+
first_run = True
66+
finished = False
67+
triggered = False
68+
69+
while True:
70+
# only query the online time once per hour (and on first run)
71+
if ticks_diff(ticks_ms(), refresh_clock) >= refresh_timer or first_run:
72+
try:
73+
print("Getting time from internet!")
74+
now = time.struct_time(io.receive_time(timezone))
75+
print(now)
76+
total_seconds = time.mktime(now)
77+
refresh_clock = ticks_add(refresh_clock, refresh_timer)
78+
except Exception as e: # pylint: disable=broad-except
79+
print("Some error occured, retrying via reset in 5seconds! -", e)
80+
time.sleep(5)
81+
microcontroller.reset()
82+
83+
if ticks_diff(ticks_ms(), clock_clock) >= clock_timer:
84+
remaining = time.mktime(event_time) - total_seconds
85+
if remaining < 0:
86+
# calculate time since event
87+
remaining = abs(remaining)
88+
secs_remaining = -(remaining % 60)
89+
remaining //= 60
90+
mins_remaining = -(remaining % 60)
91+
remaining //= 60
92+
hours_remaining = -(remaining % 24)
93+
remaining //= 24
94+
days_remaining = -remaining
95+
finished = True
96+
if not first_run and days_remaining == 0:
97+
scrolling_label.text = "It's CircuitPython Day 2024! The snakiest day of the year!"
98+
# Check for the moment of the event to trigger a NASA snake launch
99+
if not triggered and (hours_remaining==0 and mins_remaining == 0 and secs_remaining <= 0):
100+
# send a signal to an adafruit IO feed, maybe firing off an email or text message
101+
print("Launch the snakes!")
102+
triggered = True
103+
io.send_data("cpday-countdown", "Launch the snakes!")
104+
else:
105+
secs_remaining = remaining % 60
106+
remaining //= 60
107+
mins_remaining = remaining % 60
108+
remaining //= 60
109+
hours_remaining = remaining % 24
110+
remaining //= 24
111+
days_remaining = remaining
112+
if not finished or (finished and days_remaining < 0):
113+
scrolling_label.text = (f"{days_remaining} DAYS, {hours_remaining} HOURS," +
114+
f"{mins_remaining} MINUTES & {secs_remaining} SECONDS")
115+
total_seconds += 1
116+
clock_clock = ticks_add(clock_clock, clock_timer)
117+
if ticks_diff(ticks_ms(), scroll_clock) >= scroll_timer:
118+
scrolling_label.x -= 1
119+
if scrolling_label.x < -(scrolling_label.width + 5):
120+
scrolling_label.x = display.width + 2
121+
display.refresh()
122+
scroll_clock = ticks_add(scroll_clock, scroll_timer)
123+
124+
first_run = False
Binary file not shown.

0 commit comments

Comments
 (0)