Friday, January 26, 2018

Getting Started with MQTT Using Python

In the previous post on Getting Started with MQTT, it was shown, how one can configure Mosquitto, which is an MQTT broker, on Windows PC and then Subscribe and Publish topics.
In this post, we will use Python programming language for Publish and Subscribing the topics, as Python has its own advantages and by combining these two we can build great systems, which we will show in our upcoming post.
First of all, we need to install Paho Python Library and can be downloaded by clicking hereThis library provides a client class that enables applications to connect to an MQTT broker to publish messages and to subscribe to topics and receive published messages. It also provides some helper functions to make publishing one-off messages to an MQTT server very straightforward.
This library supports Python 2.7 and Python 3.x, this library also has support for Python 2.6, but still, it is advised to use Python 2.7 or Python 3.x .
Watch the following video or read the post given below.

Installation
To install paho-mqtt library, use the following commands from the command prompt. Python 3.x users can use pip3 command and Python 2.x users can use pip2 command.
pip3 install paho-mqtt
pip2 install paho-mqtt

After this library is installed first we will write a script to just subscribe to the topics and later we will modify this script to subscribe to topics and publish messages from the same script.

Subscribe Topics
The first is to import the MQTT client class, which can be done by using the following command.

import paho.mqtt.client as mqtt

If running this command alone gives you an error, then it means that your paho-MQTT library is not installed correctly.
If the above works fine then we need to create the instance for the client and then we have specified the callback functions, which will be called when the connection with the server (MQTT server, which is CloudMQTT in our case) is established and on receiving the subscribed message/topic. This can be done using the following lines.

import paho.mqtt.client as mqtt

# Callback Function on Connection with MQTT Server
def on_connect( client, userdata, flags, rc):
    print ("Connected with Code :" +str(rc))
    # Subscribe Topic from here
    client.subscribe("Test/#")

# Callback Function on Receiving the Subscribed Topic/Message
def on_message( client, userdata, msg):
    # print the message received from the subscribed topic
    print ( str(msg.payload) )

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

We have written the callback functions and it's time to connect with the CloudMQTT server, and its detail is given in the following image.
CloudMQTT
To connect with the server we need to use the connect method, but as this MQTT server is password protected, that's why we need to enter the username and password also, this all can be done using the following commands.

client.username_pw_set("setsmjwc", "apDnKqHRgAjA")
client.connect("m14.cloudmqtt.com", 18410, 60)

It is advised to use the username_pw_set() method before the connect() one, otherwise we will not be able to connect with the MQTT server.
At last, we have to use the method loop_forever(). This is a blocking form of the network loop and will not return until the client calls disconnect(). It automatically handles reconnecting also.
So the complete program for Subscription will look like this.

import paho.mqtt.client as mqtt

# Callback Function on Connection with MQTT Server
def on_connect( client, userdata, flags, rc):
    print ("Connected with Code :" +str(rc))
    # Subscribe Topic from here
    client.subscribe("Test/#")

# Callback Function on Receiving the Subscribed Topic/Message
def on_message( client, userdata, msg):
    # print the message received from the subscribed topic
    print ( str(msg.payload) )

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

client.username_pw_set("setsmjwc", "apDnKqHRgAjA")
client.connect("m14.cloudmqtt.com", 18410, 60)

client.loop_forever()
Subscription Example
Publish Messages and Subscribe Topics
The method to publish a message from Python to the MQTT server is publish(). This causes a message to be sent to the broker and subsequently from the broker to any clients subscribing to matching topics. It takes the following arguments:
  • topic: the topic that the message should be published on.
  • payload: the actual message to send. If not given, or set to None a zero-length message will be used. Passing an int or float will result in the payload being converted to a string representing that number. If you wish to send a true int/float, use struct.pack() to create the payload you require.
  • QoS: the quality of service level to use
  • retain: if set to True, the message will be set as the “last known good”/retained message for the topic.
To publish and subscribe in the same script we need to use another method also, which is loop_start() / loop_stop()
These functions implement a threaded interface to the network loop. Calling loop_start() once, before or after connect*(), runs a thread in the background to call loop() automatically. 
This frees up the main thread for other work that may be blocking. This call also handles reconnecting to the broker. Call loop_stop() to stop the background thread.
The complete code to Publish and Subscribe Topics in a non-blocking manner is given below.

import time
import paho.mqtt.client as mqtt

# Callback Function on Connection with MQTT Server
def on_connect( client, userdata, flags, rc):
    print ("Connected with Code :" +str(rc))
    # Subscribe Topic from here
    client.subscribe("Test/#")

# Callback Function on Receiving the Subscribed Topic/Message
def on_message( client, userdata, msg):
    # print the message received from the subscribed topic
    print ( str(msg.payload) )

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

client.connect("m14.cloudmqtt.com", 18410, 60)
client.username_pw_set("setsmjwc", "apDnKqHRgAjA")


# client.loop_forever()
client.loop_start()
time.sleep(1)
while True:
    client.publish("Tutorial","Getting Started with MQTT")
    print ("Message Sent")
    time.sleep(15)

client.loop_stop()
client.disconnect()

Between two consecutive Publish messages, delay of 15 seconds is inserted, as we are using a free CloudMQTT server and that has speed limitations and hence can't receive packets two quickly.
Publish-Subscribe Example
Download Complete programs from GitHub.

1 comment:

  1. Dear writer, snapshots of your code is missing operators like '=' and '.' in visibility due to color coding. I wish you properly proof read your blog before you posting it

    ReplyDelete