How to Use MQTT with the Raspberry Pi

2/6/2019 | By Staff

MQTT is a lightweight messaging protocol designed for low-cost and low-power embedded systems. Devices such as the ESP8266 benefit highly from MQTT, but even the Raspberry Pi can use the MQTT protocol.


Install the Paho-MQTT Library

Before we look at how to install the Paho-MQTT library, we first need to understand why Python is being used instead of other languages, such as C++. While other languages provide speed, Python is arguably the ultimate proto-typing language thanks to its easy-to-use library system with PIP. Also, the libraries made for Python are more times than not the easiest libraries to use. For example, getting an MQTT client to work in C++ would provide some challenges since some libraries only work on Windows systems and other libraries have complex installation and linking options. Python, however, uses one PIP command to install the library. From there, all Python programs can import the MQTT library with east. On top of that, the MQTT library for Python is incredibly easy to use and only requires a handful of lines of code.

The first step into using MQTT with Python is to install the Paho-MQTT library. To do this on the Raspberry Pi, open a console window and enter the command below. This is a PIP install instruction that will automatically find, download, and install the Paho-MQTT library. This is a great example of why I like Python for its simplicity.

pip install paho-mqtt

The Paho-MQTT Class

The MQTT class has only a handful of methods that the user needs to worry about, including:

  • connect() – Connect to an MQTT library
  • disconnect() – Disconnect from an MQTT library
  • subscribe() – Subscribe to a topic
  • unsubscribe() – Unsubscribe from topics
  • publish() – Publish a message to a topic
  • .on_message – Attach a function to the on_message event (callback)

The first step into using the Paho-MQTT is to import the library. The first line of your Python code needs to have the following line:

Import paho.mqtt.client as mqtt

With the library imported, the next step is to create a client object that is your MQTT client. This client needs to have a unique ID. This is done using the mqtt.Client() method. It does take up to 4 optional parameters but these are often not needed and you only need to provide a unique ID.

ourClient = mqtt.Client(“makerio_mqtt”) # Create a MQTT client object

The next step is to have the client connect to an MQTT broker (or server) and this is done with the connect method. This takes up to 4 parameters including the host, port, keep alive, and bind address, but we only need to provide the host IP. To keep things simple in this example we will use the Mosquitto MQTT test broker that allows developers to connect and test out software. There is no sign-up or registration required, and has the following details:

  • host: ip: 1883

ourClient.connect(“”, 1883) # Connect to the test MQTT broker

MQTT Terminology, sending, and receiving data

MQTT uses a different terminology when it comes to servers and clients. MQTT servers are not called servers, but “brokers” as they receive incoming messages for specific topics and immediately distribute that message to all devices that are subscribed to that topic. A topic can be thought of as a variable name and messages are the values of the topic.

For example, a topic could be called “air conditioning” and a thermostat could send the message “on” or “off” to turn the AC unit on or off. When a device sends a message to a topic, they “publish” a message, and when devices want to read data from a topic, they “subscribe” to it. Unlike servers, MQTT brokers do not store data and act more like a connection as opposed to a data center. If a device connects to a broker after a message has sent it will not receive that message. Brokers are also unlike servers as they can send data to a client without the client asking for anything.

Publish to a Topic

To publish a message to a topic the publish() method is used, taking multiple parameters. However, we only need to provide the topic and message.

# publish(topic, message)

ourClient.publish(“AC_unit”, “on”) # Turn the AC unit on

Subscribe to a Topic

To subscribe to a topic the function below is used:

ourClient.subscribe(“AC_unit”) # Subscribe to the topic AC_unit

Subscribing to topics requires a special method called a “callback”. Essentially, a callback can be thought of as a microcontroller interrupt, whereby the receiving of an event - such as a message from an MQTT broker - triggers a function that handles that event. Therefore, the first step is to use the following instruction BEFORE your main code loop:

ourClient.on_message = messageFunction # Attach the “messageFunction” to the message event

The next step involves creating out “messageFunction” method and this needs to accept three parameters:

def messageFunction (client, userdata, message):

Inside this function we can do whatever we want with the message variable, whether that’s get the topic or the message. In this example, our messageFunction will simply print the topic and the message that has been sent by the broker.

def messageFunction (client, userdata, message):

  topic = str(message.topic)

  message = str(message.payload.decode(“utf-8”))

  print(topic + message)

Final Result

If we put all of this code together, we can see a simple MQTT client:

import paho.mqtt.client as mqtt # Import the MQTT library

import time # The time library is useful for delays


# Our "on message" event

def messageFunction (client, userdata, message):

topic = str(message.topic)

message = str(message.payload.decode("utf-8"))

print(topic + message)



ourClient = mqtt.Client("makerio_mqtt") # Create a MQTT client object

ourClient.connect("", 1883) # Connect to the test MQTT broker

ourClient.subscribe("AC_unit") # Subscribe to the topic AC_unit

ourClient.on_message = messageFunction # Attach the messageFunction to subscription

ourClient.loop_start() # Start the MQTT client



# Main program loop


ourClient.publish("AC_unit", "on") # Publish message to MQTT broker

time.sleep(1) # Sleep for a second