adafruit / Adafruit_CircuitPython_MiniMQTT

MQTT Client Library for CircuitPython
Other
72 stars 50 forks source link

Loop crashes after successful connecting to HiveMQ (tls) #196

Open philipphock opened 6 months ago

philipphock commented 6 months ago

I used the sample code from "https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/blob/main/examples/native_networking/minimqtt_adafruitio_native_networking.py" and modified it to connect to HiveMQ.

It requires tls, so besides changing wifi and mqtt credentials, I also added the is_ssl = True flag.

I can connect but after the loop is called once, the connection fails with an empty Exception:

Traceback (most recent call last): File "", line 69, in File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1050, in loop File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1078, in _wait_for_msg MMQTTException:

Digging deeper into it, and changing line 1078 to just "raise", gives a bit more insights: Traceback (most recent call last): File "", line 69, in File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1050, in loop File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1073, in _wait_for_msg File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1160, in _sock_exact_recv OSError: -116

But not much more.

EDIT: I use RPi Pico WS, tested with CircuitPython 8 and 9, also the official release libraries and the most recent minimqtt code from here. Connecting to a local broker without credentials works fine.

The full code of the test script is:

import os
import time
import ssl
import socketpool
import wifi
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import adafruit_logging as logging

mqtt_username = "REMOVED"
mqtt_pw = "REMOVED"
brokerurl = "REMOVED"
wifi.radio.connect("REMOVED", "REMOVED")

print(f"Connected to wifi")
def connected(client, userdata, flags, rc):
    print(f"Connected")
    client.subscribe("#")
    print(f"subscribed")

def disconnected(client, userdata, rc):
    # This method is called when the client is disconnected
    print("Disconnected from Adafruit IO!")

def message(client, topic, message):
    # This method is called when a topic the client is subscribed to
    # has a new message.
    print(f"New message on topic {topic}: {message}")

# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)
ssl_context = ssl.create_default_context()

# If you need to use certificate/key pair authentication (e.g. X.509), you can load them in the
# ssl context by uncommenting the lines below and adding the following keys to the "secrets"
# dictionary in your secrets.py file:
# "device_cert_path" - Path to the Device Certificate
# "device_key_path" - Path to the RSA Private Key
# ssl_context.load_cert_chain(
#     certfile=secrets["device_cert_path"], keyfile=secrets["device_key_path"]
# )

# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
    broker=brokerurl,
    port=8883,
    username=mqtt_username,
    password=mqtt_pw,
    socket_pool=pool,
    is_ssl=True,
    ssl_context=ssl_context,
)
mqtt_client.enable_logger(logging, 0)

# 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 broker...")
mqtt_client.connect()

photocell_val = 0
while True:    
    mqtt_client.loop()
    time.sleep(0.1)

The log output is:

%Run -c $EDITOR_CONTENT Connected to wifi Connecting to broker... 2186.650: DEBUG - Attempting to connect to MQTT broker (attempt #0) 2186.653: DEBUG - Attempting to establish MQTT connection... 2186.658: INFO - Establishing a SECURE SSL connection to REMOVED 2188.582: DEBUG - Sending CONNECT to broker... 2188.586: DEBUG - Fixed Header: bytearray(b'\x10+') 2188.590: DEBUG - Variable Header: bytearray(b'\x00\x04MQTT\x04\xc2\x00<') 2188.600: DEBUG - Receiving CONNACK packet from broker 2189.115: DEBUG - Got message type: 0x20 pkt: 0x20 Connected 2189.122: DEBUG - Sending SUBSCRIBE to broker... 2189.126: DEBUG - Fixed Header: bytearray(b'\x82\x06') 2189.133: DEBUG - Variable Header: b'\x00\x01' 2189.139: DEBUG - SUBSCRIBING to topic # with QoS 0 2189.143: DEBUG - payload: b'\x00\x01#\x00' 2189.334: DEBUG - Got message type: 0x90 pkt: 0x90 subscribed 2189.340: DEBUG - Resetting reconnect backoff 2189.344: DEBUG - waiting for messages for 0 seconds Traceback (most recent call last): File "", line 69, in File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1050, in loop File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1073, in _wait_for_msg File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1160, in _sock_exact_recv OSError: -116

MyRaspberry commented 6 months ago

same problem also talked about it here but if i use a adafruit_minimqtt from 21.12.2022 OK, ?because it skips the CP's timing?

vladak commented 5 months ago

There is something about Pico W and the negative 116, see https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/issues/177#issuecomment-1780091578

StilleQuelle308 commented 3 months ago

Not much of a contribution, but I just wanted to mention that I am also facing exactly this problem on a similar environment:

justmobilize commented 3 months ago

Can you try with 9.0.0? This was caught in the 8->9 path that the Pico did errors differently.

StilleQuelle308 commented 3 months ago

Yes indeed. I have just tried to run it with CircuitPython 9.0.3 and it worked fine without the exception I faced with 8.2.10. Thanks for the hint!

justmobilize commented 3 months ago

@philipphock are you willing to test in CP9? We should be able to close this out

vladak commented 2 months ago

I believe this should be moved to CP issues.