150 lines
4.8 KiB
Python
150 lines
4.8 KiB
Python
import json
|
|
import board
|
|
import busio
|
|
from digitalio import DigitalInOut
|
|
import neopixel
|
|
from adafruit_esp32spi import adafruit_esp32spi
|
|
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
|
|
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
|
|
from adafruit_minimqtt import MQTT
|
|
from adafruit_aws_iot import MQTT_CLIENT
|
|
|
|
### WiFi ###
|
|
|
|
# Get wifi details and more from a secrets.py file
|
|
try:
|
|
from secrets import secrets
|
|
except ImportError:
|
|
print("WiFi secrets are kept in secrets.py, please add them there!")
|
|
raise
|
|
|
|
# Get device certificate
|
|
try:
|
|
with open("aws_cert.pem.crt", "rb") as f:
|
|
DEVICE_CERT = f.read()
|
|
except ImportError:
|
|
print("Certificate (aws_cert.pem.crt) not found on CIRCUITPY filesystem.")
|
|
raise
|
|
|
|
# Get device private key
|
|
try:
|
|
with open("private.pem.key", "rb") as f:
|
|
DEVICE_KEY = f.read()
|
|
except ImportError:
|
|
print("Certificate (private.pem.key) not found on CIRCUITPY filesystem.")
|
|
raise
|
|
|
|
# If you are using a board with pre-defined ESP32 Pins:
|
|
esp32_cs = DigitalInOut(board.ESP_CS)
|
|
esp32_ready = DigitalInOut(board.ESP_BUSY)
|
|
esp32_reset = DigitalInOut(board.ESP_RESET)
|
|
|
|
# If you have an externally connected ESP32:
|
|
# esp32_cs = DigitalInOut(board.D9)
|
|
# esp32_ready = DigitalInOut(board.D10)
|
|
# esp32_reset = DigitalInOut(board.D5)
|
|
|
|
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
|
|
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
|
|
|
|
# Verify nina-fw version >= 1.4.0
|
|
assert int(bytes(esp.firmware_version).decode("utf-8")[2]) >= 4, "Please update nina-fw to >=1.4.0."
|
|
|
|
# Use below for Most Boards
|
|
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards
|
|
# Uncomment below for ItsyBitsy M4
|
|
# status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
|
|
# Uncomment below for an externally defined RGB LED
|
|
# import adafruit_rgbled
|
|
# from adafruit_esp32spi import PWMOut
|
|
# RED_LED = PWMOut.PWMOut(esp, 26)
|
|
# GREEN_LED = PWMOut.PWMOut(esp, 27)
|
|
# BLUE_LED = PWMOut.PWMOut(esp, 25)
|
|
# status_light = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
|
|
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
|
|
|
|
### Code ###
|
|
|
|
# Define callback methods which are called when events occur
|
|
# pylint: disable=unused-argument, redefined-outer-name
|
|
def connect(client, userdata, flags, rc):
|
|
# This function will be called when the client is connected
|
|
# successfully to the broker.
|
|
print('Connected to MQTT Broker!')
|
|
print('Flags: {0}\n RC: {1}'.format(flags, rc))
|
|
|
|
# Subscribe client to all shadow updates
|
|
print("Subscribing to shadow updates...")
|
|
aws_iot.shadow_subscribe()
|
|
|
|
def disconnect(client, userdata, rc):
|
|
# This method is called when the client disconnects
|
|
# from the broker.
|
|
print('Disconnected from MQTT Broker!')
|
|
|
|
def subscribe(client, userdata, topic, granted_qos):
|
|
# This method is called when the client subscribes to a new topic.
|
|
print('Subscribed to {0} with QOS level {1}'.format(topic, granted_qos))
|
|
|
|
# Update device shadow with example JSON payload
|
|
payload = {"state":{"reported":{"moisture":50,"temp":30}}}
|
|
aws_iot.shadow_update(json.dumps(payload))
|
|
|
|
# We can also retrieve the shadow from AWS IoT,
|
|
# aws_iot.shadow_get()
|
|
|
|
# or delete the shadow
|
|
# aws_iot.shadow_delete()
|
|
|
|
def unsubscribe(client, userdata, topic, pid):
|
|
# This method is called when the client unsubscribes from a topic.
|
|
print('Unsubscribed from {0} with PID {1}'.format(topic, pid))
|
|
|
|
def publish(client, userdata, topic, pid):
|
|
# This method is called when the client publishes data to a topic.
|
|
print('Published to {0} with PID {1}'.format(topic, pid))
|
|
|
|
def message(client, topic, msg):
|
|
# This method is called when the client receives data from a topic.
|
|
print("Message from {}: {}".format(topic, msg))
|
|
|
|
# Set AWS Device Certificate
|
|
esp.set_certificate(DEVICE_CERT)
|
|
|
|
# Set AWS RSA Private Key
|
|
esp.set_private_key(DEVICE_KEY)
|
|
|
|
# Connect to WiFi
|
|
print("Connecting to WiFi...")
|
|
wifi.connect()
|
|
print("Connected!")
|
|
|
|
|
|
# Set up a new MiniMQTT Client
|
|
client = MQTT(socket,
|
|
broker = secrets['broker'],
|
|
client_id = secrets['client_id'],
|
|
network_manager = wifi,
|
|
log=True)
|
|
|
|
# Initialize AWS IoT MQTT API Client
|
|
aws_iot = MQTT_CLIENT(client)
|
|
|
|
# Connect callback handlers to AWS IoT MQTT Client
|
|
aws_iot.on_connect = connect
|
|
aws_iot.on_disconnect = disconnect
|
|
aws_iot.on_subscribe = subscribe
|
|
aws_iot.on_unsubscribe = unsubscribe
|
|
aws_iot.on_publish = publish
|
|
aws_iot.on_message = message
|
|
|
|
print('Attempting to connect to %s'%client.broker)
|
|
aws_iot.connect()
|
|
|
|
# Pump the message loop forever, all events
|
|
# are handled in their callback handlers
|
|
# while True:
|
|
# aws_iot.loop()
|
|
|
|
# Attempt to loop forever and handle network interface
|
|
aws_iot.loop_forever()
|