Skip to content

Commit e6a3e65

Browse files
committed
MagTag 50 Cent CPI project files
1 parent 7e3eaf1 commit e6a3e65

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed
12.8 KB
Binary file not shown.

MagTag/MagTag_50Cent_CPI/code.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# SPDX-FileCopyrightText: 2025 Tim C, written for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""
5+
50 Cent Consumer Price Index Tracker
6+
7+
This project illustrates how to fetch CPI data from the
8+
US Bureau of Labor Statistics API. CPI data from 1994,
9+
when 50 Cent adopted his moniker, is compared with the latest
10+
data to determine how much 50 Cent from 1994 is worth today.
11+
"""
12+
import json
13+
import os
14+
import time
15+
16+
import alarm
17+
import displayio
18+
from displayio import OnDiskBitmap, TileGrid, Group
19+
import supervisor
20+
from terminalio import FONT
21+
import wifi
22+
23+
import adafruit_connection_manager
24+
from adafruit_display_text.text_box import TextBox
25+
import adafruit_requests
26+
27+
28+
# CPI Data URL
29+
latest_cpi_url = "https://api.bls.gov/publicAPI/v2/timeseries/data/CUUR0000SA0"
30+
# CUUR0000SA0 the series ID for CPI-U (All items)
31+
# Note: bls.gov API is limited to 20 requests per day for unregistered users
32+
33+
# CPI value for June 1994
34+
june_94_cpi = 148.0
35+
36+
# Get WiFi details, ensure these are setup in settings.toml
37+
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
38+
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
39+
40+
# Initalize Wifi, Socket Pool, Request Session
41+
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
42+
ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio)
43+
requests = adafruit_requests.Session(pool, ssl_context)
44+
45+
try:
46+
# Connect to the WiFi network
47+
wifi.radio.connect(ssid, password)
48+
except OSError as ose:
49+
print(f"OSError: {ose}")
50+
print("Wifi connected!")
51+
52+
# Get display reference
53+
display = supervisor.runtime.display
54+
55+
# Set to portrait orientation
56+
display.rotation = 0
57+
58+
# Group to hold all visual elements
59+
main_group = Group()
60+
61+
# Full display sized white background
62+
white_bg_group = Group(scale=8)
63+
white_bg_bmp = displayio.Bitmap(display.width // 8, display.height // 8, 1)
64+
white_bg_palette = displayio.Palette(1)
65+
white_bg_palette[0] = 0xFFFFFF
66+
white_bg_tg = TileGrid(bitmap=white_bg_bmp, pixel_shader=white_bg_palette)
67+
white_bg_group.append(white_bg_tg)
68+
main_group.append(white_bg_group)
69+
70+
# 50 Cent photo
71+
photo_bmp = OnDiskBitmap("50_cent.bmp")
72+
photo_tg = TileGrid(bitmap=photo_bmp, pixel_shader=photo_bmp.pixel_shader)
73+
main_group.append(photo_tg)
74+
75+
76+
def get_latest_cpi_value():
77+
"""
78+
Fetch the latest CPI data from BLS API.
79+
80+
:return: tuple containing (latest CPI value, month, year)
81+
"""
82+
try:
83+
response = requests.get(latest_cpi_url)
84+
try:
85+
json_data = response.json()
86+
except json.decoder.JSONDecodeError as json_error:
87+
raise Exception(f"JSON Parse error: {response.text}") from json_error
88+
89+
latest_data = json_data["Results"]["series"][0]["data"][0]
90+
91+
return (
92+
float(latest_data["value"]),
93+
latest_data["periodName"],
94+
latest_data["year"],
95+
)
96+
97+
except Exception as e:
98+
raise Exception(f"Error fetching data from BLS API: {e}") from e
99+
100+
101+
# fetch the latest CPI data
102+
latest_cpi_value, month, year = get_latest_cpi_value()
103+
104+
# Label for the message below the photo
105+
message_lbl = TextBox(
106+
FONT,
107+
128,
108+
TextBox.DYNAMIC_HEIGHT,
109+
align=TextBox.ALIGN_CENTER,
110+
text=f"As of {month} {year}\n50 Cent is worth",
111+
color=0x000000,
112+
scale=1,
113+
)
114+
message_lbl.anchor_point = (0, 0)
115+
message_lbl.anchored_position = (0, photo_tg.tile_height + 6)
116+
main_group.append(message_lbl)
117+
118+
# calculate current value of 50 cents from 1994
119+
current_value = round(50.0 * (latest_cpi_value / june_94_cpi) + 0.5)
120+
121+
# Label for the calculated value
122+
amount_lbl = TextBox(
123+
FONT,
124+
128 // 3,
125+
TextBox.DYNAMIC_HEIGHT,
126+
align=TextBox.ALIGN_CENTER,
127+
text=f"{current_value}",
128+
color=0x000000,
129+
scale=3,
130+
)
131+
amount_lbl.anchor_point = (0, 0)
132+
amount_lbl.anchored_position = (0, photo_tg.tile_height + message_lbl.height + 12)
133+
main_group.append(amount_lbl)
134+
135+
# Cent label at bottom of display
136+
cent_lbl = TextBox(
137+
FONT,
138+
128,
139+
TextBox.DYNAMIC_HEIGHT,
140+
align=TextBox.ALIGN_CENTER,
141+
text="Cent",
142+
color=0x000000,
143+
scale=1,
144+
)
145+
cent_lbl.anchor_point = (0, 1)
146+
cent_lbl.anchored_position = (0, display.height - 2)
147+
main_group.append(cent_lbl)
148+
149+
# set main_group showing on the display
150+
display.root_group = main_group
151+
display.refresh()
152+
153+
# Sleep for 1 day
154+
al = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 86400)
155+
alarm.exit_and_deep_sleep_until_alarms(al)
156+
# Does not return. Exits, and restarts after 1 day

0 commit comments

Comments
 (0)