Skip to content

Commit c6066b9

Browse files
committed
Adding ANCS Files
1 parent 9696ddd commit c6066b9

File tree

10 files changed

+162
-0
lines changed

10 files changed

+162
-0
lines changed

CPB_ANCS/ancs_basecamp.bmp

113 KB
Binary file not shown.

CPB_ANCS/ancs_connect.bmp

113 KB
Binary file not shown.

CPB_ANCS/ancs_discord.bmp

113 KB
Binary file not shown.

CPB_ANCS/ancs_ical.bmp

113 KB
Binary file not shown.

CPB_ANCS/ancs_none.bmp

113 KB
Binary file not shown.

CPB_ANCS/ancs_phone.bmp

113 KB
Binary file not shown.

CPB_ANCS/ancs_slack.bmp

113 KB
Binary file not shown.

CPB_ANCS/ancs_sms.bmp

113 KB
Binary file not shown.

CPB_ANCS/code.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
"""
2+
This demo shows the latest icons from a connected Apple device on a TFT Gizmo screen.
3+
4+
The A and B buttons on the CircuitPlayground Bluefruit can be used to scroll through all active
5+
notifications. The screen's backlight will turn off after a certain number of seconds to save power.
6+
New notifications or pressing the buttons should turn it back on.
7+
"""
8+
9+
import time
10+
import board
11+
import digitalio
12+
import displayio
13+
import adafruit_ble
14+
from adafruit_ble.advertising.standard import SolicitServicesAdvertisement
15+
from adafruit_ble.services.apple import AppleNotificationService
16+
from adafruit_gizmo import tft_gizmo
17+
from audiocore import WaveFile
18+
from audiopwmio import PWMAudioOut as AudioOut
19+
20+
# Enable the speaker
21+
speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
22+
speaker_enable.direction = digitalio.Direction.OUTPUT
23+
speaker_enable.value = True
24+
25+
audio = AudioOut(board.SPEAKER)
26+
27+
# This is a whitelist of apps to show notifications from.
28+
APP_ICONS = {
29+
"com.tinyspeck.chatlyio": "/ancs_slack.bmp",
30+
"com.basecamp.bc3-ios": "/ancs_basecamp.bmp",
31+
"com.apple.MobileSMS": "/ancs_sms.bmp",
32+
"com.hammerandchisel.discord": "/ancs_discord.bmp",
33+
"com.apple.mobilecal": "/ancs_ical.bmp",
34+
"com.apple.mobilephone": "/ancs_phone.bmp"
35+
}
36+
37+
BLACKLIST = []
38+
DELAY_AFTER_PRESS = 15
39+
DEBOUNCE = 0.1
40+
DIM_TIMEOUT = 20 # Amount of timeout to turn off backlight
41+
DIM_LEVEL = 0.05
42+
43+
a = digitalio.DigitalInOut(board.BUTTON_A)
44+
a.switch_to_input(pull=digitalio.Pull.DOWN)
45+
b = digitalio.DigitalInOut(board.BUTTON_B)
46+
b.switch_to_input(pull=digitalio.Pull.DOWN)
47+
48+
file = open("/triode_rise.wav", "rb")
49+
wave = WaveFile(file)
50+
51+
update_time = time.monotonic()
52+
53+
def play_sound():
54+
audio.play(wave)
55+
time.sleep(1)
56+
57+
def find_connection():
58+
for connection in radio.connections:
59+
if AppleNotificationService not in connection:
60+
continue
61+
if not connection.paired:
62+
connection.pair()
63+
return connection, connection[AppleNotificationService]
64+
return None, None
65+
66+
def check_dim_timeout():
67+
global update_time
68+
if a.value or b.value:
69+
update_time = time.monotonic()
70+
if time.monotonic() - update_time > DIM_TIMEOUT:
71+
if display.brightness > DIM_LEVEL:
72+
display.brightness = DIM_LEVEL
73+
else:
74+
if display.brightness == DIM_LEVEL:
75+
display.brightness = 1.0
76+
77+
78+
# Start advertising before messing with the display so that we can connect immediately.
79+
radio = adafruit_ble.BLERadio()
80+
advertisement = SolicitServicesAdvertisement()
81+
advertisement.complete_name = "CIRCUITPY"
82+
advertisement.solicited_services.append(AppleNotificationService)
83+
84+
def wrap_in_tilegrid(open_file):
85+
odb = displayio.OnDiskBitmap(open_file)
86+
return displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter())
87+
88+
display = tft_gizmo.TFT_Gizmo()
89+
group = displayio.Group(max_size=3)
90+
group.append(wrap_in_tilegrid(open("/ancs_connect.bmp", "rb")))
91+
display.show(group)
92+
93+
current_notification = None
94+
current_notifications = {}
95+
all_ids = []
96+
last_press = time.monotonic()
97+
active_connection, notification_service = find_connection()
98+
cleared = False
99+
100+
while True:
101+
if not active_connection:
102+
radio.start_advertising(advertisement)
103+
104+
while not active_connection:
105+
active_connection, notification_service = find_connection()
106+
check_dim_timeout()
107+
108+
# Connected
109+
update_time = time.monotonic()
110+
play_sound()
111+
112+
with open("/ancs_none.bmp", "rb") as no_notifications:
113+
group.append(wrap_in_tilegrid(no_notifications))
114+
while active_connection.connected:
115+
all_ids.clear()
116+
current_notifications = notification_service.active_notifications
117+
for id in current_notifications:
118+
notification = current_notifications[id]
119+
if notification.app_id not in APP_ICONS or notification.app_id in BLACKLIST:
120+
continue
121+
all_ids.append(id)
122+
123+
all_ids.sort(key=lambda x: current_notifications[x]._raw_date)
124+
125+
if current_notification and current_notification.removed:
126+
# Stop showing the latest and show that there are no new notifications.
127+
current_notification = None
128+
129+
if not current_notification and not all_ids and not cleared:
130+
cleared = True
131+
update_time = time.monotonic()
132+
group[1] = wrap_in_tilegrid(no_notifications)
133+
elif all_ids:
134+
cleared = False
135+
now = time.monotonic()
136+
if current_notification and current_notification.id in all_ids and \
137+
now - last_press < DELAY_AFTER_PRESS:
138+
index = all_ids.index(current_notification.id)
139+
else:
140+
index = len(all_ids) - 1
141+
if now - last_press >= DEBOUNCE:
142+
if b.value and index > 0:
143+
last_press = now
144+
index += -1
145+
if a.value and index < len(all_ids) - 1:
146+
last_press = now
147+
index += 1
148+
id = all_ids[index]
149+
if not current_notification or current_notification.id != id:
150+
update_time = now
151+
current_notification = current_notifications[id]
152+
print(current_notification._raw_date, current_notification)
153+
154+
app_icon_file = open(APP_ICONS[current_notification.app_id], "rb")
155+
group[1] = wrap_in_tilegrid(app_icon_file)
156+
157+
check_dim_timeout()
158+
159+
group.pop()
160+
update_time = time.monotonic()
161+
active_connection = None
162+
notification_service = None

CPB_ANCS/triode_rise.wav

25.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)