Skip to content

Commit 1a5030c

Browse files
authored
Merge pull request #1543 from dherrada/iot-hub
Added FunHouse IOT hub stuff
2 parents 6230b4e + c01b9cc commit 1a5030c

10 files changed

Lines changed: 1037 additions & 0 deletions
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# SPDX-FileCopyrightText: 2021 Dylan Herrada for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
"""
5+
Adafruit IO connected LiPo charger.
6+
Uses:
7+
* https://www.adafruit.com/product/4712
8+
* Feather board (M4 or RP2040 reccomended)
9+
* https://www.adafruit.com/product/4264
10+
* https://www.adafruit.com/product/2890
11+
* https://www.adafruit.com/product/2900
12+
Either the Feather or the Airlift Featherwing should have stacking headers for the display.
13+
"""
14+
15+
import time
16+
import board
17+
from adafruit_lc709203f import LC709203F
18+
import busio
19+
from digitalio import DigitalInOut
20+
from adafruit_esp32spi import adafruit_esp32spi
21+
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
22+
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
23+
import neopixel
24+
import adafruit_minimqtt.adafruit_minimqtt as MQTT
25+
from adafruit_io.adafruit_io import IO_MQTT
26+
27+
import displayio
28+
import terminalio
29+
from adafruit_display_text import label
30+
import adafruit_displayio_ssd1306
31+
32+
displayio.release_displays()
33+
34+
### WiFi ###
35+
36+
# Get wifi details and more from a secrets.py file
37+
try:
38+
from secrets import secrets
39+
except ImportError:
40+
print("WiFi secrets are kept in secrets.py, please add them there!")
41+
raise
42+
43+
44+
# If you are using a board with pre-defined ESP32 Pins:
45+
esp32_cs = DigitalInOut(board.D13)
46+
esp32_ready = DigitalInOut(board.D11)
47+
esp32_reset = DigitalInOut(board.D12)
48+
49+
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
50+
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
51+
"""Use below for Most Boards"""
52+
status_light = neopixel.NeoPixel(
53+
board.NEOPIXEL, 1, brightness=0.2
54+
) # Uncomment for Most Boards
55+
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
56+
57+
# Define callback functions which will be called when certain events happen.
58+
# pylint: disable=unused-argument
59+
def connected(client):
60+
client.subscribe("battery")
61+
62+
63+
def subscribe(client, userdata, topic, granted_qos):
64+
# This method is called when the client subscribes to a new feed.
65+
print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos))
66+
67+
68+
def message(client, feed_id, payload):
69+
print("Feed {0} received new value: {1}".format(feed_id, payload))
70+
71+
72+
# Connect to WiFi
73+
print("Connecting to WiFi...")
74+
wifi.connect()
75+
print("Connected!")
76+
77+
# Initialize MQTT interface with the esp interface
78+
MQTT.set_socket(socket, esp)
79+
80+
# Initialize a new MQTT Client object
81+
mqtt_client = MQTT.MQTT(
82+
broker="io.adafruit.com",
83+
username=secrets["aio_username"],
84+
password=secrets["aio_key"],
85+
)
86+
87+
88+
# Initialize an Adafruit IO MQTT Client
89+
io = IO_MQTT(mqtt_client)
90+
91+
# Connect the callback methods defined above to Adafruit IO
92+
io.on_connect = connected
93+
io.on_subscribe = subscribe
94+
io.on_message = message
95+
96+
# Connect to Adafruit IO
97+
print("Connecting to Adafruit IO...")
98+
io.connect()
99+
100+
display_bus = displayio.I2CDisplay(board.I2C(), device_address=0x3C)
101+
102+
WIDTH = 128
103+
HEIGHT = 32
104+
BORDER = 2
105+
106+
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=WIDTH, height=HEIGHT)
107+
108+
splash = displayio.Group(max_size=10)
109+
display.show(splash)
110+
111+
digital_label = label.Label(
112+
terminalio.FONT, text="Battery Percent: ", color=0xFFFFFF, x=4, y=4
113+
)
114+
splash.append(digital_label)
115+
alarm_label = label.Label(terminalio.FONT, text="Voltage: ", color=0xFFFFFF, x=4, y=14)
116+
splash.append(alarm_label)
117+
118+
119+
sensor = LC709203F(board.I2C())
120+
121+
start = 0
122+
while True:
123+
io.loop()
124+
percent = sensor.cell_percent
125+
if time.time() - start > 60:
126+
io.publish("battery", int(percent))
127+
start = time.time()
128+
splash[0].text = f"Percent: {str(int(percent))}%"
129+
splash[1].text = f"Voltage: {str(sensor.cell_voltage)}"
130+
time.sleep(1)
75.2 KB
Binary file not shown.

FunHouse_IOT_Hub/code.py

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
# SPDX-FileCopyrightText: 2021 Dylan Herrada for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
import time
5+
import ssl
6+
import displayio
7+
import board
8+
from digitalio import DigitalInOut, Direction, Pull
9+
from adafruit_display_text.label import Label
10+
import terminalio
11+
import touchio
12+
import socketpool
13+
import wifi
14+
import adafruit_minimqtt.adafruit_minimqtt as MQTT
15+
from adafruit_io.adafruit_io import IO_MQTT
16+
from adafruit_dash_display import Hub
17+
18+
# Set up navigation buttons
19+
up = DigitalInOut(board.BUTTON_UP)
20+
up.direction = Direction.INPUT
21+
up.pull = Pull.DOWN
22+
23+
select = DigitalInOut(board.BUTTON_SELECT)
24+
select.direction = Direction.INPUT
25+
select.pull = Pull.DOWN
26+
27+
down = DigitalInOut(board.BUTTON_DOWN)
28+
down.direction = Direction.INPUT
29+
down.pull = Pull.DOWN
30+
31+
back = touchio.TouchIn(board.CAP7)
32+
submit = touchio.TouchIn(board.CAP8)
33+
34+
# Check for secrets.py. Note: for this project, your secrets.py needs an adafruit io api key as
35+
# well as the wifi information
36+
try:
37+
from secrets import secrets
38+
except ImportError:
39+
print("WiFi secrets are kept in secrets.py, please add them there!")
40+
raise
41+
42+
# Make the rgb group for setting rgb hex values for NeoPixels
43+
rgb_group = displayio.Group(max_size=9)
44+
R_label = Label(
45+
terminalio.FONT,
46+
text=" +\nR:\n -",
47+
color=0xFFFFFF,
48+
anchor_point=((0, 0.5)),
49+
anchored_position=((5, 120)),
50+
scale=2,
51+
)
52+
G_label = Label(
53+
terminalio.FONT,
54+
text=" +\nG:\n -",
55+
color=0xFFFFFF,
56+
anchor_point=((0, 0.5)),
57+
anchored_position=((90, 120)),
58+
scale=2,
59+
)
60+
B_label = Label(
61+
terminalio.FONT,
62+
text=" +\nB:\n -",
63+
color=0xFFFFFF,
64+
anchor_point=((0, 0.5)),
65+
anchored_position=((175, 120)),
66+
scale=2,
67+
)
68+
rgb_group.append(R_label)
69+
rgb_group.append(G_label)
70+
rgb_group.append(B_label)
71+
R = Label(
72+
terminalio.FONT,
73+
text="00",
74+
color=0xFFFFFF,
75+
anchor_point=((0, 0.5)),
76+
anchored_position=((35, 120)),
77+
scale=2,
78+
)
79+
G = Label(
80+
terminalio.FONT,
81+
text="00",
82+
color=0xFFFFFF,
83+
anchor_point=((0, 0.5)),
84+
anchored_position=((120, 120)),
85+
scale=2,
86+
)
87+
B = Label(
88+
terminalio.FONT,
89+
text="00",
90+
color=0xFFFFFF,
91+
anchor_point=((0, 0.5)),
92+
anchored_position=((205, 120)),
93+
scale=2,
94+
)
95+
rgb_group.append(R)
96+
rgb_group.append(G)
97+
rgb_group.append(B)
98+
99+
# Set up callbacks
100+
101+
# pylint: disable=unused-argument
102+
def rgb(last):
103+
""" Function for when the rgb screen is active """
104+
display.show(None)
105+
rgb_group[3].text = "00"
106+
rgb_group[4].text = "00"
107+
rgb_group[5].text = "00"
108+
display.show(rgb_group)
109+
time.sleep(0.2)
110+
index = 0
111+
colors = [00, 00, 00]
112+
113+
while True:
114+
if select.value:
115+
index += 1
116+
if index == 3:
117+
index = 0
118+
time.sleep(0.3)
119+
continue
120+
121+
if up.value:
122+
colors[index] += 1
123+
if colors[index] == 256:
124+
colors[index] = 0
125+
rgb_group[index + 3].text = hex(colors[index])[2:]
126+
time.sleep(0.01)
127+
continue
128+
129+
if down.value:
130+
colors[index] -= 1
131+
if colors[index] == -1:
132+
colors[index] = 255
133+
rgb_group[index + 3].text = hex(colors[index])[2:]
134+
time.sleep(0.01)
135+
continue
136+
137+
if submit.value:
138+
color = ["{:02x}".format(colors[i]) for i in range(len(colors))]
139+
color = "#" + "".join(color)
140+
iot.publish("neopixel", color)
141+
break
142+
143+
if back.value:
144+
break
145+
time.sleep(0.1)
146+
147+
display.show(None)
148+
time.sleep(0.1)
149+
150+
def rgb_set_color(message):
151+
""" Sets the color of the rgb label based on the value of the feed """
152+
return int(message[1:], 16)
153+
154+
def door_color(message):
155+
""" Sets the color of the door label based on the value of the feed """
156+
door = bool(int(message))
157+
if door:
158+
return int(0x00FF00)
159+
return int(0xFF0000)
160+
161+
def on_door(client, feed_id, message):
162+
""" Sets the door text based on the value of the feed """
163+
door = bool(int(message))
164+
if door:
165+
return "Door: Closed"
166+
return "Door: Open"
167+
168+
def pub_lamp(lamp):
169+
if isinstance(lamp, str):
170+
lamp = eval(lamp) # pylint: disable=eval-used
171+
iot.publish("lamp", str(not lamp))
172+
# funhouse.set_text(f"Lamp: {not lamp}", 0)
173+
time.sleep(0.3)
174+
175+
display = board.DISPLAY
176+
177+
# Set your Adafruit IO Username and Key in secrets.py
178+
# (visit io.adafruit.com if you need to create an account,
179+
# or if you need your Adafruit IO key.)
180+
aio_username = secrets["aio_username"]
181+
aio_key = secrets["aio_key"]
182+
183+
print("Connecting to %s" % secrets["ssid"])
184+
wifi.radio.connect(secrets["ssid"], secrets["password"])
185+
print("Connected to %s!" % secrets["ssid"])
186+
187+
# Create a socket pool
188+
pool = socketpool.SocketPool(wifi.radio)
189+
190+
# Initialize a new MQTT Client object
191+
mqtt_client = MQTT.MQTT(
192+
broker="io.adafruit.com",
193+
username=secrets["aio_username"],
194+
password=secrets["aio_key"],
195+
socket_pool=pool,
196+
ssl_context=ssl.create_default_context(),
197+
)
198+
199+
# Initialize an Adafruit IO MQTT Client
200+
io = IO_MQTT(mqtt_client)
201+
202+
iot = Hub(display=display, io=io, nav=(up, select, down, back, submit))
203+
204+
iot.add_device(
205+
feed_key="lamp",
206+
default_text="Lamp: ",
207+
formatted_text="Lamp: {}",
208+
pub_method=pub_lamp,
209+
)
210+
iot.add_device(
211+
feed_key="temperature",
212+
default_text="Temperature: ",
213+
formatted_text="Temperature: {:.1f} C",
214+
)
215+
iot.add_device(
216+
feed_key="humidity", default_text="Humidity: ", formatted_text="Humidity: {:.2f}%"
217+
)
218+
iot.add_device(
219+
feed_key="neopixel",
220+
default_text="LED: ",
221+
formatted_text="LED: {}",
222+
color_callback=rgb_set_color,
223+
pub_method=rgb,
224+
)
225+
iot.add_device(
226+
feed_key="battery",
227+
default_text="Battery: ",
228+
formatted_text="Battery: {}%",
229+
)
230+
iot.add_device(
231+
feed_key="door",
232+
default_text="Door: ",
233+
formatted_text="Door: {}",
234+
color_callback=door_color,
235+
callback=on_door,
236+
)
237+
238+
iot.get()
239+
240+
while True:
241+
iot.loop()
242+
time.sleep(0.01)

0 commit comments

Comments
 (0)