Skip to content

Commit 1164297

Browse files
committed
code for Matter sensor dashboard
CircuitPython code for Matter sensor demo. Displays data from four different sensor feeds and sends data to one feed with the onboard buttons. IO communication is handled with MQTT
1 parent f8e920e commit 1164297

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed

Matter_Devices_Dashboard/code.py

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
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 wifi
9+
import socketpool
10+
import microcontroller
11+
import board
12+
import digitalio
13+
import displayio
14+
from adafruit_bitmap_font import bitmap_font
15+
from adafruit_display_text import bitmap_label
16+
from adafruit_display_shapes.circle import Circle
17+
from adafruit_display_shapes.roundrect import RoundRect
18+
from adafruit_ticks import ticks_ms, ticks_add, ticks_diff
19+
import adafruit_minimqtt.adafruit_minimqtt as MQTT
20+
21+
aio_username = os.getenv("ADAFRUIT_AIO_USERNAME")
22+
aio_key = os.getenv("ADAFRUIT_AIO_KEY")
23+
24+
# feeds!
25+
temp_feed = aio_username + "/feeds/eve-temp" # temperature sensor
26+
humid_feed = aio_username + "/feeds/eve-humid" # humidity sensor
27+
lux_feed = aio_username + "/feeds/eve-light" # lux sensor
28+
occupy_feed = aio_username + "/feeds/eve-occupy" # occupation sensor
29+
light_feed = aio_username + "/feeds/nanoleaf" # lightstrip
30+
31+
# buttons
32+
button0 = digitalio.DigitalInOut(board.D0)
33+
button0.direction = digitalio.Direction.INPUT
34+
button0.pull = digitalio.Pull.UP
35+
button0_state = False
36+
button1 = digitalio.DigitalInOut(board.D1)
37+
button1.direction = digitalio.Direction.INPUT
38+
button1.pull = digitalio.Pull.DOWN
39+
button1_state = False
40+
button2 = digitalio.DigitalInOut(board.D2)
41+
button2.direction = digitalio.Direction.INPUT
42+
button2.pull = digitalio.Pull.DOWN
43+
button2_state = False
44+
45+
display = board.DISPLAY
46+
group = displayio.Group()
47+
display.root_group = group
48+
49+
# load background bitmap
50+
bitmap = displayio.OnDiskBitmap("/tft_bg.bmp")
51+
tile_grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader)
52+
group = displayio.Group()
53+
group.append(tile_grid)
54+
55+
# bitmap font
56+
font_file = "/roundedHeavy-26.bdf"
57+
font = bitmap_font.load_font(font_file)
58+
# text elements
59+
temp_text = bitmap_label.Label(font, text="00.0°C", x=55, y=70, color=0xFFFFFF)
60+
group.append(temp_text)
61+
humid_text = bitmap_label.Label(font, text="00.0%", x=120, y=70, color=0xFFFFFF)
62+
group.append(humid_text)
63+
lux_text = bitmap_label.Label(font, text="00 lx", x=190, y=70, color=0xFFFFFF)
64+
group.append(lux_text)
65+
occupy_text = bitmap_label.Label(font, text="Occupied?", x=128,
66+
y=display.height - 12, color=0xFFFFFF)
67+
group.append(occupy_text)
68+
onOff_circ = Circle(display.width - 12, display.height - 12, 10, fill=0xcc0000)
69+
group.append(onOff_circ)
70+
scene_select = RoundRect(0, 0, 42, 40, 8, fill=None, outline=0xcccc00, stroke=6)
71+
scene_y = [0, int(display.height / 2) - int(scene_select.height / 2),
72+
display.height - scene_select.height - 1]
73+
group.append(scene_select)
74+
75+
display.root_group = group
76+
print()
77+
print("Connecting to WiFi...")
78+
# connect to your SSID
79+
wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD'))
80+
print("Connected to WiFi!")
81+
82+
# pylint: disable=unused-argument
83+
# Define callback methods which are called when events occur
84+
def connected(client, userdata, flags, rc): # pylint: disable=unused-argument
85+
# This function will be called when the client is connected
86+
# successfully to the broker.
87+
print("Connected to Adafruit IO!")
88+
# Subscribe to all changes on feeds
89+
client.subscribe(temp_feed)
90+
client.subscribe(humid_feed)
91+
client.subscribe(lux_feed)
92+
client.subscribe(occupy_feed)
93+
client.subscribe(light_feed)
94+
95+
def disconnected(client, userdata, rc): # pylint: disable=unused-argument
96+
# This method is called when the client is disconnected
97+
print("Disconnected from Adafruit IO!")
98+
99+
def on_message(client, topic, msg): # pylint: disable=unused-argument
100+
# This method is called when a topic the client is subscribed to
101+
# has a new message.
102+
print(f"New message on topic {topic}")
103+
104+
def on_temp_msg(client, topic, msg):
105+
print(f"temp feed data: {msg}°C")
106+
temp_text.text = f"{float(msg):.01f}°C"
107+
108+
def on_humid_msg(client, topic, msg):
109+
print(f"humid feed data: {msg}%")
110+
humid_text.text = f"{float(msg):.01f}%"
111+
112+
def on_lux_msg(client, topic, msg):
113+
print(f"lux feed data: {msg} lx")
114+
lux_text.text = f"{float(msg):.00f} lx"
115+
116+
def on_occupy_msg(client, topic, msg):
117+
print(f"occupation feed data: {msg}")
118+
if msg == "1":
119+
onOff_circ.fill = 0x00cc00
120+
else:
121+
onOff_circ.fill = 0xcc0000
122+
123+
def on_light_msg(client, topic, msg):
124+
print(f"light scene selected: {msg}")
125+
scene_select.y = scene_y[int(msg)]
126+
127+
pool = socketpool.SocketPool(wifi.radio)
128+
ssl_context = ssl.create_default_context()
129+
# Initialize an Adafruit IO HTTP API object
130+
mqtt_client = MQTT.MQTT(
131+
broker="io.adafruit.com",
132+
port=1883,
133+
username=aio_username,
134+
password=aio_key,
135+
socket_pool=pool,
136+
ssl_context=ssl_context,
137+
)
138+
# Setup the callback methods above
139+
mqtt_client.on_connect = connected
140+
mqtt_client.on_disconnect = disconnected
141+
mqtt_client.on_message = on_message
142+
mqtt_client.add_topic_callback(temp_feed, on_temp_msg)
143+
mqtt_client.add_topic_callback(humid_feed, on_humid_msg)
144+
mqtt_client.add_topic_callback(lux_feed, on_lux_msg)
145+
mqtt_client.add_topic_callback(occupy_feed, on_occupy_msg)
146+
mqtt_client.add_topic_callback(light_feed, on_light_msg)
147+
148+
# Connect the client to the MQTT broker.
149+
print("Connecting to Adafruit IO...")
150+
mqtt_client.connect()
151+
152+
clock_clock = ticks_ms()
153+
clock_timer = 5 * 1000
154+
155+
while True:
156+
try:
157+
if ticks_diff(ticks_ms(), clock_clock) >= clock_timer:
158+
mqtt_client.loop(timeout=1)
159+
clock_clock = ticks_add(clock_clock, clock_timer)
160+
# reset button state on release
161+
if button0.value and button0_state:
162+
button0_state = False
163+
if not button1.value and button1_state:
164+
button1_state = False
165+
if not button2.value and button2_state:
166+
button2_state = False
167+
# buttons change light scenes
168+
if not button0.value and not button0_state:
169+
mqtt_client.publish(light_feed, 0)
170+
scene_select.y = scene_y[0]
171+
button0_state = True
172+
if button1.value and not button1_state:
173+
mqtt_client.publish(light_feed, 1)
174+
scene_select.y = scene_y[1]
175+
button1_state = True
176+
if button2.value and not button2_state:
177+
mqtt_client.publish(light_feed, 2)
178+
scene_select.y = scene_y[2]
179+
button2_state = True
180+
except Exception as error: # pylint: disable=broad-except
181+
print(error)
182+
mqtt_client.disconnect()
183+
time.sleep(5)
184+
microcontroller.reset()

0 commit comments

Comments
 (0)