From 0e15164600a307c012056b53b72a55504b564434 Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:24:15 -0500 Subject: [PATCH 1/4] Create minimqtt_multipub_simpletest.py Adds a simple demo for publishing multiple feeds. Designed to be used with the BME280 sensor but filled in with fake values so it should work as is. Most other demos are using the ESP32SPI library. This one is more designed for the newer ESP32-S2 & S3 with no coprocessor. --- examples/minimqtt_multipub_simpletest.py | 139 +++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 examples/minimqtt_multipub_simpletest.py diff --git a/examples/minimqtt_multipub_simpletest.py b/examples/minimqtt_multipub_simpletest.py new file mode 100644 index 00000000..bf49d2f1 --- /dev/null +++ b/examples/minimqtt_multipub_simpletest.py @@ -0,0 +1,139 @@ +# SPDX-FileCopyrightText: 2023 DJDevon3 +# SPDX-License-Identifier: MIT +# MQTT Multi-Feed Publish Example +# Coded for Circuit Python 8.2.x + +import traceback +import os +import time +import board +import ssl +import wifi +import socketpool +import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_minimqtt.adafruit_minimqtt import MMQTTException +# from adafruit_bme280 import basic as adafruit_bme280 + +# Initialize Web Sockets (This should always be near the top of a script!) +# There can be only one pool +pool = socketpool.SocketPool(wifi.radio) + +# Add settings.toml to your filesystem CIRCUITPY_WIFI_SSID and CIRCUITPY_WIFI_PASSWORD keys +# with your WiFi credentials. Add your Adafruit IO username and key as well. +# DO NOT share that file or commit it into Git or other source control. +ssid = os.getenv("CIRCUITPY_WIFI_SSID") +appw = os.getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = os.getenv("aio_username") +aio_key = os.getenv("aio_key") + +# MQTT Topic +# Use this format for a standard MQTT broker +feed_01 = aio_username + "/feeds/BME280-RealTemp" +feed_02 = aio_username + "/feeds/BME280-Pressure" +feed_03 = aio_username + "/feeds/BME280-Humidity" +feed_04 = aio_username + "/feeds/BME280-Altitude" + +# Time in seconds between updates (polling) +# 600 = 10 mins, 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour +sleep_time = 900 + +# Initialize BME280 Sensor +# i2c = board.STEMMA_I2C() # uses board.SCL and board.SDA +# bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c) + +# Converts seconds to minutes/hours/days +# Attribution: Written by DJDevon3 & refined by Elpekenin +def time_calc(input_time): + if input_time < 60: + return f"{input_time:.0f} seconds" + if input_time < 3600: + return f"{input_time / 60:.0f} minutes" + if input_time < 86400: + return f"{input_time / 60 / 60:.0f} hours" + return f"{input_time / 60 / 60 / 24:.1f} days" + +# Define callback methods when events occur +def connect(mqtt_client, userdata, flags, rc): + # Method when mqtt_client connected to the broker. + print("| | ✅ Connected to MQTT Broker!") + + +def disconnect(mqtt_client, userdata, rc): + # Method when the mqtt_client disconnects from broker. + print("| | ✂️ Disconnected from MQTT Broker") + + +def publish(mqtt_client, userdata, topic, pid): + # Method when the mqtt_client publishes data to a feed. + print(f"| | | Published {topic}") + + +# Initialize a new MQTT Client object +mqtt_client = MQTT.MQTT( + broker="io.adafruit.com", + port=8883, + username=aio_username, + password=aio_key, + socket_pool=pool, + ssl_context=ssl.create_default_context(), + is_ssl=True, +) + +# Connect callback handlers to mqtt_client +mqtt_client.on_connect = connect +mqtt_client.on_disconnect = disconnect +mqtt_client.on_publish = publish + +while True: + # These are fake values, replace with sensor variables. + BME280_temperature = 80 + BME280_pressure = round(1014.89, 1) + BME280_humidity = round(49.57, 1) + BME280_altitude = round(100.543, 2) + print("===============================") + + # Board Uptime + print("Board Uptime: ", time_calc(time.monotonic())) + print("| Connecting to WiFi...") + + while not wifi.radio.ipv4_address: + try: + wifi.radio.connect(ssid, appw) + except ConnectionError as e: + print("Connection Error:", e) + print("Retrying in 10 seconds") + time.sleep(10) + print("| ✅ WiFi!") + + while wifi.radio.ipv4_address: + try: + # Connect to MQTT Broker + mqtt_client.connect() + mqtt_client.publish(feed_01, BME280_temperature) + # slight delay required between publishes! + # otherwise only the 1st publish will succeed + time.sleep(0.001) + mqtt_client.publish(feed_02, BME280_pressure) + time.sleep(1) + mqtt_client.publish(feed_03, BME280_humidity) + time.sleep(1) + mqtt_client.publish(feed_04, BME280_altitude) + time.sleep(1) + + except (ValueError, RuntimeError, OSError) as e: + print("| | ❌ Error:, retrying\n", e) + continue + except (ConnectionError) as e: + print("| | ❌ Failed to connect, retrying\n", e) + continue + except (MMQTTException) as e: + print("| | ❌ MMQTTException", e) + traceback.print_exception(e, e, e.__traceback__) + break + + mqtt_client.disconnect() + print("| ✂️ Disconnected from Wifi") + print("Next Update: ", time_calc(sleep_time)) + + time.sleep(sleep_time) + break From 358ac9f248ed235d4177453d3d705c0dd7157cad Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:26:55 -0500 Subject: [PATCH 2/4] ran black --- examples/minimqtt_multipub_simpletest.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/minimqtt_multipub_simpletest.py b/examples/minimqtt_multipub_simpletest.py index bf49d2f1..775b24c1 100644 --- a/examples/minimqtt_multipub_simpletest.py +++ b/examples/minimqtt_multipub_simpletest.py @@ -12,6 +12,7 @@ import socketpool import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_minimqtt.adafruit_minimqtt import MMQTTException + # from adafruit_bme280 import basic as adafruit_bme280 # Initialize Web Sockets (This should always be near the top of a script!) @@ -41,6 +42,7 @@ # i2c = board.STEMMA_I2C() # uses board.SCL and board.SDA # bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c) + # Converts seconds to minutes/hours/days # Attribution: Written by DJDevon3 & refined by Elpekenin def time_calc(input_time): @@ -52,6 +54,7 @@ def time_calc(input_time): return f"{input_time / 60 / 60:.0f} hours" return f"{input_time / 60 / 60 / 24:.1f} days" + # Define callback methods when events occur def connect(mqtt_client, userdata, flags, rc): # Method when mqtt_client connected to the broker. @@ -123,14 +126,14 @@ def publish(mqtt_client, userdata, topic, pid): except (ValueError, RuntimeError, OSError) as e: print("| | ❌ Error:, retrying\n", e) continue - except (ConnectionError) as e: + except ConnectionError as e: print("| | ❌ Failed to connect, retrying\n", e) continue - except (MMQTTException) as e: + except MMQTTException as e: print("| | ❌ MMQTTException", e) traceback.print_exception(e, e, e.__traceback__) break - + mqtt_client.disconnect() print("| ✂️ Disconnected from Wifi") print("Next Update: ", time_calc(sleep_time)) From a3c1bfb8069b2de6a186079b2b2abd9783b3712a Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:41:17 -0500 Subject: [PATCH 3/4] trying to make pylint happy --- examples/minimqtt_multipub_simpletest.py | 26 ++++++------------------ 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/examples/minimqtt_multipub_simpletest.py b/examples/minimqtt_multipub_simpletest.py index 775b24c1..d25d5f85 100644 --- a/examples/minimqtt_multipub_simpletest.py +++ b/examples/minimqtt_multipub_simpletest.py @@ -6,20 +6,18 @@ import traceback import os import time -import board import ssl import wifi import socketpool import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_minimqtt.adafruit_minimqtt import MMQTTException -# from adafruit_bme280 import basic as adafruit_bme280 - # Initialize Web Sockets (This should always be near the top of a script!) # There can be only one pool pool = socketpool.SocketPool(wifi.radio) -# Add settings.toml to your filesystem CIRCUITPY_WIFI_SSID and CIRCUITPY_WIFI_PASSWORD keys +# Add settings.toml to your filesystem +# CIRCUITPY_WIFI_SSID and CIRCUITPY_WIFI_PASSWORD keys # with your WiFi credentials. Add your Adafruit IO username and key as well. # DO NOT share that file or commit it into Git or other source control. ssid = os.getenv("CIRCUITPY_WIFI_SSID") @@ -38,11 +36,6 @@ # 600 = 10 mins, 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour sleep_time = 900 -# Initialize BME280 Sensor -# i2c = board.STEMMA_I2C() # uses board.SCL and board.SDA -# bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c) - - # Converts seconds to minutes/hours/days # Attribution: Written by DJDevon3 & refined by Elpekenin def time_calc(input_time): @@ -56,19 +49,19 @@ def time_calc(input_time): # Define callback methods when events occur -def connect(mqtt_client, userdata, flags, rc): +def connect(client, userdata, flags, rc): # Method when mqtt_client connected to the broker. print("| | ✅ Connected to MQTT Broker!") -def disconnect(mqtt_client, userdata, rc): +def disconnect(client, userdata, rc): # Method when the mqtt_client disconnects from broker. print("| | ✂️ Disconnected from MQTT Broker") -def publish(mqtt_client, userdata, topic, pid): +def publish(client, userdata, topic, pid): # Method when the mqtt_client publishes data to a feed. - print(f"| | | Published {topic}") + print("| | | Published to {0} with PID {1}".format(topic, pid)) # Initialize a new MQTT Client object @@ -122,13 +115,6 @@ def publish(mqtt_client, userdata, topic, pid): time.sleep(1) mqtt_client.publish(feed_04, BME280_altitude) time.sleep(1) - - except (ValueError, RuntimeError, OSError) as e: - print("| | ❌ Error:, retrying\n", e) - continue - except ConnectionError as e: - print("| | ❌ Failed to connect, retrying\n", e) - continue except MMQTTException as e: print("| | ❌ MMQTTException", e) traceback.print_exception(e, e, e.__traceback__) From 04f84012fc6a1c215939e754a92aa4220aba0c41 Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:46:16 -0500 Subject: [PATCH 4/4] ran black again added #pylint ignore unused arguments... seems like that's cheating. --- examples/minimqtt_multipub_simpletest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/minimqtt_multipub_simpletest.py b/examples/minimqtt_multipub_simpletest.py index d25d5f85..83e3956b 100644 --- a/examples/minimqtt_multipub_simpletest.py +++ b/examples/minimqtt_multipub_simpletest.py @@ -36,6 +36,7 @@ # 600 = 10 mins, 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour sleep_time = 900 + # Converts seconds to minutes/hours/days # Attribution: Written by DJDevon3 & refined by Elpekenin def time_calc(input_time): @@ -48,7 +49,8 @@ def time_calc(input_time): return f"{input_time / 60 / 60 / 24:.1f} days" -# Define callback methods when events occur +# Define callback methods which are called when events occur +# pylint: disable=unused-argument, redefined-outer-name def connect(client, userdata, flags, rc): # Method when mqtt_client connected to the broker. print("| | ✅ Connected to MQTT Broker!")