I'm devopling an application on a PicoW using Visual Studio (Thonny gives the same results).
It uses umqtt.simple:
from machine import Pin, I2C
from time import sleep
import network
from umqtt.simple import MQTTClient
import config
# MQTT Parameters
MQTT_SERVER = config.mqtt_server
MQTT_PORT = 0
MQTT_USER = config.mqtt_username
MQTT_PASSWORD = config.mqtt_password
MQTT_CLIENT_ID = b"rPi_pico_train_1"
MQTT_KEEPALIVE = 7200
MQTT_SSL = True
led = Pin("LED", Pin.OUT)
def flash_led(count):
_count = count
while _count > 0:
led.value(True)
sleep(0.25)
led.value(False)
sleep(0.05)
_count -= 1
def init_wifi(ssid, password):
led.value(0)
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
connection_timeout = 20
print("Waiting for WIFI Connection...")
while connection_timeout > 0:
if wlan.status() >= 3:
break
connection_timeout -= 1
print(f"Timeout in: {connection_timeout}")
sleep(1)
if wlan.status() != 3:
return False
else:
print("Connected!")
network_info = wlan.ifconfig()
print(f"IP: {network_info[0]}")
led.value(1)
return True
def sub_cb(topic, msg):
print("New message on topic {}".format(topic.decode('utf-8')))
msg = msg.decode('utf-8')
print(msg)
if init_wifi(config.wifi_ssid, config.wifi_password):
flash_led(2)
else:
print("NOT CONNECTED TO WIFI")
client = MQTTClient(MQTT_CLIENT_ID, MQTT_SERVER,0, MQTT_USER, MQTT_PASSWORD, 3600,{'server_hostname' : MQTT_SERVER})
client.connect()
client.set_callback(sub_cb)
print('Connected to %s MQTT Broker'%(client))
print("Connecting to client")
flash_led(5)
print("Client listening")
while True:
client.subscribe('trains')
sleep(1)
Presumbly, my client
iVar isn't init'd correcly, but having looked at Hive and Tom's Hardware, I've run to a stop.
EDIT
Thanks for @Brits comment about not inclusing client.connect()
. I've re-written and started afresh a couple of times and must have missed that!
Unfortunately I still can't connect. The error is now:
Waiting for WIFI Connection...
Connected!
IP: 192.168.1.183
Traceback (most recent call last):
File "<stdin>", line 69, in <module>
File "/lib/umqtt/simple.py", line 68, in connect
AttributeError: 'dict' object has no attribute 'wrap_socket'
The line quoted in the module - line 69 - is the line of my code that contains: client.connect()
.
How is my code not connecting properly to Hive?
client = MQTTClient(MQTT_CLIENT_ID, MQTT_SERVER,0, MQTT_USER, MQTT_PASSWORD, 3600,{'server_hostname' : MQTT_SERVER})
client.set_callback(sub_cb)
print('Connected to %s MQTT Broker'%(client))
You are not calling client.connect
i.e.
client = MQTTClient(MQTT_CLIENT_ID, MQTT_SERVER,0, MQTT_USER, MQTT_PASSWORD, 3600,{'server_hostname' : MQTT_SERVER})
client.set_callback(sub_cb)
client.connect()
print('Connected to %s MQTT Broker'%(client))
client.connect
sets self.sock
which subscribe
uses (self.sock.write(pkt)
- line 157 in simple.py
); hence the error.
Update
Ref your subsequent error File "/lib/umqtt/simple.py", line 68, in connect
, that line (and the line before) is:
if self.ssl:
self.sock = self.ssl.wrap_socket(self.sock, server_hostname=self.server)
So self.ssl
is set. This will be because you call
client = MQTTClient(MQTT_CLIENT_ID, MQTT_SERVER,0, MQTT_USER, MQTT_PASSWORD, 3600,{'server_hostname' : MQTT_SERVER})
where:
def __init__(
self,
client_id,
server,
port=0,
user=None,
password=None,
keepalive=0,
ssl=None,
):
so you are setting ssl
to {'server_hostname' : MQTT_SERVER}
. Ufortunately, based on this discussion and the source, it looks like this paramater changed in version 1.4 and you need something like the following (copied from the discussion):
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.verify_mode = ssl.CERT_NONE
client = MQTTClient(client_id=b"kudzai_raspberrypi_picow", server=b"8fbadaf843514ef286a2ae29e80b15a0.s1.eu.hivemq.cloud", port=0, user=b"mydemoclient", password=b"passowrd", keepalive=7200, ssl=context )
Note: Sorry I don't actually use this currently, so cannot provide a fully working example I can just tyy to point out where you probably need to look (and looking at the library source is a good starting point with issues like this, unfortunately to keep the size down and performance up the library does not validate paramaters).