# 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)
Пример #2
0
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)