import time 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 import adafruit_minimqtt as 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!") # Initialize MQTT interface with the esp interface MQTT.set_socket(socket, esp) # Set up a new MiniMQTT Client client = MQTT.MQTT(broker=secrets["broker"], client_id=secrets["client_id"]) # 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() # Start a blocking message loop... # NOTE: NO code below this loop will execute # NOTE: Network reconnection is handled within this loop while True: try: aws_iot.loop() except (ValueError, RuntimeError) as e: print("Failed to get data, retrying\n", e) wifi.reset() aws_iot.reconnect() continue time.sleep(1)