Search code examples
pythonpahopython-class

Working with Paho MQTT client in a Python class


I'm trying to set up an MQTT connector using a Python class. The problem I'm facing is that self.connected is always printed as False, even if in the on_connect module I've changed its value. Moreover, the two print instructions in the on_connect module are not being executed. However, if I do:

print(self.client.connect(host=broker, port=port, keepalive=120))

Within the bootstrap_mqtt module, the result is 0, which means that the client is connected.

What am I doing wrong?

I'm using this example for a better understanding of how Python classes work, and in particular how to manage modules/variables within a class.

Thank you!

Here's my code:

import paho.mqtt.client as paho
import ssl

broker = "mybrokerurl.com"
port = 8883
ca_file = "certs/file.pem"
cert_file = "certs/file.crt"
key_file = "certs/file.key"
client_id = 'client1234'

class MQTTConnector():
    def __init__(self):
        self.connected = False
    
    def on_connect(self, client, userdata, flags, rc):
        self.connected = True
        if rc == 0:
            print("Connected to MQTT Broker!") # Not being printed in output
        else:
            print("Failed to connect, return code:", rc)
    
    def bootstrap_mqtt(self):
        self.client = paho.Client(client_id=client_id)
    
        self.client.tls_set(
            ca_file,
            certfile=cert_file,
            keyfile=key_file,
            cert_reqs=ssl.CERT_REQUIRED,
            tls_version=ssl.PROTOCOL_TLSv1_2,
            ciphers=None
            )
    
        self.client.on_connect = self.on_connect

        self.client.connect(host=broker, port=port, keepalive=120)
        
        print(self.connected) # Gives False
        print(self.client.connect(host=broker, port=port, keepalive=120)) # Gives 0

        return self

if __name__ == '__main__':
    MQTTConnector().bootstrap_mqtt()

Solution

  • There are two problems here :

    • The main MQTT loop function, such as client.loop_start() or client.loop_forever(), is never called. The MQTT client won't connect until the program enter the loop (https://pypi.org/project/paho-mqtt/#client).

    I suggest to run the loop outside of the class, or to implement a specific method in the MQTTConnector class.

    if __name__ == '__main__':
        conn = MQTTConnector()
        conn.bootstrap_mqtt()
        conn.client.loop_forever()
    
    • The function self.client.connect is called twice, because you are re-calling it to print its return value.