# Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", username=secrets["aio_username"], password=secrets["aio_key"], ) # Initialize an Adafruit IO MQTT Client io = IO_MQTT(mqtt_client) # Connect the callback methods defined above to Adafruit IO io.on_connect = connected io.on_disconnect = disconnected io.on_message = message # Connect to Adafruit IO io.connect() # Start a blocking message loop... # NOTE: NO code below this loop will execute # NOTE: Network reconnection is handled within this loop while True: try: io.loop() except (ValueError, RuntimeError) as e: print("Failed to get data, retrying\n", e) wifi.reset() io.reconnect() continue time.sleep(1)
class DataWarehouse(): SECRETS_REQUIRED = ("ssid", "password", "aio_username", "aio_key") def __init__( self, secrets_, *, esp01_pins=[], esp01_uart=None, esp01_baud=115200, pub_prefix="", debug=False ### pylint: disable=redefined-outer-name ): if esp01_uart: self.esp01_uart = esp01_uart else: self.esp01_uart = busio.UART(*esp01_pins, receiver_buffer_size=2048) self.debug = debug self.esp = adafruit_espatcontrol.ESP_ATcontrol(self.esp01_uart, esp01_baud, debug=debug) self.esp_version = "" self.wifi = None try: _ = [secrets_[key] for key in self.SECRETS_REQUIRED] except KeyError: raise RuntimeError("secrets.py must contain: " + " ".join(self.SECRETS_REQUIRED)) self.secrets = secrets_ self.io = None self.pub_prefix = pub_prefix self.pub_name = {} self.init_connect() def init_connect(self): self.esp.soft_reset() self.wifi = adafruit_espatcontrol_wifimanager.ESPAT_WiFiManager( self.esp, self.secrets) ### A few retries here seems to greatly improve reliability for _ in range(4): if self.debug: print("Connecting to WiFi...") try: self.wifi.connect() self.esp_version = self.esp.get_version() if self.debug: print("Connected!") break except (RuntimeError, TypeError, adafruit_espatcontrol.OKError) as ex: if self.debug: print("EXCEPTION: Failed to publish()", repr(ex)) time.sleep(RECONNECT_SLEEP) ### This uses global variables socket.set_interface(self.esp) ### MQTT Client ### pylint: disable=protected-access self.mqtt_client = MQTT.MQTT(broker="io.adafruit.com", username=self.secrets["aio_username"], password=self.secrets["aio_key"], socket_pool=socket, ssl_context=MQTT._FakeSSLContext( self.esp)) self.io = IO_MQTT(self.mqtt_client) ### Callbacks of interest on io are ### on_connect on_disconnect on_subscribe self.io.connect() def reset_and_reconnect(self): self.wifi.reset() self.io.reconnect() def update_pub_name(self, field_name): pub_name = self.pub_prefix + field_name return pub_name def poll(self): dw_poll_ok = False try_reconnect = False for _ in range(2): try: ### Process any incoming messages if try_reconnect: self.reset_and_reconnect() try_reconnect = False self.io.loop() dw_poll_ok = True except (ValueError, RuntimeError, AttributeError, MQTT.MMQTTException, adafruit_espatcontrol.OKError, AdafruitIO_MQTTError) as ex: if self.debug: print("EXCEPTION: Failed to get data in loop()", repr(ex)) try_reconnect = True return dw_poll_ok def publish(self, p_data, p_fields): ok = [False] * len(p_fields) try_reconnect = False if self.debug: print("publish()") for idx, field_name in enumerate(p_fields): try: pub_name = self.pub_name[field_name] except KeyError: pub_name = self.update_pub_name(field_name) for _ in range(2): try: if try_reconnect: self.reset_and_reconnect() try_reconnect = False self.io.publish(pub_name, p_data[field_name]) ok[idx] = True break except (ValueError, RuntimeError, AttributeError, MQTT.MMQTTException, adafruit_espatcontrol.OKError, AdafruitIO_MQTTError) as ex: if self.debug: print("EXCEPTION: Failed to publish()", repr(ex)) try_reconnect = True time.sleep(RECONNECT_SLEEP) return all(ok)