I am trying to understand why a simple micropython sensor setup on a pico2_w as client has stopped being able to connect and publish to my mosquitto broker on homeassistant OS running on a raspberry pi4. I have tried to debug, and it seems like the broker is closing connection / disconnecting / not responding the way it should, but the debug log only shows:
2025-03-12 20:33:47: New connection from 192.168.86.8:59092 on port 1883.
2025-03-12 20:33:47: Client <unknown> disconnected due to protocol error.
I have used MQTT Explorer and the exact same connection details and it will connect (I even set the same client ID the pico script was using that mosquitto broker calls unknown)
2025-03-12 20:46:27: New connection from 192.168.86.9:54254 on port 1883.
2025-03-12 20:46:27: New client connected from 192.168.86.9:54254 as 2c:cf:67:ba:f2:87 (p2, c1, k60, u'pico2').
Here is my connect function that I call, (and I want to note that this all fails on the connection, not publishing of data as we never get that far):
def connect_mqtt():
print("Connecting to MQTT")
for x in range(2):
try:
print("Attempting connection")
client = MQTTClient("2c:cf:67:ba:f2:87",MQTT_BROKER ,user=MQTT_USER, password=MQTT_PASSWORD)
print("Setting connection data... ")
client.connect()
print("Connected to MQTT Broker")
return client
except OSError as e:
print(f"MQTT Connection failed: {e}, retrying...")
time.sleep(3)
raise RuntimeError("Failed to connect to MQTT Broker after multiple attempts.")
I pulled data from the umqtt package I was using into the script to also help with debugging (I placed the print(“#”) throughout to try and figure out where things are going awry:
class MQTTException(Exception):
pass
class MQTTClient:
print("a")
def __init__(self, client_id, server, port=1883, user=None, password=None, keepalive=60):
print("b")
self.client_id = client_id
self.server = server
self.port = port
self.user = user
self.password = password
self.keepalive = keepalive
self.sock = None
print("c")
def connect(self):
"""Connects to the MQTT broker."""
print("entered connect function")
self.sock = socket.socket()
print("1")
addr = socket.getaddrinfo(self.server, self.port)[0][-1]
print("2")
self.sock.connect(addr)
print("3")
# MQTT Connect Packet
msg = bytearray(b"\x10\0\0\0\0\0")
print("4")
msg[1] = 10 + len(self.client_id) + (2 + len(self.user) if self.user else 0) + (2 + len(self.password) if self.password else 0)
print("5")
msg.extend(b"\x00\x04MQTT\x04\x02") # MQTT protocol and version
print("6")
msg.extend(struct.pack("!H", self.keepalive))
print(7)
msg.extend(struct.pack("!H", len(self.client_id)) + self.client_id.encode())
print("8")
if self.user:
print("9")
msg.extend(struct.pack("!H", len(self.user)) + self.user.encode())
print("10")
if self.password:
print("11")
msg.extend(struct.pack("!H", len(self.password)) + self.password.encode())
print("12")
self.sock.send(msg)
print("13")
resp = self.sock.recv(4)
print("14")
if resp[0] != 0x20 or resp[1] != 0x02 or resp[3] != 0x00:
print("15")
raise MQTTException("MQTT connection failed")
print("16")
def publish(self, topic, msg):
"""Publishes a message to a topic."""
pkt = bytearray(b"\x30\0")
pkt.extend(struct.pack("!H", len(topic)) + topic.encode() + msg.encode())
pkt[1] = len(pkt) - 2 # Set remaining length
self.sock.send(pkt)
def disconnect(self):
"""Disconnect from the MQTT broker."""
if self.sock:
self.sock.send(b"\xE0\x00") # MQTT DISCONNECT Packet
self.sock.close()
self.sock = None
Finally when I run the script here is my output
a
Connecting to Wi-Fi...
Connected to Wi-Fi: ('192.168.86.8', '255.255.255.0', '192.168.86.1', '192.168.86.1')
Connecting to MQTT
Attempting connection
b
c
Setting connection data...
entered connect function
1
2
3
4
5
6
7
8
9
10
11
12
13
MQTT Connection failed: [Errno 104] ECONNRESET, retrying...
Traceback (most recent call last):
File "<stdin>", line 187, in <module>
File "<stdin>", line 133, in connect_mqtt
RuntimeError: Failed to connect to MQTT Broker after multiple attempts.
it seems resp = self.sock.recv(4)
is the line that is failing based on the highest print message before erroring out.
I am open to any and all ideas, happy to run a different library, I just want to get this working so I can start collecting data.