Paho MQTT Python

Paho MQTT Python

Paho is an open source MQTT client project that provides MQTT client implementations in multiple languages, including C, C++, C#, Java, Python, JavaScript, etc., and fully supports MQTT v3.1 and v3.1.1. Paho Python Client is its Python language version and supports Python 2.7 and 3.x. More features can be found at http://www.eclipse.org/paho/clients/python/, and the source code and documentation are at https://github.com/eclipse/paho.mqtt.python.

This project provides a test MQTT broker: iot.eclipse.org, port 1883, no password.

1. Installation

Use the pip install paho-mqtt command to install it in the Python environment, or download the source code:

git clone https://github.com/eclipse/paho.mqtt.python.git
cd org.eclipse.paho.mqtt.python.git
python setup.py install

The following is a simple example to connect to a broker, subscribe to the system default topic, and obtain the broker’s version number:

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    client.subscribe("$SYS/broker/version")

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("iot.eclipse.org", 1883, 60)

client.loop_forever()

Save to the paho-mqtt.py file and execute:

$ python paho-mqtt.py
Connected with result code 0
$SYS/broker/version mosquitto version 1.4.10

2. Programming

The paho.mqtt package provides three classes, Client, Publish and Subscribe. Publish and Subscribe provide simple methods to send or receive messages once, without maintaining a connection. Client includes methods such as creating a new client, connecting, subscribing, sending, and callback functions. The usual programming steps are to create a new instance of Client, and then call the connection, publish and subscribe methods it provides to communicate with the broker:

Create a new Client instance
Connect to the broker using a connect*() function
Use a loop*() function to maintain the connection with the broker
Use the subscribe() function to subscribe to a topic and receive messages
Publish messages using publish() function
Disconnect using disconnect() function
The following mainly introduces the methods provided by Client. Import them before use:

import paho.mqtt.client as mqtt

2.1. Initialization

Create a new Client instance:

Client(client_id="", clean_session=True, userdata=None, protocol=MQTTv311, transport="tcp")

This is the constructor of the Client class, the meaning of the parameters:

client_id, set the client ID, should be a string, submitted to the broker when connecting. If it is empty, an id will be randomly generated. At this time, clean_session must be set to True.
clean_session, Boolean, if True, the broker will clear all information about this client when disconnecting. If False, the broker will retain this client’s subscription information and message queue when disconnecting.
userdata, user-defined data, which can be of any type, is passed to the callback function. It can be updated using the user_data_set() function.
protocol , set the MQTT protocol version, MQTTv31 or MQTTv311.
transport, transport protocol, the default is still tcp, and can be set to websockets.
Construction example:

import paho.mqtt.client as mqtt
mqttc = mqtt.Client()

Client can be reinitialized by calling reinitialise():

reinitialise(client_id="", clean_session=True, userdata=None)

2.2. Configuration

These functions are used to set some characteristics of the Client and are usually called before connecting to the broker.

max_inflight_messages_set(self, inflight)

This function can set the maximum number of dynamic messages that can exist when QoS>0 (messages that have been sent but have not yet been successfully confirmed). The default is 20. Increasing this value will take up more memory, but can improve throughput.

max_queued_messages_set(self, queue_size)

This function can set the maximum value of the message queue when QoS>0. The default is 0, which means no limit. When the queue is full, old messages are discarded.

message_retry_set(retry)

When Qos>0, if the confirmation message is not received after a certain period of time after sending the message, the message must be resent. This function is used to set the timeout, in seconds. The default is 5 seconds and usually does not need to be modified.

The function to configure SSL certificate verification must be called before the connect*() function. The meaning of several parameters:

ca_certs , specifies the path to the CA root certificate.
certfile,keyfile, specify the path to the client’s private key and certificate.
cert_reqs, sets the client’s requirements for the broker certificate. The default is ssl.CERT_REQUIRED, which means the broker must provide a certificate.
tls_version, set the SSL/TLS protocol version, the default is TLS v1.
ciphers, set the encryption password for this connection, the default is None.
Set username and password:

username_pw_set(username, password=None)

Set up a will:

will_set(topic, payload=None, qos=0, retain=False)

The broker will publish this will message when the client disconnects. Parameter meaning:

topic , the topic of the will message
payload, the content of the will message, string type, if set to None, a message with a length of 0 will be sent. If a value of type int or float is set, it will be sent as a string. If you want to send a real int or float value, you need to use struct.pack() to generate the message.
qos, the security level of will messages
retain, if set to True, the will message will be set as a retained message
If the parameters are set incorrectly, the function will throw a ValueError exception.

2.3. Connection

The most basic connection method is connect():

connect(host, port=1883, keepalive=60, bind_address="")

Connect to broker. This is a blocking function. The meaning of the parameters:

host , the hostname or IP of the broker
port, the open port of the broker, the default is 1883, if SSL/TLS is enabled, the port may be 8883
keepalive, heartbeat interval, unit is seconds. If there is no communication between the broker and the client during this period, the client will send a ping message to the broker.
bind_address, if the client’s local computer has multiple network interfaces, you can use this parameter to bind one of them
After the client calls this function to initiate a connection, if it receives the CONNACK message from the broker, the on_connect() callback function will be executed. In addition, there are two functions connect_async() and connect_srv() to connect to broker. connect_async() needs to cooperate with the loop_start() function to connect to the broker in a non-blocking manner. connect_srv() obtains the broker’s address from SRV DNS and then connects.

After calling the connect*() function, you can call reconnect() to reconnect with the existing parameters. Call the disconnect() function to disconnect from the broker. After disconnecting, the on_disconnect() callback function will be executed.

2.4. Network loop

There are four network loop functions, which run in the background and process messages sent and received. The most basic is loop() :

loop(timeout=1.0, max_packets=1)

This function will block through the select() function until there is a message to be sent and received. The blocking time is set with the timeout parameter and cannot exceed the heartbeat time keepalive, otherwise your client will disconnect from the broker regularly. The max_packets parameter is obsolete and does not need to be set.

Another loop function is loop_forever(), which will block until the client calls disconnect(), and it will automatically reconnect:

loop_forever(timeout=1.0, max_packets=1, retry_first_connection=False)

The timeout and max_packets parameters are obsolete and do not need to be set.

2.5. Publishing

publish(topic, payload=None, qos=0, retain=False)

Send a message to the specified topic. The meaning of the parameters:

topic , the topic to which this message belongs
payload, message content, string type, if set to None, a message with a length of 0 will be sent. If a value of type int or float is set, it will be sent as a string. If you want to send a real int or float value, you need to use struct.pack() to generate the message.
qos, the security level of the message
retain, if set to True, this message will be set as a retained message
If the parameters are set incorrectly, a ValueError exception will be thrown. After the message is sent successfully, the on_publish() callback function will be executed.

2.6. Subscription

subscribe(topic, qos=0)

Subscribe to the topic from the broker. The parameter topic sets the topic name and qos sets the security level. If you only subscribe to one topic, just set two parameters directly, for example:

subscribe(("my/topic", 1))

If you want to subscribe to multiple topics, you can put each topic in a tuple, and multiple topics form a list:

subscribe([("my/topic", 0), ("another/topic", 2)])

When the broker confirms that the subscription is valid, the client will execute the on_subscribe() callback function. If you want to unsubscribe from a topic, you can call unsubscribe(topic). The parameter is a string. If you want to cancel multiple topics, the parameter should be a list of strings. If the cancellation is successful, the on_unsubscribe() callback function will be executed.

2.7. Callback function

When the broker responds to the client’s connection request, the on_connect() callback function will be called. In this function, you can determine whether the connection is successful:

on_connect(client, userdata, flags, rc)

The parameter client is the current client instance, and userdata is the user data set by Client() or userdata_set(). flags is the response flags sent by the broker, dictionary type. rc represents the connection result, integer type, 0 represents successful connection, possible values for connection failure are:

1. Wrong protocol version
2, invalid client ID
3, the server is unavailable
4. Wrong username or password
5, unable to verify
Usage examples:

def on_connect(client, userdata, flags, rc):
    print("Connection returned result: " + connack_string(rc))

mqttc.on_connect = on_connect


Correspondingly, after disconnecting from the broker, the on_disconnect() callback function will be executed:

on_disconnect(client, userdata, rc)

rc represents the status of disconnection. If it is 0, it means the disconnection is caused by calling disconnect(). Other results indicate unexpected disconnection, such as network interruption. Usage examples:

def on_disconnect(client, userdata, rc):
    if rc != 0:
        print("Unexpected disconnection.")

mqttc.on_disconnect = on_disconnect


When the client receives a message from a subscribed topic, it will call the on_message() callback function. In this function, it will determine which topic the message is from and process the message content:

on_message(client, userdata, message)

The parameter message is an instance of the MQTTMessage class. The members of this class include topic, payload, qos, and retain. Usage examples:

def on_message(client, userdata, message):
    print("Received message '" + str(message.payload) + "' on topic '"
         + message.topic + "' with QoS " + str(message.qos))

mqttc.on_message = on_message


If you want to use wildcards to process messages from multiple topics at the same time, for example, use sensors/# to match the sensors/temperature and sensors/humidity topics, you can use message_callback_add() to set the callback function:

message_callback_add(sub, callback)

Parameter sub is a topic filter using wildcard characters, string type, and the callback parameter is used to specify the callback function, which is the same type as on_message().

If both on_message() and message_callback_add() callback functions are set, it will first look for a suitable topic filter defined by message_callback_add(). If there is no match, on_message() will be called.

2.8. Example

Assume that the broker requires a username, password, certificate, and key. Here is a simple client example:

$ cat path-mqtt.py
#!/usr/bin/python

import paho.mqtt.client as mqtt

cafile = "/etc/mosquitto/ca/ca.crt"
certfile = "/home/ubuntu/CA/client.crt"
keyfile = "/home/ubuntu/CA/client.key"
user = "guest"
passwd = "12345678"
server = "localhost"
port=8883

def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    client.subscribe("$SYS/broker/version")

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))

client = mqtt.Client()
client.tls_set(cafile,certfile,keyfile)
client.username_pw_set(user,passwd)
client.on_connect = on_connect
client.on_message = on_message

client.connect(server, port, 60)

client.loop_forever()

implement:

$ ./path-mqtt.py
Connected with result code 0
$SYS/broker/version mosquitto version 1.4.11