MiniMQTT Loop
You should always use a loop when writing CircuitPython code which uses the MiniMQTT module. The loop method checks incoming and processes outgoing MQTT messages along with keeping the network connection between your board and the MQTT broker alive.
loop
Calling loop
creates a non-blocking network loop. You can create new code below the call to loop
, and it'll be executed. This type of loop should be run frequently to avoid disconnecting from the MQTT server. The loop
method also does not handle network hardware (WiFi) or MQTT broker disconnection. You'll need to handle that yourself.
Here's an example of using a non-blocking loop.
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT import time from os import getenv import adafruit_connection_manager import board import busio import neopixel from adafruit_esp32spi import adafruit_esp32spi from digitalio import DigitalInOut import adafruit_minimqtt.adafruit_minimqtt as MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml # (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) ssid = getenv("CIRCUITPY_WIFI_SSID") password = getenv("CIRCUITPY_WIFI_PASSWORD") aio_username = getenv("ADAFRUIT_AIO_USERNAME") aio_key = getenv("ADAFRUIT_AIO_KEY") # 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) """Use below for Most Boards""" status_pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_pixel = 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_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) ### Adafruit IO Setup ### # Setup a feed named `testfeed` for publishing. default_topic = f"{aio_username}/feeds/testfeed" ### Code ### # Define callback methods which are called when events occur def connected(client, userdata, flags, rc): # This function will be called when the client is connected # successfully to the broker. print(f"Connected to MQTT broker! Listening for topic changes on {default_topic}") # Subscribe to all changes on the default_topic feed. client.subscribe(default_topic) def disconnected(client, userdata, rc): # This method is called when the client is disconnected print("Disconnected from MQTT Broker!") def message(client, topic, message): """Method callled when a client's subscribed feed has a new value. :param str topic: The topic of the feed with a new value. :param str message: The new value """ print(f"New message on topic {topic}: {message}") # Connect to WiFi print("Connecting to WiFi...") esp.connect_AP(ssid, password) print("Connected!") pool = adafruit_connection_manager.get_radio_socketpool(esp) ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Set up a MiniMQTT Client mqtt_client = MQTT.MQTT( broker="io.adafruit.com", username=aio_username, password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) # Setup the callback methods above mqtt_client.on_connect = connected mqtt_client.on_disconnect = disconnected mqtt_client.on_message = message # Connect the client to the MQTT broker. mqtt_client.connect() photocell_val = 0 while True: # Poll the message queue mqtt_client.loop() # Send a new message print(f"Sending photocell value: {photocell_val}") mqtt_client.publish(default_topic, photocell_val) photocell_val += 1 time.sleep(3)
Here's an example of using a loop with a network interface. In this example, we use the loop to reset the network interface (wifi.reset
) and reconnect the socket to the MQTT broker (mqtt_client.reconnect
)
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT import time from os import getenv import adafruit_connection_manager import board import busio import neopixel from adafruit_esp32spi import adafruit_esp32spi from digitalio import DigitalInOut import adafruit_minimqtt.adafruit_minimqtt as MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml # (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) ssid = getenv("CIRCUITPY_WIFI_SSID") password = getenv("CIRCUITPY_WIFI_PASSWORD") aio_username = getenv("ADAFRUIT_AIO_USERNAME") aio_key = getenv("ADAFRUIT_AIO_KEY") # 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) """Use below for Most Boards""" status_pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_pixel = 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_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) ### Adafruit IO Setup ### # Setup a feed named `testfeed` for publishing. default_topic = f"{aio_username}/feeds/testfeed" ### Code ### # Define callback methods which are called when events occur def connected(client, userdata, flags, rc): # This function will be called when the client is connected # successfully to the broker. print(f"Connected to MQTT broker! Listening for topic changes on {default_topic}") # Subscribe to all changes on the default_topic feed. client.subscribe(default_topic) def disconnected(client, userdata, rc): # This method is called when the client is disconnected print("Disconnected from MQTT Broker!") def message(client, topic, message): """Method callled when a client's subscribed feed has a new value. :param str topic: The topic of the feed with a new value. :param str message: The new value """ print(f"New message on topic {topic}: {message}") # Connect to WiFi print("Connecting to WiFi...") esp.connect_AP(ssid, password) print("Connected!") pool = adafruit_connection_manager.get_radio_socketpool(esp) ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Set up a MiniMQTT Client mqtt_client = MQTT.MQTT( broker="io.adafruit.com", username=aio_username, password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) # Setup the callback methods above mqtt_client.on_connect = connected mqtt_client.on_disconnect = disconnected mqtt_client.on_message = message # Connect the client to the MQTT broker. print("Connecting to MQTT broker...") mqtt_client.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: mqtt_client.loop() except (ValueError, RuntimeError) as e: print("Failed to get data, retrying\n", e) esp.reset() time.sleep(1) esp.connect_AP(ssid, password) mqtt_client.reconnect() continue time.sleep(1)
MiniMQTT Client Identifier
By default, MiniMQTT will generate a unique, randomly generated client identifier based off the CircuitPython device's microcontroller's UUID and a random number. The broker will see a client named something like cpy-3123
If you'd like to set a custom client_id
(what the broker sees the CircuitPython device as), you can provide a string. Do make sure the client_id
's you create are unique, or your broker will disconnect them.
client = MQTT.MQTT( broker="io.adafruit.com", username=aio_username, password=aio_key, client_id='brentspyportal' )
MiniMQTT Logging
MiniMQTT uses the CircuitPython logger module for printing different types of errors, depending on the priority the logger was set to.
To attach a logger to a MiniMQTT client, simply:
client = MQTT.MQTT( broker="io.adafruit.com", username=aio_username, password=aio_key, ) client.enable_logger(adafruit_logging);
Then, you will need to add another line setting the logger's level. While the logger is initialized to the INFO level by default, you may want to see more information about your current MQTT session.
To set the logger to a higher priority logging level, like DEBUG, add the following line after the MQTT client has been initialized:
client.set_logger_level(DEBUG)
MiniMQTT Last Will and Testament
MiniMQTT supports setting publishing a message to a specific topic when your MQTT client disconnects.
- For more information about MQTT's Last Will - check this guide.
To use the last will - specify the topic
you'd like to publish to and provide it with a message
to publish when the client disconnects.
client.will_set('device/status/','Goodbye!')
This method must be called before the connect method. The last will and testament also must be allowed by your MQTT Broker - Adafruit IO does not support this feature.
Page last edited April 01, 2025
Text editor powered by tinymce.