Skip to content

Commit 014c913

Browse files
authored
Merge pull request #2396 from adafruit/octoprint_mqtt
adding code for OctoPrint MQTT project
2 parents 8b6134d + 586cf5d commit 014c913

File tree

3 files changed

+259
-0
lines changed

3 files changed

+259
-0
lines changed

OctoPrint_MQTT_Controller/.trinket_m0.test.skip

Whitespace-only changes.

OctoPrint_MQTT_Controller/code.py

+259
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
import time
5+
import ssl
6+
import os
7+
import json
8+
import socketpool
9+
import wifi
10+
import adafruit_requests
11+
from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError
12+
import board
13+
import digitalio
14+
import displayio
15+
import terminalio
16+
from adafruit_progressbar.horizontalprogressbar import (
17+
HorizontalProgressBar,
18+
HorizontalFillDirection,
19+
)
20+
from adafruit_display_shapes.rect import Rect
21+
from adafruit_display_text import bitmap_label, wrap_text_to_lines
22+
import neopixel
23+
from adafruit_led_animation.animation.rainbow import Rainbow
24+
from adafruit_led_animation.animation.blink import Blink
25+
26+
aio_username = os.getenv('aio_username')
27+
aio_key = os.getenv('aio_key')
28+
29+
wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD'))
30+
31+
# Make the display context
32+
splash = displayio.Group()
33+
board.DISPLAY.show(splash)
34+
35+
width = 165
36+
height = 30
37+
38+
x = 70
39+
y = 100
40+
41+
# Create a new progress_bar object at (x, y)
42+
progress_bar = HorizontalProgressBar(
43+
(x, y),
44+
(width, height),
45+
fill_color=0x000000,
46+
outline_color=0xFFFFFF,
47+
bar_color=0x13c100,
48+
direction=HorizontalFillDirection.LEFT_TO_RIGHT
49+
)
50+
51+
# Append progress_bar to the splash group
52+
splash.append(progress_bar)
53+
54+
rect = Rect(60, 0, 2, 135, fill=0xFFFFFF)
55+
splash.append(rect)
56+
57+
img = displayio.OnDiskBitmap("octoprint_logo.bmp")
58+
59+
tile_grid = displayio.TileGrid(bitmap=img, pixel_shader=img.pixel_shader, x = 185, y=5)
60+
splash.append(tile_grid)
61+
62+
text = bitmap_label.Label(terminalio.FONT, text="Connecting", scale=2, x=75, y=45)
63+
splash.append(text)
64+
65+
d0_text = bitmap_label.Label(terminalio.FONT, text="Cooldown", scale=1, x=5, y=10)
66+
splash.append(d0_text)
67+
d1_text = bitmap_label.Label(terminalio.FONT, text="Heat up", scale=1, x=5, y=65)
68+
splash.append(d1_text)
69+
d2_text = bitmap_label.Label(terminalio.FONT, text="Reboot", scale=1, x=5, y=125)
70+
splash.append(d2_text)
71+
72+
led = digitalio.DigitalInOut(board.LED)
73+
led.direction = digitalio.Direction.OUTPUT
74+
75+
button0 = digitalio.DigitalInOut(board.D0)
76+
button0.direction = digitalio.Direction.INPUT
77+
button0.pull = digitalio.Pull.UP
78+
79+
button1 = digitalio.DigitalInOut(board.D1)
80+
button1.direction = digitalio.Direction.INPUT
81+
button1.pull = digitalio.Pull.DOWN
82+
83+
button2 = digitalio.DigitalInOut(board.D2)
84+
button2.direction = digitalio.Direction.INPUT
85+
button2.pull = digitalio.Pull.DOWN
86+
87+
button0_state = False
88+
button1_state = False
89+
button2_state = False
90+
91+
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness = 0.6)
92+
93+
pool = socketpool.SocketPool(wifi.radio)
94+
95+
requests = adafruit_requests.Session(pool, ssl.create_default_context())
96+
io = IO_HTTP(aio_username, aio_key, requests)
97+
98+
try:
99+
# get feed
100+
printing_status = io.get_feed("printing")
101+
print_done = io.get_feed("printdone")
102+
printer_state = io.get_feed("printerstatechanged")
103+
shutdown = io.get_feed("shutdown")
104+
heat_up = io.get_feed("heatup")
105+
cooldown = io.get_feed("cooldown")
106+
resume = io.get_feed("printresumed")
107+
pause = io.get_feed("printpaused")
108+
cancelled = io.get_feed("printcancelled")
109+
110+
except AdafruitIO_RequestError:
111+
# if no feed exists, create one
112+
printing_status = io.create_new_feed("printing")
113+
print_done = io.create_new_feed("printdone")
114+
printer_state = io.create_new_feed("printerstatechanged")
115+
shutdown = io.create_new_feed("shutdown")
116+
heat_up = io.create_new_feed("heatup")
117+
cooldown = io.create_new_feed("cooldown")
118+
resume = io.create_new_feed("printresumed")
119+
pause = io.create_new_feed("printpaused")
120+
cancelled = io.create_new_feed("printcancelled")
121+
122+
read_feeds = [printing_status, printer_state, print_done]
123+
send_while_idle_feeds = [cooldown, heat_up, shutdown]
124+
send_while_printing_feeds = [pause, resume, cancelled]
125+
new_feed_msg = ["None", "None", "None"]
126+
last_feed_msg = ["none","none","none"]
127+
msg_json = [{"path": "none"}, {"state_id": "NONE"}, {"path": "none"}]
128+
print_progress = 0
129+
current_state = 0
130+
state_value = 0
131+
current_file = None
132+
finished_file = None
133+
red = (255, 0, 0)
134+
green = (0, 255, 0)
135+
blue = (0, 0, 255)
136+
cyan = (0, 255, 255)
137+
purple = (255, 0, 255)
138+
yellow = (255, 255, 0)
139+
140+
printer_state_options = ["OPEN_SERIAL", "DETECT_SERIAL",
141+
"DETECT_BAUDRATE", "CONNECTING", "OPERATIONAL", "PRINTING", "PAUSING", "PAUSED",
142+
"CLOSED", "ERROR", "FINISHING", "CLOSED_WITH_ERROR", "TRANSFERING_FILE", "OFFLINE", "STARTING",
143+
"CANCELLING", "UNKNOWN", "NONE"]
144+
colors = [green, yellow, cyan, yellow,
145+
green, purple, yellow, yellow, red,
146+
red, blue, red, yellow, red,
147+
purple, red, red, red]
148+
149+
clock = 5
150+
151+
rainbow = Rainbow(pixel, speed=0.1, period=2)
152+
blink = Blink(pixel, speed=0.5, color=green)
153+
154+
while True:
155+
if button0.value and button0_state:
156+
led.value = False
157+
button0_state = False
158+
if not button1.value and button1_state:
159+
led.value = False
160+
button1_state = False
161+
if not button2.value and button2_state:
162+
led.value = False
163+
button2_state = False
164+
165+
if current_state in ("PRINTING", "PAUSED", "PAUSING"):
166+
rainbow.animate()
167+
if not button0.value and not button0_state:
168+
led.value = True
169+
io.send_data(send_while_printing_feeds[0]["key"], "ping")
170+
button0_state = True
171+
if button1.value and not button1_state:
172+
led.value = True
173+
io.send_data(send_while_printing_feeds[1]["key"], "ping")
174+
button1_state = True
175+
if button2.value and not button2_state:
176+
led.value = True
177+
io.send_data(send_while_printing_feeds[2]["key"], "ping")
178+
button2_state = True
179+
else:
180+
blink.color=colors[state_value]
181+
blink.animate()
182+
if not button0.value and not button0_state:
183+
if finished_file == current_file:
184+
current_file = "None"
185+
progress_bar.value = 100
186+
progress_bar.bar_color = colors[state_value]
187+
text.text = "\n".join(wrap_text_to_lines("Status: %s" % current_state, 11))
188+
d0_text.text = "Cooldown"
189+
d1_text.text = "Heat up"
190+
d2_text.text = "Reboot"
191+
button0_state = True
192+
else:
193+
led.value = True
194+
io.send_data(send_while_idle_feeds[0]["key"], "ping")
195+
button0_state = True
196+
if button1.value and not button1_state:
197+
led.value = True
198+
io.send_data(send_while_idle_feeds[1]["key"], "ping")
199+
button1_state = True
200+
if button2.value and not button2_state:
201+
led.value = True
202+
io.send_data(send_while_idle_feeds[2]["key"], "ping")
203+
button2_state = True
204+
if (time.monotonic() - clock) > 15:
205+
# get data
206+
for feed in range(3):
207+
try:
208+
data = io.receive_data(read_feeds[feed]["key"])
209+
except AdafruitIO_RequestError:
210+
print("Check that OctoPrint is sending data! Check your IO dashboard.")
211+
# if a new value is detected
212+
if data["value"] != last_feed_msg[feed]:
213+
# assign value to new_msg
214+
new_feed_msg[feed] = data["value"]
215+
msg_json[feed] = json.loads(data["value"])
216+
print(read_feeds[feed]["key"])
217+
print()
218+
print(new_feed_msg[feed])
219+
print()
220+
print_progress = int(msg_json[0]['progress'])
221+
current_file = str(msg_json[0]['path'])
222+
current_state = str(msg_json[1]['state_id'])
223+
finished_file = str(msg_json[2]['path'])
224+
state_value = printer_state_options.index(current_state)
225+
# log msg
226+
last_feed_msg[feed] = new_feed_msg[feed]
227+
if current_state == "PRINTING":
228+
progress_bar.value = print_progress
229+
#octoprint green
230+
progress_bar.bar_color = 0x13c100
231+
text.text = "\n".join(wrap_text_to_lines("%d%% Printed" % print_progress, 7))
232+
d0_text.text = "Pause"
233+
d1_text.text = "Resume"
234+
d2_text.text = "Cancel"
235+
elif current_state in ("PAUSED", "PAUSING"):
236+
progress_bar.value = print_progress
237+
progress_bar.bar_color = colors[state_value]
238+
text.text = "\n".join(wrap_text_to_lines("Status: %s" % current_state, 11))
239+
d0_text.text = "Pause"
240+
d1_text.text = "Resume"
241+
d2_text.text = "Cancel"
242+
# when a print is finished:
243+
elif finished_file == current_file and print_progress == 100:
244+
progress_bar.value = 100
245+
progress_bar.bar_color = purple
246+
text.text = "\n".join(wrap_text_to_lines("Print Finished!", 11))
247+
d0_text.text = "Confirm"
248+
d1_text.text = " "
249+
d2_text.text = " "
250+
# when printer is idle, display status
251+
else:
252+
progress_bar.value = 100
253+
progress_bar.bar_color = colors[state_value]
254+
text.text = "\n".join(wrap_text_to_lines("Status: %s" % current_state, 11))
255+
d0_text.text = "Cooldown"
256+
d1_text.text = "Heat up"
257+
d2_text.text = "Reboot"
258+
# reset clock
259+
clock = time.monotonic()
2.53 KB
Binary file not shown.

0 commit comments

Comments
 (0)