Python: Publishing messages to MQTT topic

The objective of this post is to explain how to connect to a MQTT broker and post some messages to a topic, using Python.


Introduction

The objective of this post is to explain how to connect to a MQTT broker and post some messages to a topic, using Python.

For this example, we will be using paho-mqtt for Python. Paho-mqtt is a MQTT Python client library which implements versions 3.1 and 3.1.1 of the MQTT protocol [1].

As usual, the easiest way to install this library is by using pip, a tool for installing Python packages. To do so, we just need the following command:

pip install paho-mqtt

As MQTT broker, we will use CloudMQTT, which offers a free plan, amongst other options. You can check here how to create an account and how to create a broker instance.

After completing the procedure, check the instance information page, which should be similar to the one shown in figure 1. The important credentials that we will be using are the server, the user, the password and the port.

ESP8266 CloudMQTT Credentials

Figure 1 – CloudMQTT instance information.


The code

First, we need to import the client class, to have access to all the functionality needed to connect to the broker and publish some messages to topics. This class provides a very simple interface, which means we don’t need to worry about the low level details of the MQTT protocol. We will alias it as mqttClient.

Additionally, we will also import Python’s time module, so we can have access to the sleep function, for introducing some delays in our code.

import paho.mqtt.client as mqttClient
import time

In order to control the state of the connection to the broker, we will declare a global variable called Connected, initialized with “false”. After the connection is established, we will change it to “true”. As we will see later, we will change the value to “true” in a callback function that is executed when the connection is established.

Connected = False #global variable for the state of the connection

Next, we will declare 4 variables to hold the information needed to connect to the server. This will be the information mentioned in the introduction section, shown in figure 1. You should use the information from your instance.

broker_address= "m11.cloudmqtt.com"
port = 12948
user = "yourUSer"
password = "yourPass"

Now, we will create a new client instance. We will pass as argument of the constructor a unique client identifier in format of a string. You can check here other optional arguments that the constructor takes.

client = mqttClient.Client("Python")

Next, we will call the username_pw_set method, which allows to specify a username and optionally a password. This method should be called before the connect method [2], which we will call in a moment.

client.username_pw_set(user, password=password)

We also need to specify a on_connect callback function, which is called when the broker responds to the connection request [3]. We will just assign the function for now and define the actual code latter.

client.on_connect= on_connect

Finally, we will call the connect method, for establishing the connection to the broker. Note that this is a blocking call [4]. It will receive as input the broker address and the port.

client.connect(broker_address, port=port)

Now, we will call a method called loop_start, which will run a thread in background to handle the network connection and sending/receiving data. On the background, it calls a method called loop.

client.loop_start()

Since establishing the connection may take a while, we will do a loop until the previously declared Connected variable is set to true. As we said, this will be done in our callback function, which we still need to specify.

We will insert a small delay between each iteration of the loop.

while Connected != True:    #Wait for connection
    time.sleep(0.1)

After that, we will run a continuous loop in a try except block, that will catch a keyboard interrupt. This way, we can end the loop by sending a ctrl+C command on Python shell.

In this loop, we will use the raw_input function to get an input string from the command line, which we will use to publish to a topic.

To send a message to a topic, we just need to call the publish method, passing as first argument the topic where we want to publish, and has second argument the message to be sent. We will be posting on the “python/test” topic.

In the except block, since the program will finish, we call the disconnect method, to disconnect from the broker. Note that this generates a on_disconnect callback [5], which we are not using in this example.

After that, we also need to call the loop_stop method, to stop the previously launched background thread.

try:
    while True:

        value = raw_input('Enter the message:')
        client.publish("python/test",value)

except KeyboardInterrupt:

    client.disconnect()
    client.loop_stop()

To finish the coding, we just need to specify the on_connect callback function. It receives 4 arguments, as can be seen here. In this example we are only going to use the argument specified in the previous link as rc, which contains the result of the connection. It has the value 0 when the connection is successful.

So, on execution, if rc is equal to 0, we will print a success message and set the value of the Connected variable to “true”. Otherwise, we will print a error message.

Don’t forget to declare the variable as global to modify it outside the scope of the function.

def on_connect(client, userdata, flags, rc):

    if rc == 0:

        print("Connected to broker")

        global Connected                #Use global variable
        Connected = True                #Signal connection 

    else:

        print("Connection failed")

Check the full code bellow:

import paho.mqtt.client as mqttClient
import time

def on_connect(client, userdata, flags, rc):

    if rc == 0:

        print("Connected to broker")

        global Connected                #Use global variable
        Connected = True                #Signal connection 

    else:

        print("Connection failed")

Connected = False   #global variable for the state of the connection

broker_address=	"m11.cloudmqtt.com"
port = 12948
user = "yourUser"
password = "yourPassword"

client = mqttClient.Client("Python")               #create new instance
client.username_pw_set(user, password=password)    #set username and password
client.on_connect= on_connect                      #attach function to callback
client.connect(broker_address, port=port)          #connect to broker

client.loop_start()        #start the loop

while Connected != True:    #Wait for connection
    time.sleep(0.1)

try:
    while True:

        value = raw_input('Enter the message:')
        client.publish("python/test",value)

except KeyboardInterrupt:

    client.disconnect()
    client.loop_stop()


Testing the code

The easiest way to test the code is by using an application that can subscribe to the topic where the Python program will be posting, such as MQTTlens, a Google Chrome application, which connects to a MQTT broker and is able to subscribe and publish to MQTT topics [6].  So, open it and subscribe to the “python/test”.

Then run the Python code, for example, on IDLE, the Python IDE. On the command line, insert the message you want, such as exemplified in figure 2.

Python command line raw input

Figure 2 – Publishing the messages.

In MQTTlens, you should now see the messages sent to the topic, such as shown in figure 3.

MQTTlens Python topic

Figure 3 – Messages received from the subscribed topic.


Related posts


References

[1] https://pypi.python.org/pypi/paho-mqtt/

[2] https://github.com/eclipse/paho.mqtt.python#username_pw_set

[3] https://github.com/eclipse/paho.mqtt.python#on_connect

[4] https://github.com/eclipse/paho.mqtt.python#connect-reconnect-disconnect

[5] https://github.com/eclipse/paho.mqtt.python#disconnect

[6] https://chrome.google.com/webstore/detail/mqttlens/hemojaaeigabkbcookmlgmdigohjobjm

 

Technical details

  • Python version: 2.7.8

11 thoughts on “Python: Publishing messages to MQTT topic”

  1. Pingback: LinkIt Smart 7688 Duo: Publishing messages to MQTT topic | techtutorialsx

  2. Pingback: LinkIt Smart 7688 Duo: Publishing messages to MQTT topic | techtutorialsx

  3. Pingback: ESP32: Sending JSON messages over MQTT | techtutorialsx

  4. Pingback: ESP32: Sending JSON messages over MQTT | techtutorialsx

  5. Hi! I am a newbie to mqtt & I have a question. I am currently working on a project in which I publish messages to multiple devices(esp8266) using the same python publisher code, the problem is one device receives messages while the other doesn’t. Although The other device is connected(active), & has an IP assigned to it, does nothing. So my question is, should I make some changes to the code when I use it to publish messages to multiple devices subscribed on the same topic?

    1. Hi!

      Are all the devices that should receive the message subscribing to the same topic?

      If multiple subscribers subscribed a topic and someone publishes a message there, then all the subscribers should receive it. It’s the broker responsibility to ensure it.

      Are you hosting your own MQTT broker or using some third party service?

      Best regards,
      Nuno Santos

  6. Hi! I am a newbie to mqtt & I have a question. I am currently working on a project in which I publish messages to multiple devices(esp8266) using the same python publisher code, the problem is one device receives messages while the other doesn’t. Although The other device is connected(active), & has an IP assigned to it, does nothing. So my question is, should I make some changes to the code when I use it to publish messages to multiple devices subscribed on the same topic?

    1. Hi!
      Are all the devices that should receive the message subscribing to the same topic?
      If multiple subscribers subscribed a topic and someone publishes a message there, then all the subscribers should receive it. It’s the broker responsibility to ensure it.
      Are you hosting your own MQTT broker or using some third party service?
      Best regards,
      Nuno Santos

Leave a Reply

Discover more from techtutorialsx

Subscribe now to keep reading and get access to the full archive.

Continue reading