Simple Python MQTT Publish and Subscribe -Example

In this simple project we will be publish and subscribe to a topic, and then receive the published message.

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

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
[Total: 2    Average: 5/5]

6 comments

  1. Thank you for the explanation on how to use MQTT under Python. I have managed to successfully write a script to control my house heating using a Raspberry Pi with Mosquitto and Python3. It is running flawlessly as far as I can tell.

    I have tried to make it start at boot in case the Pi goes down and starts when power is restored but I can’t get it to work when called via a cron job. It seems it can’t find the client and publish libraries presumably because it is being run by root at this stage.

    Is it possible to give the full path to the import function and, what is more to the point, what would that path be?

    1. John
      I’ve haven’t done what you are trying but I would try running the cron job as your normal user I found these instructions.
      https://stackoverflow.com/questions/8475694/how-to-specify-in-crontab-by-what-user-to-run-script

      On my Linux box the mqtt client is under
      /home/steve/.local/lib/site-packages
      On some of my scripts I use my own classes which I don’t put in site packages the command at the top of the python script to set the path is this.(windows system)
      sys.path.append(“c:/python34/steve/network/”)
      Hope that helps.
      Rgds
      Steve

      1. Hi Steve,

        Many thanks for your reply. I really thought that you had cracked it when you suggested using cron as a local user but, unfortunately, not.

        I also tried adding the two lines:
        import sys
        sys.path.append(“/home/pi/.local/lib/python3.5/site-packages/paho/mqtt”)
        at the top of my script (having checked with FileZilla that that was where the packages where kept) but again, no luck.

        It’s interesting that Python did not balk at the’ import sys’ so it must be something to do with Python not being able to find the Paho library. It says, “No module named ‘paho'”

        Anyway, I shall have to shelve this for now; it has taken up far too much of my time (and yours). The program works just fine; I just have to start it manually in the event of a system reboot.

        Thanks again,

        John.

        1. John
          Try import the paho client using the full path in a normal script (not cron) or a python shell. That way you can be sure it is were you think it is.
          If it is finding SYS Ok then it is a path problem.

          1. Once again, so close but not quite there.

            I added the full path but Python balked at the forward slashes. Then it dawned on me that the path uses dots and not forward slashes. BUT the .local directory has a dot in the name and I haven’t figured out how to escape it in that situation.

            Despite the fact that I said I was going to shelve the problem, I did try putting ‘sleep 100’ in the shell file so that the system had time to settle before attempting to import any Paho libraries but again, no joy.

            Thanks for your help. If I ever sort it, I shall get back to you and let you know what the solution is.

            John.

Leave a Reply

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