aws_iot_shadows.py
1 import time 2 import json 3 import board 4 import busio 5 from digitalio import DigitalInOut 6 import neopixel 7 from adafruit_esp32spi import adafruit_esp32spi 8 from adafruit_esp32spi import adafruit_esp32spi_wifimanager 9 import adafruit_esp32spi.adafruit_esp32spi_socket as socket 10 import adafruit_minimqtt as MQTT 11 from adafruit_aws_iot import MQTT_CLIENT 12 13 ### WiFi ### 14 15 # Get wifi details and more from a secrets.py file 16 try: 17 from secrets import secrets 18 except ImportError: 19 print("WiFi secrets are kept in secrets.py, please add them there!") 20 raise 21 22 # Get device certificate 23 try: 24 with open("aws_cert.pem.crt", "rb") as f: 25 DEVICE_CERT = f.read() 26 except ImportError: 27 print("Certificate (aws_cert.pem.crt) not found on CIRCUITPY filesystem.") 28 raise 29 30 # Get device private key 31 try: 32 with open("private.pem.key", "rb") as f: 33 DEVICE_KEY = f.read() 34 except ImportError: 35 print("Certificate (private.pem.key) not found on CIRCUITPY filesystem.") 36 raise 37 38 # If you are using a board with pre-defined ESP32 Pins: 39 esp32_cs = DigitalInOut(board.ESP_CS) 40 esp32_ready = DigitalInOut(board.ESP_BUSY) 41 esp32_reset = DigitalInOut(board.ESP_RESET) 42 43 # If you have an externally connected ESP32: 44 # esp32_cs = DigitalInOut(board.D9) 45 # esp32_ready = DigitalInOut(board.D10) 46 # esp32_reset = DigitalInOut(board.D5) 47 48 spi = busio.SPI(board.SCK, board.MOSI, board.MISO) 49 esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) 50 51 # Verify nina-fw version >= 1.4.0 52 assert ( 53 int(bytes(esp.firmware_version).decode("utf-8")[2]) >= 4 54 ), "Please update nina-fw to >=1.4.0." 55 56 # Use below for Most Boards 57 status_light = neopixel.NeoPixel( 58 board.NEOPIXEL, 1, brightness=0.2 59 ) # Uncomment for Most Boards 60 # Uncomment below for ItsyBitsy M4 61 # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) 62 # Uncomment below for an externally defined RGB LED 63 # import adafruit_rgbled 64 # from adafruit_esp32spi import PWMOut 65 # RED_LED = PWMOut.PWMOut(esp, 26) 66 # GREEN_LED = PWMOut.PWMOut(esp, 27) 67 # BLUE_LED = PWMOut.PWMOut(esp, 25) 68 # status_light = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) 69 wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) 70 71 ### Code ### 72 73 # Define callback methods which are called when events occur 74 # pylint: disable=unused-argument, redefined-outer-name 75 def connect(client, userdata, flags, rc): 76 # This function will be called when the client is connected 77 # successfully to the broker. 78 print("Connected to MQTT Broker!") 79 print("Flags: {0}\n RC: {1}".format(flags, rc)) 80 81 # Subscribe client to all shadow updates 82 print("Subscribing to shadow updates...") 83 aws_iot.shadow_subscribe() 84 85 86 def disconnect(client, userdata, rc): 87 # This method is called when the client disconnects 88 # from the broker. 89 print("Disconnected from MQTT Broker!") 90 91 92 def subscribe(client, userdata, topic, granted_qos): 93 # This method is called when the client subscribes to a new topic. 94 print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos)) 95 96 # Update device shadow with example JSON payload 97 payload = {"state": {"reported": {"moisture": 50, "temp": 30}}} 98 aws_iot.shadow_update(json.dumps(payload)) 99 100 # We can also retrieve the shadow from AWS IoT, 101 # aws_iot.shadow_get() 102 103 # or delete the shadow 104 # aws_iot.shadow_delete() 105 106 107 def unsubscribe(client, userdata, topic, pid): 108 # This method is called when the client unsubscribes from a topic. 109 print("Unsubscribed from {0} with PID {1}".format(topic, pid)) 110 111 112 def publish(client, userdata, topic, pid): 113 # This method is called when the client publishes data to a topic. 114 print("Published to {0} with PID {1}".format(topic, pid)) 115 116 117 def message(client, topic, msg): 118 # This method is called when the client receives data from a topic. 119 print("Message from {}: {}".format(topic, msg)) 120 121 122 # Set AWS Device Certificate 123 esp.set_certificate(DEVICE_CERT) 124 125 # Set AWS RSA Private Key 126 esp.set_private_key(DEVICE_KEY) 127 128 # Connect to WiFi 129 print("Connecting to WiFi...") 130 wifi.connect() 131 print("Connected!") 132 133 # Initialize MQTT interface with the esp interface 134 MQTT.set_socket(socket, esp) 135 136 # Set up a new MiniMQTT Client 137 client = MQTT.MQTT(broker=secrets["broker"], client_id=secrets["client_id"]) 138 139 # Initialize AWS IoT MQTT API Client 140 aws_iot = MQTT_CLIENT(client) 141 142 # Connect callback handlers to AWS IoT MQTT Client 143 aws_iot.on_connect = connect 144 aws_iot.on_disconnect = disconnect 145 aws_iot.on_subscribe = subscribe 146 aws_iot.on_unsubscribe = unsubscribe 147 aws_iot.on_publish = publish 148 aws_iot.on_message = message 149 150 print("Attempting to connect to %s" % client.broker) 151 aws_iot.connect() 152 153 # Pump the message loop forever, all events 154 # are handled in their callback handlers 155 # while True: 156 # aws_iot.loop() 157 158 # Start a blocking message loop... 159 # NOTE: NO code below this loop will execute 160 # NOTE: Network reconnection is handled within this loop 161 while True: 162 try: 163 aws_iot.loop() 164 except (ValueError, RuntimeError) as e: 165 print("Failed to get data, retrying\n", e) 166 wifi.reset() 167 aws_iot.reconnect() 168 continue 169 time.sleep(1)