Skip to content

Commit 3a93a5e

Browse files
committed
code for Qualia iOS Photo display
Uses MQTT with Adafruit IO to decode and display base64 encoded photos
1 parent 24406bf commit 3a93a5e

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

  • Qualia/Qualia_S3_iOS_Photo_Frame
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import time
6+
import os
7+
import ssl
8+
import io
9+
import binascii
10+
import jpegio
11+
import microcontroller
12+
import wifi
13+
import socketpool
14+
import displayio
15+
from adafruit_qualia.graphics import Graphics, Displays
16+
import adafruit_minimqtt.adafruit_minimqtt as MQTT
17+
18+
aio_username = os.getenv("ADAFRUIT_AIO_USERNAME")
19+
aio_key = os.getenv("ADAFRUIT_AIO_KEY")
20+
21+
print(f"Connecting to {os.getenv('CIRCUITPY_WIFI_SSID')}")
22+
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
23+
print(f"Connected to {os.getenv('CIRCUITPY_WIFI_SSID')}!")
24+
25+
camera_feed = aio_username + "/feeds/camera"
26+
27+
graphics = Graphics(Displays.ROUND40, default_bg=None, auto_refresh=True)
28+
29+
def center(g, b):
30+
# center the image
31+
g.x -= ((b.width * 2) - 720) // 4
32+
g.y -= ((b.height * 2) - 720) // 4
33+
34+
def decode_image(base64_msg):
35+
# Decode the base64 image into raw binary JPEG data
36+
decoded_image = binascii.a2b_base64(base64_msg)
37+
# Create a JpegDecoder instance
38+
decoder = jpegio.JpegDecoder()
39+
# Use io.BytesIO to treat the decoded image as a file-like object
40+
jpeg_data = io.BytesIO(decoded_image)
41+
# Open the JPEG data source from the BytesIO object
42+
width, height = decoder.open(jpeg_data)
43+
print(width, height)
44+
# Create a Bitmap with the dimensions of the JPEG image
45+
bitmap = displayio.Bitmap(width, height, 65536) # Use 65536 colors for RGB565
46+
# Decode the JPEG into the bitmap
47+
decoder.decode(bitmap)
48+
# pylint: disable=line-too-long
49+
grid = displayio.TileGrid(bitmap, pixel_shader=displayio.ColorConverter(input_colorspace=displayio.Colorspace.RGB565_SWAPPED))
50+
center(grid, bitmap)
51+
group = displayio.Group(scale=2)
52+
group.append(grid)
53+
graphics.display.root_group = group
54+
graphics.display.refresh()
55+
56+
# Define callback methods which are called when events occur
57+
def connected(client, userdata, flags, rc):
58+
# This function will be called when the client is connected
59+
# successfully to the broker.
60+
print(f"Connected to Adafruit IO! Listening for topic changes on {camera_feed}")
61+
# Subscribe to all changes on the onoff_feed.
62+
client.subscribe(camera_feed)
63+
64+
65+
def disconnected(client, userdata, rc):
66+
# This method is called when the client is disconnected
67+
print("Disconnected from Adafruit IO!")
68+
69+
70+
def message(client, topic, message):
71+
# This method is called when a topic the client is subscribed to
72+
# has a new message.
73+
print(f"New message on topic {topic}")
74+
decode_image(message)
75+
76+
pool = socketpool.SocketPool(wifi.radio)
77+
ssl_context = ssl.create_default_context()
78+
# Initialize an Adafruit IO HTTP API object
79+
mqtt_client = MQTT.MQTT(
80+
broker="io.adafruit.com",
81+
port=1883,
82+
username=aio_username,
83+
password=aio_key,
84+
socket_pool=pool,
85+
ssl_context=ssl_context,
86+
)
87+
# Setup the callback methods above
88+
mqtt_client.on_connect = connected
89+
mqtt_client.on_disconnect = disconnected
90+
mqtt_client.on_message = message
91+
92+
# Connect the client to the MQTT broker.
93+
print("Connecting to Adafruit IO...")
94+
mqtt_client.connect()
95+
while True:
96+
# Poll the message queue
97+
try:
98+
mqtt_client.loop(timeout=1)
99+
time.sleep(5)
100+
except Exception as error: # pylint: disable=broad-except
101+
print(error)
102+
time.sleep(5)
103+
microcontroller.reset()

0 commit comments

Comments
 (0)