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.
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.
Figure 2 – Publishing the messages.
In MQTTlens, you should now see the messages sent to the topic, such as shown in figure 3.
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
Reblogged this on The Technology Tinker and commented:
MQTT is almost a must for everyone who’s interested in home automation. I must admit, I’m reblogging this as much to share with everyone, as to be able to find it easily myself later! I’ve connected using a library on an ESP8266, but not from Python. That’s something that I was planning to figure out anyways…it will make propagating a unified date/time to all of the devices on the network that don’t have access to NTP in an easy way…like ESP8266, arduino, etc, for one thing. And that’s just off the top of my head! If it works for MicroPython as well, then it’s even more useful.
Update: Works great on my Raspberry Pi that I keep up as a little print server in back. So now it’s my MQTT server as well, keeping up with full date, full time, and broken out hour, minute, month, day, and year so I can retrieve just what I need, when I need it. Thanks!
Hi! Awesome news, this opens up the possibility of more complex IoT systems, since it can be used by multiple devices. Thanks for sharing!
As soon as I have some time, I will try to test it on the LinkItSmart, which runs OpenWRT and also supports Python. It would be another great addition to the list of devices that can use MQTT.
Reblogged this on The Technology Tinker and commented:
MQTT is almost a must for everyone who’s interested in home automation. I must admit, I’m reblogging this as much to share with everyone, as to be able to find it easily myself later! I’ve connected using a library on an ESP8266, but not from Python. That’s something that I was planning to figure out anyways…it will make propagating a unified date/time to all of the devices on the network that don’t have access to NTP in an easy way…like ESP8266, arduino, etc, for one thing. And that’s just off the top of my head! If it works for MicroPython as well, then it’s even more useful.
Update: Works great on my Raspberry Pi that I keep up as a little print server in back. So now it’s my MQTT server as well, keeping up with full date, full time, and broken out hour, minute, month, day, and year so I can retrieve just what I need, when I need it. Thanks!
Hi! Awesome news, this opens up the possibility of more complex IoT systems, since it can be used by multiple devices. Thanks for sharing!
As soon as I have some time, I will try to test it on the LinkItSmart, which runs OpenWRT and also supports Python. It would be another great addition to the list of devices that can use MQTT.
Pingback: Python: Subscribing to MQTT topic | techtutorialsx
Pingback: Python: Subscribing to MQTT topic | techtutorialsx
Pingback: ESP32: Publishing messages to MQTT topic | techtutorialsx
Pingback: ESP32: Publishing messages to MQTT topic | techtutorialsx
Pingback: ESP32: Subscribing to MQTT topic | techtutorialsx
Pingback: ESP32: Subscribing to MQTT topic | techtutorialsx
Pingback: LinkIt Smart 7688 Duo: Subscribing to MQTT topic | techtutorialsx
Pingback: LinkIt Smart 7688 Duo: Subscribing to MQTT topic | techtutorialsx