Skip to content

Commit 27fb900

Browse files
authored
Merge pull request #2665 from makermelissa/main
Add SMS Messsage Scroller Project
2 parents 1f7367c + 9d02f94 commit 27fb900

File tree

1 file changed

+153
-0
lines changed
  • Matrix_Portal_S3_SMS_Scroller

1 file changed

+153
-0
lines changed

Matrix_Portal_S3_SMS_Scroller/code.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# SPDX-FileCopyrightText: 2023 Melissa-LeBlanc-Williams for Adafruit Industries
2+
# SPDX-FileCopyrightText: 2023 Erin St. Blaine for Adafruit Industries
3+
# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries
4+
#
5+
# SPDX-License-Identifier: MIT
6+
7+
# SMS Message board matrix display
8+
# uses AdafruitIO to serve up a message text feed and color feed
9+
# messages are displayed in order, updates periodically to look for new messages
10+
11+
from collections import deque
12+
import time
13+
import random
14+
import board
15+
from adafruit_matrixportal.matrix import Matrix
16+
from adafruit_matrixportal.network import Network
17+
from messageboard import MessageBoard
18+
from messageboard.fontpool import FontPool
19+
from messageboard.message import Message
20+
21+
WIDTH = 64
22+
HEIGHT = 32
23+
DEFAULT_COLOR = 0x0000FF
24+
DEFAULT_MESSAGE = "Text Adafruit IO to update"
25+
DEFAULT_FONT = "arial_sm"
26+
MESSAGES_FEED = "text"
27+
COLORS_FEED = "color"
28+
UPDATE_DELAY = 50 # Seconds between updates
29+
SCROLL_DURATION = 6 # Seconds to scroll entire message
30+
RANDOMIZE_FONTS = True # Randomize fonts, make "False" to just use the default font
31+
RANDOMIZE_COLORS = True # Randomise colors, make "False" to just use the default color
32+
KEEP_LATEST_MESSAGE = True # Keep the last message in the Message Feed
33+
34+
# --- Display setup ---
35+
matrix = Matrix(width=WIDTH, height=HEIGHT, bit_depth=5)
36+
network = Network(status_neopixel=board.NEOPIXEL, debug=True)
37+
messageboard = MessageBoard(matrix)
38+
39+
fontpool = FontPool()
40+
fontpool.add_font("arial_sm", "fonts/Arial-10.pcf")
41+
fontpool.add_font("arial_lg", "fonts/Arial-15.pcf")
42+
fontpool.add_font("sofia", "fonts/Sofia-Regular-15.pcf")
43+
44+
system_message = Message(fontpool.find_font("arial_sm"))
45+
46+
message_fonts = ("sofia", "arial_lg")
47+
48+
message_queue = deque((), 10000) # Use a double-ended queue for messages
49+
colors = []
50+
51+
52+
def update_data():
53+
print("Updating data from Adafruit IO")
54+
# Only show connecting message if not connected
55+
if not network.is_connected:
56+
system_message.clear()
57+
system_message.add_text("Connecting", color=0xFFFF00)
58+
messageboard.animate(system_message, "Static", "show")
59+
60+
try:
61+
color_data = network.get_io_data(COLORS_FEED)
62+
colors.clear()
63+
for json_data in color_data:
64+
color = network.json_traverse(json_data, ["value"])
65+
colors.append(int(color[1:], 16))
66+
# pylint: disable=broad-except
67+
except Exception as error:
68+
print(error)
69+
70+
try:
71+
messages_data = network.get_io_data(MESSAGES_FEED)
72+
message_ids = []
73+
sms_messages = [] # Temporary place for messages
74+
for json_data in messages_data:
75+
message_ids.append(network.json_traverse(json_data, ["id"]))
76+
sms_messages.append(network.json_traverse(json_data, ["value"]))
77+
78+
# Results are returned in reverse order, so we reverse that and add to end of queue
79+
sms_messages.reverse()
80+
for sms_message in sms_messages:
81+
message_queue.append(sms_message)
82+
83+
# Remove any messages that have been grabbed except the latest one if setting enabled
84+
start_index = 1 if KEEP_LATEST_MESSAGE else 0
85+
for index in range(start_index, len(message_ids)):
86+
message_id = message_ids[index]
87+
network.delete_io_data(MESSAGES_FEED, message_id)
88+
89+
# pylint: disable=broad-except
90+
except Exception as error:
91+
print(error)
92+
93+
messageboard.animate(system_message, "Static", "hide")
94+
95+
96+
def get_new_rand_item(current_index, item_list):
97+
if not item_list:
98+
return None
99+
if len(item_list) > 1 and current_index is not None:
100+
new_index = current_index
101+
while new_index == current_index:
102+
new_index = random.randrange(0, len(item_list))
103+
else:
104+
new_index = random.randrange(0, len(item_list))
105+
return new_index
106+
107+
108+
update_data()
109+
last_update = time.monotonic()
110+
quote_index = None
111+
color_index = None
112+
font_index = None
113+
message_text = None
114+
115+
while True:
116+
if len(message_queue) >= 1:
117+
message_text = message_queue.popleft()
118+
119+
if message_text is None:
120+
message_text = DEFAULT_MESSAGE
121+
122+
# Choose a random color from colors
123+
if RANDOMIZE_COLORS:
124+
color_index = get_new_rand_item(color_index, colors)
125+
if color_index is None:
126+
message_color = DEFAULT_COLOR
127+
else:
128+
message_color = colors[color_index]
129+
else:
130+
message_color = DEFAULT_COLOR
131+
132+
# Choose a random font from message_fonts
133+
if RANDOMIZE_FONTS:
134+
font_index = get_new_rand_item(font_index, message_fonts)
135+
if font_index is None:
136+
message_font = DEFAULT_FONT
137+
else:
138+
message_font = message_fonts[font_index]
139+
else:
140+
message_font = DEFAULT_FONT
141+
142+
# Set the quote text and color
143+
message = Message(fontpool.find_font(message_font))
144+
message.add_text(message_text, color=message_color)
145+
146+
# Scroll the message
147+
duration = SCROLL_DURATION / 2
148+
messageboard.animate(message, "Scroll", "in_from_right", duration=duration)
149+
messageboard.animate(message, "Scroll", "out_to_left", duration=duration)
150+
151+
if time.monotonic() > last_update + UPDATE_DELAY:
152+
update_data()
153+
last_update = time.monotonic()

0 commit comments

Comments
 (0)