I am following allong in the micropython for pico book and I am running into an error. Code connects to router and delivers an IP address. however when running the connect_mqtt() function I get the following error message:
*********** I solved this by finding a ussl library (not easy at least for me) and parling it in the .lib folder. NEW ERROR MESSAGE NOW:
Connection successful!
IP address: 10.82.1.251
Connecting to MQTT
Client defined
Error connecting to MQTT: ‘module’ object has no attribute ‘create_default_context’
Error: ‘NoneType’ object has no attribute ‘set_callback’
Connection successful! — I added this as a debug check —
IP address: 10.82.1.251
Connecting to MQTT
Error connecting to MQTT: no module named ‘ussl’
Error: ‘NoneType’ object has no attribute ‘set_callback’
I added an import ssl line in the setup but it still fails….
Any thoughts? I did a forum search but no joy.
Here is the function that fails:
Start your code here
def connect_mqtt():
print("Connecting to MQTT")
try:
client = MQTTClient(client_id=MQTT_CLIENT_ID,
server=MQTT_SERVER,
port=MQTT_PORT,
user=MQTT_USER,
password=MQTT_PASSWORD,
keepalive=MQTT_KEEPALIVE,
ssl=MQTT_SSL,
ssl_params=MQTT_SSL_PARAMS)
print("Client defined")
client.connect() #--- This is where it fails
return client
except Exception as e:
print('Error connecting to MQTT:', e)
client.connect() calls this
Start your code here:
def connect(self, clean_session=True):
self.sock = socket.socket()
addr = socket.getaddrinfo(self.server, self.port)[0][-1]
self.sock.connect(addr)
if self.ssl:
import ussl
self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)
premsg = bytearray(b”\x10\0\0\0\0\0″)
msg = bytearray(b”\x04MQTT\x04\x02\0\0″)
sz = 10 + 2 + len(self.client_id)
msg[6] = clean_session << 1
if self.user is not None:
sz += 2 + len(self.user) + 2 + len(self.pswd)
msg[6] |= 0xC0
if self.keepalive:
assert self.keepalive < 65536
msg[7] |= self.keepalive >> 8
msg[8] |= self.keepalive & 0x00FF
if self.lw_topic:
sz += 2 + len(self.lw_topic) + 2 + len(self.lw_msg)
msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3
msg[6] |= self.lw_retain << 5
i = 1
while sz > 0x7F:
premsg[i] = (sz & 0x7F) | 0x80
sz >>= 7
i += 1
premsg[i] = sz
tomfitzphilly
Hi.
Which MQTT broker were you using?
And what was the original code that you were testing and what was the first error that you encountered?
Regards
Sara
Sara – HiveMQ. I originally had a problem because I needed to import the ussl library. After that I get the context message when trying to initiate a connection to HiveMQ. I added some print commands to track down the fault. Here is my error traceback:
Temperature: 25.00463 °C, pressure: 1019.263 hPa.
Connection successful!
IP address: 10.1.10.110
beginning connection to Hive
<MQTTClient object at 20019e60>
Error connecting to MQTT: ‘module’ object has no attribute ‘create_default_context’
Error: ‘module’ object has no attribute ‘create_default_context’
Start your code here: def connect_mqtt():
print("beginning connection to Hive")
try:
client = MQTTClient(client_id=MQTT_CLIENT_ID,server=MQTT_SERVER,port=MQTT_PORT,user=MQTT_USER,
password=MQTT_PASSWORD,
keepalive=MQTT_KEEPALIVE,
ssl=MQTT_SSL,
ssl_params=MQTT_SSL_PARAMS)
print(client)
client.connect()
Here’s the original code. I didn’t have a bme280 so i swapped in a bmp280. but that is working fine. The code is breaking at the connect() function in the simple.py module with this command:
if self.ssl:
import ussl
I seem to be getting a good addr (52.31.xx.xx, 8883)
Start your code here
# Rui Santos & Sara Santos – Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-w-mqtt-micropython/
from machine import Pin, I2C
from time import sleep
import network
from umqtt.simple import MQTTClient
import config
from bmp280 import BMP280I2C
# Constants for MQTT Topics
MQTT_TOPIC_TEMPERATURE = ‘pico/temperature’
MQTT_TOPIC_PRESSURE = ‘pico/pressure’
# MQTT Parameters
MQTT_SERVER = config.mqtt_server
MQTT_PORT = 0
MQTT_USER = config.mqtt_username
MQTT_PASSWORD = config.mqtt_password
MQTT_CLIENT_ID = b”raspberrypi_picow”
MQTT_KEEPALIVE = 7200
MQTT_SSL = True # set to False if using local Mosquitto MQTT broker
MQTT_SSL_PARAMS = {‘server_hostname’: MQTT_SERVER}
# Initialize I2C communication
i2c0_sda = Pin(8)
i2c0_scl = Pin(9)
i2c0 = I2C(0, sda=i2c0_sda, scl=i2c0_scl, freq=400000)
bme = BMP280I2C(0x77, i2c0) # address may be different
sleep(1)
readout = bme.measurements
print(f”Temperature: {readout[‘t’]} °C, pressure: {readout[‘p’]} hPa.”)
sleep(1)
# Initialize BME280 sensor
def get_sensor_readings():
temp = bme.temperature[:-1]
pres = bme.pressure[:-3]
return temp, hum, pres
def initialize_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Connect to the network
wlan.connect(ssid, password)
# Wait for Wi-Fi connection
connection_timeout = 10
while connection_timeout > 0:
if wlan.status() >= 3:
break
connection_timeout -= 1
print(‘Waiting for Wi-Fi connection…’)
sleep(1)
# Check if connection is successful
if wlan.status() != 3:
return False
else:
print(‘Connection successful!’)
network_info = wlan.ifconfig()
print(‘IP address:’, network_info[0])
return True
def connect_mqtt():
print(“beginning connection to Hive”)
try:
client = MQTTClient(client_id=MQTT_CLIENT_ID,
server=MQTT_SERVER,
port=MQTT_PORT,
user=MQTT_USER,
password=MQTT_PASSWORD,
keepalive=MQTT_KEEPALIVE,
ssl=MQTT_SSL,
ssl_params=MQTT_SSL_PARAMS)
print(client)
client.connect()
print(“connecting to client”)
return client
except Exception as e:
print(‘Error connecting to MQTT:’, e)
raise # Re-raise the exception to see the full traceback
def publish_mqtt(topic, value):
client.publish(topic, value)
print(topic)
print(value)
print(“Publish Done”)
try:
if not initialize_wifi(config.wifi_ssid, config.wifi_password):
print(‘Error connecting to the network… exiting program’)
else:
# Connect to MQTT broker, start MQTT client
client = connect_mqtt()
while True:
# Read sensor data
temperature, humidity, pressure = get_sensor_readings()
# Publish as MQTT payload
publish_mqtt(MQTT_TOPIC_TEMPERATURE, str(temperature))
publish_mqtt(MQTT_TOPIC_PRESSURE, str(pressure))
publish_mqtt(MQTT_TOPIC_HUMIDITY, str(humidity))
# Delay 10 seconds
sleep(10)
except Exception as e:
print(‘Error:’, e)
Hi.
Can you tell me what files do you have on your Raspberry Pi Pico?
Can you show me the folder structure?
You mentioned this earlier “I solved this by finding a ussl library (not easy at least for me) and parling it in the .lib folder. ”
How did you install the recommended MQTT libraries?
Did you install them via the package manager?
Regards,
Sara
lib
bmp280
bmp280.py
bmp_configuration.py
bmp280_i2c.py
bmp280_spi.py
__init__.py
ussl.py
umqtt
robust.py
simple.py
code.py
config.py
Here is my entire code. when trying to import with the Thony package manager – I can’t
(install micropython-cpython-ussl
Error ‘type’ object is not subscriptable)
Start your code here
# Rui Santos & Sara Santos – Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-w-mqtt-micropython/
from machine import Pin, I2C
from time import sleep
import network
from umqtt.simple import MQTTClient
import config
from bmp280 import BMP280I2C
# Constants for MQTT Topics
MQTT_TOPIC_TEMPERATURE = ‘pico/temperature’
MQTT_TOPIC_PRESSURE = ‘pico/pressure’
# MQTT Parameters
MQTT_SERVER = config.mqtt_server
MQTT_PORT = 0
MQTT_USER = config.mqtt_username
MQTT_PASSWORD = config.mqtt_password
MQTT_CLIENT_ID = b”raspberrypi_picow”
MQTT_KEEPALIVE = 7200
MQTT_SSL = True # set to False if using local Mosquitto MQTT broker
MQTT_SSL_PARAMS = {‘server_hostname’: MQTT_SERVER}
# Initialize I2C communication
i2c0_sda = Pin(8)
i2c0_scl = Pin(9)
i2c0 = I2C(0, sda=i2c0_sda, scl=i2c0_scl, freq=400000)
bme = BMP280I2C(0x77, i2c0) # address may be different
sleep(1)
readout = bme.measurements
print(f”Temperature: {readout[‘t’]} °C, pressure: {readout[‘p’]} hPa.”)
sleep(1)
# Initialize BME280 sensor
def get_sensor_readings():
temp = bme.temperature[:-1]
pres = bme.pressure[:-3]
return temp, pres
def initialize_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Connect to the network
wlan.connect(ssid, password)
# Wait for Wi-Fi connection
connection_timeout = 10
while connection_timeout > 0:
if wlan.status() >= 3:
break
connection_timeout -= 1
print(‘Waiting for Wi-Fi connection…’)
sleep(1)
# Check if connection is successful
if wlan.status() != 3:
return False
else:
print(‘Connection successful!’)
network_info = wlan.ifconfig()
print(‘IP address:’, network_info[0])
return True
def connect_mqtt():
print(“beginning connection to Hive”)
try:
client = MQTTClient(client_id=MQTT_CLIENT_ID,
server=MQTT_SERVER,
port=MQTT_PORT,
user=MQTT_USER,
password=MQTT_PASSWORD,
keepalive=MQTT_KEEPALIVE,
ssl=MQTT_SSL,
ssl_params=MQTT_SSL_PARAMS)
print(client)
client.connect()
print(“connecting to client”)
return client
except Exception as e:
print(‘Error connecting to MQTT:’, e)
raise # Re-raise the exception to see the full traceback
def publish_mqtt(topic, value):
client.publish(topic, value)
print(topic)
print(value)
print(“Publish Done”)
try:
if not initialize_wifi(config.wifi_ssid, config.wifi_password):
print(‘Error connecting to the network… exiting program’)
else:
# Connect to MQTT broker, start MQTT client
client = connect_mqtt()
while True:
# Read sensor data
temperature, pressure = get_sensor_readings()
# Publish as MQTT payload
publish_mqtt(MQTT_TOPIC_TEMPERATURE, str(temperature))
publish_mqtt(MQTT_TOPIC_PRESSURE, str(pressure))
# Delay 10 seconds
sleep(10)
except Exception as e:
print(‘Error:’, e)
*******************************
Here is my traceback
Temperature: 24.44769 °C, pressure: 1023.624 hPa.
Connection successful!
IP address: 10.1.10.110
beginning connection to Hive
<MQTTClient object at 20019e40>
Trying to connect…
socket and address OK
(‘54.73.92.158’, 8883)
Error connecting to MQTT: ‘module’ object has no attribute ‘create_default_context’
Error: ‘module’ object has no attribute ‘create_default_context’
************************
Here’s the traceback without the ussl.py module
Temperature: 24.33433 °C, pressure: 1023.645 hPa.
Connection successful!
IP address: 10.1.10.110
beginning connection to Hive
<MQTTClient object at 20019e40>
Trying to connect…
socket and address OK
(‘46.137.47.218’, 8883)
Error connecting to MQTT: no module named ‘ussl’
Error: no module named ‘ussl’
**********************
here is where if fails in the simple.py module/connect function (I added the print commands for tracking):
if self.ssl:
import ussl
print(“ussl imported!”)
self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)
print(“skipped SSL”)
Hi.
You should not install it via the Package Manager. That’s why I was asking.
I just tested the instructions again and everything is working fine.
I don’t need to install any ussl library.
I’m wondering if maybe you have copied the wrong HiveMQ URL? When you go to the cluster details, you must copy the first Cluster URL (not the TLS or Webscoket URL).
You must also maintain the b’.
For example:
mqtt_server = b’4aa8b557ee9340adbef2cecf04125bc0.s2.eu.hivemq.cloud’
Double-check that you’re using the right MQTT username and password.
Can you share your code using Girhub? It’s very difficult to troubleshoot the code with the indentation all messed up.
Regards
Sara
Sara – thanks for taking so much time with this…
https://github.com/tomfitzphilly/mqtt
Hi.
I just tested your code using your configuration file and I was able to publish to MQTT.
You just have to publish your values as strings like this:
publish_mqtt(MQTT_TOPIC_TEMPERATURE, "78")
publish_mqtt(MQTT_TOPIC_PRESSURE, "15")
publish_mqtt(MQTT_TOPIC_HUMIDITY, "50")
So, the issue is not in the code or config file.
I can’t figure out what might be causing the issue.
Did you try the file that you sent me? Or did you try the file with the BMP280? Maybe there is something wrong with those BMP280 libraries… Sometimes there are issues with libraries installed via Thonny package manager.
Regards,
Sara
I HAVE NO IDEA WHAT I WAS DOING WRONG!!!!!!!!!!!!!!!!!!
however, all seems fine for publishing. Now on to subscribe!
This was frustrating and I really appreciate your help.
Best
Tom
Hi.
Great.
I’m glad everything is working now.
I’ll mark this issue as resolved. If you need further help, you just need to open a new question in our forum.
Regards,
Sara
Sara and Tom,
I’ve had the same issue with hivemq:
Error connecting to MQTT: no module named ‘ussl’
Error: no module named ‘ussl’
I eventually found out, that the MicroPython version causes this behaviour. The code runs only on 1.22.0 (the version you use in the book) and 1.22.1. Recent versions 1.23 and 1.24 preview will not work or need the ussl module.
Hope that helps, maybe someone knows which ussl package is needed to make it work with recent version of MicroPython.
All the best!
Thomas
Hi.
Thanks for letting me know.
Indeed, you are right.
I was not running the latest version of micropython.
You just need to replace ussl with ssl on the simple.py example: https://github.com/orgs/micropython/discussions/15229
I’ll update the file to be compatible with the latest version.
Regards,
Sara