Skip to content

Commit 0954bf0

Browse files
committed
product overlay code
1 parent e7cb145 commit 0954bf0

File tree

1 file changed

+194
-0
lines changed
  • Fruit_Jam/Fruit_Jam_Product_Overlay

1 file changed

+194
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import time
6+
import board
7+
import supervisor
8+
9+
from adafruit_fruitjam import FruitJam
10+
from adafruit_fruitjam.peripherals import request_display_config
11+
12+
BG_COLOR = 0x0000FF
13+
14+
request_display_config(320, 240)
15+
display = supervisor.runtime.display
16+
17+
FETCH_DELAY = 12
18+
19+
# Set up where we'll be fetching data from
20+
DATA_SOURCE = "https://www.adafruit.com/api/products/6358"
21+
22+
TITLE_LOCATION = ["product_name"]
23+
SALE_PRICE_LOCATION = ["product_sale_price"]
24+
REG_PRICE_LOCATION = ["product_price"]
25+
STOCK_LOCATION = ["product_stock"]
26+
27+
config_index = 0
28+
29+
TEXT_POSITIONS = [
30+
{
31+
"title_anchor_point": (0, 0),
32+
"title_anchored_position": (4, 205 + 4),
33+
"stock_anchor_point": (1.0, 1.0),
34+
"stock_anchored_position": (display.width - 4, display.height - 4),
35+
"price_anchor_point": (1.0, 0),
36+
"price_anchored_position": (display.width - 4, 200),
37+
"outline_size": 1,
38+
"outline_color": 0x000000,
39+
},
40+
{
41+
"title_anchor_point": (0, 0),
42+
"title_anchored_position": (4, 205 + 4),
43+
"stock_anchor_point": (1.0, 1.0),
44+
"stock_anchored_position": (display.width - 4, display.height - 4),
45+
"price_anchor_point": (1.0, 0),
46+
"price_anchored_position": (display.width - 4, 200),
47+
"outline_size": 0,
48+
"outline_color": 0x000000,
49+
},
50+
{
51+
"title_anchor_point": (0, 0),
52+
"title_anchored_position": (4, 4),
53+
"stock_anchor_point": (1.0, 0),
54+
"stock_anchored_position": (display.width - 4, 26),
55+
"price_anchor_point": (1.0, 0),
56+
"price_anchored_position": (display.width - 4, 4),
57+
"outline_size": 0,
58+
"outline_color": 0x000000,
59+
},
60+
{
61+
"title_anchor_point": (0, 0),
62+
"title_anchored_position": (4, 4),
63+
"stock_anchor_point": (1.0, 0),
64+
"stock_anchored_position": (display.width - 4, 26),
65+
"price_anchor_point": (1.0, 0),
66+
"price_anchored_position": (display.width - 4, 4),
67+
"outline_size": 1,
68+
"outline_color": 0x000000,
69+
},
70+
{
71+
"title_anchor_point": (0, 0),
72+
"title_anchored_position": (4, -104),
73+
"stock_anchor_point": (1.0, 0),
74+
"stock_anchored_position": (display.width - 4, -126),
75+
"price_anchor_point": (1.0, 0),
76+
"price_anchored_position": (display.width - 4, -104),
77+
"outline_size": 1,
78+
"outline_color": 0x000000,
79+
},
80+
]
81+
82+
83+
def apply_hotkey_visuals(index):
84+
config = TEXT_POSITIONS[index]
85+
fruitjam.text_fields[0]["anchor_point"] = config["title_anchor_point"]
86+
fruitjam.text_fields[0]["position"] = config["title_anchored_position"]
87+
fruitjam.text_fields[0]["outline_color"] = config["outline_color"]
88+
fruitjam.text_fields[0]["outline_size"] = config["outline_size"]
89+
if fruitjam.text_fields[0]["label"] is not None:
90+
fruitjam.text_fields[0]["label"].anchor_point = config["title_anchor_point"]
91+
fruitjam.text_fields[0]["label"].anchored_position = config[
92+
"title_anchored_position"
93+
]
94+
fruitjam.text_fields[0]["label"].outline_size = config["outline_size"]
95+
fruitjam.text_fields[0]["label"].outline_color = config["outline_color"]
96+
fruitjam.text_fields[1]["anchor_point"] = config["stock_anchor_point"]
97+
fruitjam.text_fields[1]["position"] = config["stock_anchored_position"]
98+
fruitjam.text_fields[1]["outline_color"] = config["outline_color"]
99+
fruitjam.text_fields[1]["outline_size"] = config["outline_size"]
100+
if fruitjam.text_fields[1]["label"] is not None:
101+
fruitjam.text_fields[1]["label"].anchor_point = config["stock_anchor_point"]
102+
fruitjam.text_fields[1]["label"].anchored_position = config[
103+
"stock_anchored_position"
104+
]
105+
fruitjam.text_fields[1]["label"].outline_size = config["outline_size"]
106+
fruitjam.text_fields[1]["label"].outline_color = config["outline_color"]
107+
fruitjam.text_fields[2]["anchor_point"] = config["price_anchor_point"]
108+
fruitjam.text_fields[2]["position"] = config["price_anchored_position"]
109+
fruitjam.text_fields[2]["outline_color"] = config["outline_color"]
110+
fruitjam.text_fields[2]["outline_size"] = config["outline_size"]
111+
if fruitjam.text_fields[2]["label"] is not None:
112+
fruitjam.text_fields[2]["label"].anchor_point = config["price_anchor_point"]
113+
fruitjam.text_fields[2]["label"].anchored_position = config[
114+
"price_anchored_position"
115+
]
116+
fruitjam.text_fields[2]["label"].outline_size = config["outline_size"]
117+
fruitjam.text_fields[2]["label"].outline_color = config["outline_color"]
118+
119+
120+
def format_data(json_data):
121+
if "product_sale_price" in json_data:
122+
json_data["product_sale_price"] = f'${json_data["product_sale_price"]}'
123+
else:
124+
json_data["product_sale_price"] = f'${json_data["product_price"]}'
125+
126+
json_data["product_stock"] = f'Stock: {json_data["product_stock"]}'
127+
128+
129+
# the current working directory (where this file is)
130+
cwd = ("/" + __file__).rsplit("/", 1)[0]
131+
132+
fruitjam = FruitJam(
133+
url=DATA_SOURCE,
134+
json_path=(TITLE_LOCATION, STOCK_LOCATION, SALE_PRICE_LOCATION),
135+
status_neopixel=board.NEOPIXEL,
136+
default_bg=BG_COLOR,
137+
json_transform=[format_data],
138+
debug=True,
139+
)
140+
fruitjam.remove_all_text()
141+
fruitjam.add_text(
142+
text_wrap=35, text_maxlen=180, text_color=0xFFFFFF, outline_size=1
143+
) # title
144+
fruitjam.add_text(
145+
text_wrap=0, text_maxlen=30, text_color=0xFFFFFF, outline_size=1
146+
) # stock
147+
fruitjam.add_text(text_wrap=0, text_maxlen=30, text_color=0xFFFFFF, outline_size=1) #
148+
apply_hotkey_visuals(config_index)
149+
150+
fruitjam.neopixels.brightness = 0.1
151+
152+
fetch_success = False
153+
data_values = None
154+
last_fetch_time = 0
155+
156+
while not fetch_success:
157+
try:
158+
data_values = fruitjam.fetch()
159+
fruitjam._text[2]["label"].scale = 2 # pylint: disable=protected-access
160+
fetch_success = True
161+
last_fetch_time = time.monotonic()
162+
except ValueError as e:
163+
# no value found for product_sale_price
164+
print("product_sale_price not found. Using regular price.")
165+
print(fruitjam.json_path)
166+
fruitjam.json_path = (TITLE_LOCATION, STOCK_LOCATION, ["product_price"])
167+
print(fruitjam.json_path)
168+
time.sleep(5)
169+
except (RuntimeError, ConnectionError, OSError) as e:
170+
print("Some error occured, retrying! -", e)
171+
time.sleep(5)
172+
173+
old_btn1 = False
174+
old_btn2 = False
175+
old_btn3 = False
176+
177+
while True:
178+
btn1_pressed = fruitjam.button1
179+
if btn1_pressed and not old_btn1:
180+
config_index = (config_index + 1) % len(TEXT_POSITIONS)
181+
apply_hotkey_visuals(config_index)
182+
183+
now = time.monotonic()
184+
if last_fetch_time + FETCH_DELAY <= now:
185+
try:
186+
data_values = fruitjam.fetch()
187+
print(f"type: {fruitjam.text_fields[1]['label']}")
188+
fruitjam._text[2]["label"].scale = 2 # pylint: disable=protected-access
189+
fetch_success = True
190+
last_fetch_time = time.monotonic()
191+
except (ValueError, RuntimeError, ConnectionError, OSError) as e:
192+
print("Some error occured, retrying! -", e)
193+
194+
old_btn1 = btn1_pressed

0 commit comments

Comments
 (0)