Paho Python MQTT Client Subscribe With Examples

subscribe-topics-iconTo receive messages on a topic you will need to subscribe to the topic or topics.

To subscribe to a topic you use the subscribe method of the Paho MQTT Class object.

In this tutorial we will look at some examples of using the subscribe method.

The diagram below illustrates the subscribe message flow.



The subscribe method accepts 2 parameters – A topic or topics and a QOS (quality of Service) as shown below with their default values.

subscribe(topic, qos=0)

The documentation lists three ways of calling the subscribe method.

Method 1- Uses a single topic string This is an example function call.

client1.subscribe(“house/bulb1”,1)

Method 2- Uses single tuple for topic and QOS -(topic,qos)

client1.subscribe((“house/bulb2”,2))

Method 3- Used for subscribing to multiple topics and uses a list of tuples [(topic1,qos),(topic2,qos),(topic3,qos)]

client1.subscribe([(“house/bulb3”,2),(“house/bulb4”,1),(“house/bulb5”,0)])

The subscribe function returns a tuple to indicate success, and also a message id which is used as a tracking code.

(result, mid)

Subscribe Acknowledgements

The MQTT broker/server will acknowledge subscriptions which will then generate an on_subscribe callback.

The format of the callback function is shown below:

on_subscribe(client, userdata, mid, granted_qos)

The mid value can be compared with the one returned by the function call to check for successful subscription requests.
See Checking Subscriptions using Python

MQTT Subscribe Success and Failure Examples:

We will use a simple Python subscribe script to show:

  1. Successful subscription
  2. Failed subscription raising a value error -To make this fail I set the QOS to 5 which is invalid
  3. Failed subscription with an MQTT_ERR_NO_CONN –To make this fail I didn’t connect to the broker before I tried to subscribe.

mqtt-subsribe-examples

Notes:

In the screen shot above you can see in the successful subscribe that the mid (message ID) values that are printed match.

This shows that the subscribe was successful.

You would use the mid values when checking on multiple subscriptions as some might fail and others succeed

Also note the result value of 0 which is a success code (MQTT_ERR_SUCCESS)

The last example shows a fail due to a connection error the mid value is None. The (MQTT_ERR_NO_CONN) value is 4 which indicates a connection failure.

The table below taken from the client source show the other error codes and their meaning:

mqtt-error-values

Subscribing to Multiple MQTT Topics

In this example we will look at the different ways of subscribing to multiple MQTT topics.

You can subscribe by:

    • Calling the subscribe function for each topic.
    • Calling the subscribe function with a topic list

The screenshot below illustrates both methodsSubscribing-Multiple-Topics

Firstly we use single topic subscriptions to subscribe to 2 topics. Notice that two messages are sent and we would need to track two message ids.

In the second example we subscribe to 3 topics using a list. Notice that a single subscribe message is sent, and results in a single acknowledgment.

Notice also how the message ids match.

Setting The Quality of Service

If you want to try and ensure that the subscriber gets a message then you need to subscribe with a quality of service of 1 or 2. See

However even this doesn’t guarantee that they will receive the message, as you also need to have subscribed with a persistent connection (not the default). See Clean Sessions and QOS (quality of service) -Example.

When you subscribe the suback message will tell you what QOS the broker has assigned to the subscription.

Although it could be downgraded it is usually the same as what you set in the subscription request.

Subscribe Wait Loops

In my simple scripts demo scripts I don’t process the callbacks to check for successful subscriptions, but in real scripts you will need to.

Generally it will make no sense proceeding unless you have successfully subscribed.

Therefore I tend to use the following format:

  1. Subscribe
  2. Wait for success or quit
  3. Proceed

Here is a snippet of code from my wait for function which I use to wait for connections and subscriptions

def wait_for(client,msgType,period=0.25):
 if msgType=="SUBACK":
  if client.on_subscribe:
    while not client.suback_flag:
      logging.info("waiting suback")
      client.loop()  #check for messages
      time.sleep(period)

Clean Session Flag and Remembering Subscriptions

If you connect using the clean session flag set to False then the next time you connect you won’t need to subscribe as the broker remembers your subscriptions.

You can use the unsubscribe method to cancel existing subscriptions.

Subscribing to Restricted Topics

Brokers like the Mosquitto broker allow you to control access to topics.

This means that some topics may be restricted, and you are unable to subscribe to them.

Unfortunately the client doesn’t receive any indication of this, and so it appears that the subscription has been successful but it has not. See Using the ACL to restrict topic access on the Mosquitto broker.

The only way to be sure that a subscribe has really succeeded is to receive messages on that topic.

Effects of Retained Messages

When you subscribe to a topic that has had messages published with the retain flag set then you will receive any retained messages.

The client can detect that is a retained messages by examining the message.retain flag in the on_message callback as shown in the code snippet below:

def on_message(client, userdata, message):
    print("message received  ",str(message.payload.decode("utf-8")),\
          "topic",message.topic,"retained ",message.retain)
    if message.retain==1:
        print("This is a retained message")

– See Understanding Retained messages

Unsubscribing

If you no loner need to receive messages on a topic you can unsubscribe from that topic using the unsubscribe method.

The method only accepts 1 argument the topic.

unsubscribe(topic)

The call returns a return code and mid value like the subscribe method and is acknowledged by a UnSubAck response which triggers the on_unsubscribe callback function.

on_unsubscribe(client, userdata, mid)

Again you can compare the mid values in the response code and on_unsubscribe callback to check for success or failure.

Subscribe Suggestions

  • Use a try block on the subscribe call.
  • Check the return code result value for a success
  • Check that all subscriptions have been successful by examining the mid value in the callback.
  • Use a wait loop to wait for successful subscriptions before proceeding.
  • Consider publishing to the same topic to verify subscription.

Script Examples

Simple MQTT Publish and subscribe example script

Video

If you prefer a videos I’ve created a YouTube video that covers the subscribe process that you may enjoy watching.

There is another video that covers subscribe acknowledgements

Next—>MQTT Publish-Python Client Example

Common Questions and Answers

Q- I have subscribed to a topic when using a persistent connection. I’ve been disconnected for a few hours what happens when I re-connect?

A– When you reconnect you will see all messages that have been published on that topic while you were disconnected provided the messages were published with a QOS of 1 or 2 and that you originally subscribed with a QOS of 1 or 2.

Q- How do I subscribe to all topics?

A- Subscribe to #

Using The Paho Python MQTT Client Tutorials

Related tutorials and Resources

Facebooktwittergoogle_plusredditpinterestlinkedinmail

16 comments

  1. def On_message(client, userdata, msg):
    if str(msg.payload)==”b\’start\'”:
    while True:
    print(“in while loop”)

    if str(msg.payload)==”b\’stop\'”:
    print (“stop”)
    if the message start is sent then the code is stuck in while loop
    i am unable to receive the message stop when the message start is sent.

    1. Don’t run the loop in the on message callback. In the onmessgae callback use
      def On_message(client, userdata, msg):
      msg_received=str(msg.payload.decode(“utf-8″))
      if msg_received==”Start”:
      client.startflag=True
      if msg_received==”Stop”:
      client.startflag=False

      In the main Loop use
      client.startflag=True
      while client.startflag:
      loop code here

  2. hi steve,
    I want to store my subscription message to a variable, how do I do it?

    Here is my on_message function:

    def on_message(client, obj, msg):
    print(msg.payload.decode())

    how do I get the msg.payload.decode() value and store it to a variable?because I need store the message to JSON file.

  3. Hello again steve. I finally succeed the connection to client using MQTT Broker and subscribing to the topic,receiving data from it.

    I intend to send data back to node,by define an “on_publish” callback.
    I want to send back,payload,which i will define it every time.

    My question is:i have to create-as i mentioned before-“”on_publish” function or i can set just a code line as,
    client.publish(“v1/devices/me/telemetry”,json.dumps(a[‘object’][‘gpsLocation’][‘3’])),where i will set the desired value,every time, in the way i do.

    Is it appropriate, setting the message payload inside or outside the function?

    Thanks in advance,
    Nikos.

    1. Just use the publish to publish data. The on_publish is used to check that the publish succeeded and is only used if you publish with QOS pf 1 or 2.
      I would set the payload outside the function as it is much clearer.
      rgds
      steve

      1. Thanks for the immediate answer steve.
        Just another question:sending/publishing data back to node using (client.publish (…….)), i can send back only specific data according to the subscripted data,received from the topic?

        Finally, the fields: client.publish(“v1/devices/me/telemetry”) are right or i have to set the same topic i subscribed from:
        “application/1/node/70b3d58ff00317cd/#”

        Thanks again,
        Nikos.

  4. i’ve read a lot of your tutorials on mqtt and watched some videos so i just wanted to say thanks a bunch for the effort, peace =)

  5. How do I check the mid arguments match, so I can test for a successful subscription when an on_subscribe call back is defined? I want to be able to resend a subscribe request (or simply stop the program from being in a blocking routine) if the mid arguments don’t match.

      1. Do you have the script in the video. Its useful to have the script shown in the video and its easier to modify the code i reconize

Leave a Reply

Your email address will not be published. Required fields are marked *