Adafruit_CircuitPython_MiniMQTT icon indicating copy to clipboard operation
Adafruit_CircuitPython_MiniMQTT copied to clipboard

Getting trapped in publish?

Open githubguy007 opened this issue 4 years ago • 3 comments

When using a MatrixPortal with CircuitPython, “publish” will intermittently hang indefinitely without returning any error messages rendering the M4 unresponsive.

This is documented in Adafruit Forums.

githubguy007 avatar Apr 28 '21 21:04 githubguy007

please include minimal code that reliably demonstrates the issue

ladyada avatar Apr 28 '21 21:04 ladyada

Hello,

I also seem to have this issue. After an MQTT publish the code seems to hang with no error. This can be within a few hours upto a day or two. ` import time import board import busio #import adafruit_shtc3 import adafruit_sht4x from digitalio import DigitalInOut, Direction, Pull from adafruit_pm25.i2c import PM25_I2C

#NTP import ipaddress import ssl import wifi import socketpool import adafruit_requests import secrets import rtc

#MQTT import adafruit_minimqtt.adafruit_minimqtt as MQTT

#Binary to HEX from adafruit_binascii import hexlify, unhexlify

#Continuity import supervisor import microcontroller

try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise print("Starting AQ monitor...") #Get unique ID based on MAC address ID = hexlify(wifi.radio.mac_address) ID = str(ID,'utf-8')

If you have a GPIO, its not a bad idea to connect it to the RESET pin

reset_pin = DigitalInOut(board.IO6) reset_pin.direction = Direction.OUTPUT reset_pin.value = False

MQTT Topic

Use this topic if you'd like to connect to a standard MQTT broker

mqtt_topic = "LOG/"+ ID +"/DATA"

Get our username, key and desired timezone

aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] location = secrets.get("timezone", None) TIME_URL = "https://io.adafruit.com/api/v2/%s/integrations/time/strftime?x-aio-key=%s" % (aio_username, aio_key) TIME_URL += "&fmt=%25Y-%25m-%25d+%25H%3A%25M%3A%25S.%25L+%25j+%25u+%25z+%25Z"

print("MAC ID addr:", ID)

print("Connecting to %s"%secrets["ssid"]) wifi.radio.connect(secrets["ssid"], secrets["password"]) print("Connected to %s!"%secrets["ssid"]) print("My IP address is", wifi.radio.ipv4_address) print("Getting Time...")

radio = wifi.radio pool = socketpool.SocketPool(radio) requests = adafruit_requests.Session(pool, ssl.create_default_context()) response = requests.get("http://worldtimeapi.org/api/timezone/Etc/UTC") if response.status_code == 200: r = rtc.RTC() r.datetime = time.localtime(response.json()['unixtime']) print(f"System Time: {r.datetime}") else: print("Setting time failed") #supervisor.reload() microcontroller.reset()

Code

Define callback methods which are called when events occur

pylint: disable=unused-argument, redefined-outer-name

def connect(mqtt_client, userdata, flags, rc): # This function will be called when the mqtt_client is connected # successfully to the broker. print("Connected to MQTT Broker!") print("Flags: {0}\n RC: {1}".format(flags, rc))

def disconnect(mqtt_client, userdata, rc): # This method is called when the mqtt_client disconnects # from the broker. print("Disconnected from MQTT Broker!")

def subscribe(mqtt_client, userdata, topic, granted_qos): # This method is called when the mqtt_client subscribes to a new feed. print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos))

def unsubscribe(mqtt_client, userdata, topic, pid): # This method is called when the mqtt_client unsubscribes from a feed. print("Unsubscribed from {0} with PID {1}".format(topic, pid))

def publish(mqtt_client, userdata, topic, pid): # This method is called when the mqtt_client publishes data to a feed. print("Published to {0} with PID {1}".format(topic, pid))

def message(client, topic, message): # Method called when a client's subscribed feed has a new value. print("New message on topic {0}: {1}".format(topic, message))

Create a socket pool

pool = socketpool.SocketPool(wifi.radio)

Set up a MiniMQTT Client

mqtt_client = MQTT.MQTT( broker= 'IPADDRESS', port= PORT, #username=secrets["aio_username"], #password=secrets["aio_key"], socket_pool=pool, ssl_context=ssl.create_default_context(), )

Connect callback handlers to mqtt_client

mqtt_client.on_connect = connect mqtt_client.on_disconnect = disconnect mqtt_client.on_subscribe = subscribe mqtt_client.on_unsubscribe = unsubscribe mqtt_client.on_publish = publish mqtt_client.on_message = message

Create library object, use 'slow' 100KHz frequency!

HTi2c = board.I2C() #SHTC3 sensor #sht = adafruit_shtc3.SHTC3(HTi2c) #SHT4 sensor sht = adafruit_sht4x.SHT4x(HTi2c) #Breadboard Wired header pins #PMi2c = busio.I2C(board.IO1, board.IO38, frequency=100000) PMi2c = board.I2C()

Connect to a PM2.5 sensor over I2C

pm25 = PM25_I2C(PMi2c, reset_pin)

print("Found PM2.5 sensor, reading data...")

while True: time.sleep(59) unix = time.time()

try:
    aqdata = pm25.read()
    temperature, relative_humidity = sht.measurements
    print(aqdata)
except RuntimeError:
    print("Unable to read from sensor, retrying...")
    supervisor.reload()
    #microcontroller.reset()
try:
    # Poll the message queue
    #mqtt_client.loop()
    print("Attempting to connect to %s" % mqtt_client.broker)
    mqtt_client.connect()
    try:
        print("Subscribing to %s" % mqtt_topic)
        mqtt_client.subscribe(mqtt_topic)
    except:
        continue
    #print("Publishing to %s" % mqtt_topic)
    try:
        print(
            "%d, %d, %d, %d, %d, %d, 0"
            % (unix, temperature, relative_humidity, aqdata["pm10 env"], aqdata["pm25 env"], aqdata["pm100 env"])
        )
        mqtt_client.publish(mqtt_topic, "%d, %d, %d, %d, %d, %d, 0"
            % (unix, temperature, relative_humidity, aqdata["pm10 env"], aqdata["pm25 env"], aqdata["pm100 env"]) )
    except:
        continue
    #print("Unsubscribing from %s" % mqtt_topic)
    try:
        mqtt_client.unsubscribe(mqtt_topic)
    except:
        continue
    #print("Disconnecting from %s" % mqtt_client.broker)
    try:
        mqtt_client.disconnect()
    except:
        continue
except:
    print("Something went wrong")
    try:
        mqtt_client.reconnect()
    except:
        continue
    continue

`

dlcollins avatar May 10 '21 11:05 dlcollins

The code in https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/issues/81#issuecomment-836570883 is in dire need of reformatting - use the triple backtick to include larger chunks of code.

vladak avatar Aug 17 '22 11:08 vladak