Simple Python MQTT Publish and Subscribe Example Script

This is a very simple example script to publish to a topic, and then receive the published message.

To do that we will need to first subscribe to the topic and then publish messages to the same topic.

We will publish and subscribe using the same client.

The Code


import time
import paho.mqtt.client as paho
broker="broker.hivemq.com"
broker="iot.eclipse.org"
#define callback
def on_message(client, userdata, message):
    time.sleep(1)
    print("received message =",str(message.payload.decode("utf-8")))

client= paho.Client("client-001") #create client object client1.on_publish = on_publish #assign function to callback client1.connect(broker,port) #establish connection client1.publish("house/bulb1","on")
######Bind function to callback
client.on_message=on_message
#####
print("connecting to broker ",broker)
client.connect(broker)#connect
client.loop_start() #start loop to process received messages
print("subscribing ")
client.subscribe("house/bulb1")#subscribe
time.sleep(2)
print("publishing ")
client.publish("house/bulb1","on")#publish
time.sleep(4)
client.disconnect() #disconnect
client.loop_stop() #stop loop

Note: You can copy the code direct from the page, paste it in a file and use.

When we run the script we get

pub-sub-code-output

Code Explanation and Notes

I use the time.sleep() function to insert delays so as to give the client time to connect etc.

We publish and subscribe using the same client.

The client.loop() is important otherwise the callbacks aren’t triggered.

The on message callback function catches the callback and the client.on_message=on_message binds the function to the callback.

There is no error checking i.e. I don’t check for a successful connection before publishing, and subscribing.

I have two free external brokers listed as sometimes the brokers are down and you will need to use the other one.

Just comment out the one you aren’t using.

I’ve used the topic house/bulb1 you can use any topic name you want.

Questions and Things to Try

  1. What would happen if I published before I subscribed?
  2. What would happen if I didn’t start the loop?
  3. What would happen if I didn’t bind the on_message function to the callback?

Answers below

Useful Tutorials and Resources:

Answers

  1. The message would be discarded by the broker.
  2. You wouldn’t see the message.
  3. You wouldn’t see the message.

Save

Save

Save

Save

Save

Save

Please rate? And use Comments to let me know more

48 comments

    1. If you try and run the program in the python IDE you will see the script end but still see the ping request/response in the IDE as the loop_start starts another thread and that is still running.
      Rgds
      Steve

  1. Great write up boss, hello am doing a final year project with the topic DESIGN AND IMPLEMENTATION OF CRYPTOGRAPHIC CYBERSECURITY PROTECTION FOR IOT DEVICES, I don’t know anything about Cryptographic, I need clue that will help me out and any recommendation on materials that could be of help. I appreciate your help

  2. Hi Steve, I am trying to publish a message to a topic using MQTT, i can see that the code reaches to the Publish command but the message is not published into the topic. is_published() if false. I added additional log and i see that the RC is 0 for the publish but the mid is 2 and when called from On_COnnect the Mid is 4. When i give the wait_for_publish() it hangs forever.
    How do i debug this, i was able to publish into another topic but this one is hanging. Any ways to debug

    1. It looks like you aren’t connected.Can you send me the code and I’ll take a look. Use the ask steve page to contact me so you can then send it via email.
      steves-internet-guide.com/ask-steve/

  3. Hello Steve,
    I’m trying to publish and subscribe to data from a ThingSpeak channel using MQTT. I am trying to publish data to the ThingSpeak channel from a sensor connected to the Pi and subscribe to that data using a different script and with the temperature values, control an LED connected to the Pi. I am able to publish data, but not subscribe to data from that channel. Kindly help with this.

  4. Hello Steve,
    I’m struggeling with sending message to the broker, because it requires username and password.
    I read a lot thrue the net but was not able to find out how to add username and password to the script.
    Are you able and willing to help me?

    kind regards
    Andi

  5. Hi Steve,

    Thanks for this wonderful tutorial, I want to check the connection before sending data, if the connection is not there, then I need to store the data in a local file and send once the connection is up. Can you help me to do that. Thanks

    Regards,
    Thomas TJ.

  6. Hi Steve, if I want to use the Mosquitto broker installed locally on the same laptop I’m creating the client on, how do you specify the broker when connecting the client to it?

    1. Use localhost or 127.0.0.0 or find the ip address and use that . localhost or 17.0.0.1 are the better options

  7. If python client is always listening. i.e loop_forever() if server connection get disconnected and it reconnect.
    That time i wont get any message from publisher.

  8. Hi Steve!
    I have a question about the disconnect/loop_stop functions. I want to publish a message every 30 seconds (a reading from an IoT device). I’m planning to set client.connected_flag=True in the on_connect function and then do the following after connecting to the broker:

    client.loop_start()
    while client.connected_flag:
    current_device_reading = get_device_read()
    client.publish(my_topic, current_device_reading)
    time.sleep(30)

    My question is do I still need to call client.loop_stop() or client.disconnect() somewhere? If the broker goes offline for some reason, is this when disconnect/loop_stop need to be invoked?

    1. Sam
      By starting a loop the client will handle reconnects for you I would change the code to
      client.loop_start()
      while True: #loop forever
      while client.connected_flag:
      current_device_reading = get_device_read()
      client.publish(my_topic, current_device_reading)
      time.sleep(30)
      If you get disconnected it wont try tp publish until it reconnects
      client.disconnect()
      Loop_stop()
      is at very end of script
      Rgds
      Steve

      1. Thanks! But in that case doesn’t the “while True” loop prevent the “client.disconnect()” and “client.loop_stop()” from ever being called?

        1. yes it does.
          the alternative is
          while flag
          code

          inside the while loop set the flag False on some condition.
          rgds
          Steve

  9. Can a Python script be both a publisher and a subscriber e.g. subscribe to one topic, publish to another? I have multiple RPi devices, one as a web server and mqtt borker, others as sensors/controllers. As I issue commands to the sensors/controllers, I presently have 1 script for publish and 1 script for receive on both sides (device and server) to enable bi-directional com. It is making maintenance/upgrades difficult, and I’m just wondering if there is a better way.

    Thanks!
    Reagan

    1. Yes It can be. It can also connect to multiple brokers at the same time. If you want an example script use the ask-steve page to let me know.
      Rgds
      Steve

  10. Is it possible to publish objects and not just string messages? The object of course could have a bunch of properties (strings, integers, etc.). Will the broker accept objects?

  11. What if instead of 2 MQTT brokers that you are using in this example I’d like to use the mosquitto broker that runs locally on my Raspi ? I am newbie to Python although have decades of C/C++/C# under my belt (this is the 2nd time I see Python script in my life).

    1. Yes you can use a single broker, As far as I remember the script does. It may use two clients but you can also use a single client.

  12. How do I publish and subscribe through different clients?
    I do not have raspberry Pi and only using PAho-mqtt python package.
    Thanks

    1. You can use the example script and run it twice. One would publish on topic one and the other would subscribe on topic1.
      Does that make sense?
      rgds
      Steve

  13. Hey, I love this tutorial but I stumbled across this tutorial because I am in the learning process and want to succeed in making a Python client that’ll receive messages on a subscribed topic for 30 mins for various continuous messages and then package it all into one file maybe .txt, .json or something.
    I’ll love it if you provide me with a direction where to go next in this learning process.

  14. Hi

    I want to save my data from the subscribed topic on to a text file. Here’s what I added to my code:

    “client.on_message= on_message
    f = open(‘/home/pi/test.txt’,’w’)
    f.write(‘on_message’)
    f.close() ”

    However the text file test.txt doesnt save the desired rather it just saves the word “on_message”

    Can anybody please help?

    Thanks.

    1. the on_message is a function
      You need to declare and on message function like below:
      def on_message(client, userdata, message):
      msg=msg.decode(“utf-8”) #get the message
      f = open(‘/home/pi/test.txt’,’w’)
      f.write(msg)
      f.close()

  15. Hello Steve ,

    Your explanation is very helpful. Is that possible in python to store the real time publish data. I am getting the data as a message , which includes integer , character as well as real number. Is there any way to store or save that published data. I want to use this data for training my deep learning model. Thanking you .

    Hitesh

  16. Hi Steve,
    Wondering if you tried to log a MQTT message to a SQL database (MySQL for instance)? I’m working on a small python script that keeps status of a MQTT message before logging data into MySQL database. The very odd thing is that the MySQL piece of code block never get executed (within a try … except trap). Any experience in that direction?
    Thanks,
    Yanick

  17. Hi, I tried your script with a broker (an other pi) on my lan and I get the result expected. Therefore, for me is still missing a piece of the story (I admit, non only from you tutorial!): how can I publish from a client and read from an other client? How can I keep running two pi’s and transmit infos with mqtt from one pi to the other? Should I launch a script like this one for the publisher and a second script for the subscriber? The web if full of examples using third party apps for the cloud but I would leave all my stuff on the lan.
    Thanks

    1. To get a publish script and subscribe script then just copy the pub-sub script.
      You then need to change the client name as each client needs to use its own name.
      You can then remove the subscribe code from the publish script and the publish code from the subscribe script.

      To move info between two pi’s then you need to publish from pi 1 and subscribe using pi 2 and vice versa. This you can do using the original pub-sub script.you will need to assign topic names e.g
      pi 1 would publish on topic pi-1 and pi 2 would subscribe to topic pi-1 and vice versa.
      The broker could be located on one of the pi’s or in the cloud.
      Does it make sense?

      1. Hi Steve, thank you for the suggestion. I created two separate scripts, one for the publisher (also broker) and one on a second machine for the subscriber. Both scripts have a while cicle. I launch together and I get message appearing on subscriber at regular intervals.
        Thank you again

        1. Hello,
          Can you help me in setting this up?
          I’m copying this into two different scripts but cannot see the message printed on subscriber script.

          1. Can you send your script to me using the ask steve page. You don’t need to paste it in as once I get the message I can email you.

  18. Hi Steve,
    Thanks for nice explanation,I want to explore on MQTT from scratch .
    Could you please suggest any link/documentation with few hands on examples.
    Thanks in advance!!!

Leave a Reply to Tejesh Cancel reply

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