What is MQTT?
MQTT (Message Queue Telemetry Transport) is a simple and ‘lightweight’ way for internet-connected devices to send each other messages. This is important for home-automation because devices need to send messages back and forth like ‘turn on the lights’ or ‘turn off the sprinklers.’ Devices using MQTT communicate by publishing data to topics. MQTT devices subscribe to a topic, and when data is published to that topic it is pushed to all the subscribers.
In this tutorial we’re going to set up an MQTT client on our raspberry pi which will subscribe to a couple of topics. Any data published to those topics will be pushed to our raspberry pi, and it can decide how to react.
Python Setup
Here we're assuming you’re running a reasonably up-to-date version of raspbian, that already has pip installed. pip is a package management system used to install and manage software packages written in Python.
First we need to get some MQTT libraries to use with python
sudo pip install paho-mqtt
recap: sudo gives us super-user permissions, pip is the command/program we’re invoking, and we’re using pip to install a package called paho-mqtt
Set up a client
Now we’re going to write a python script that sets the RasPi up as a client that connects to a free MQTT server.
If you’re accessing your Raspberry Pi with a keyboard and monitor it is easy enough to open the Python Shell (Start Button > Programming > Python 2(IDLE)) and open a new script (File > New File). Select File > Save As and navigate to your Documents folder. Save the currently empty file as mqtt_client_demo.py
If you’re accessing your RasPi over SSH then you can execute sudo nano ~/Documents/mqtt_client_demo.py instead to access the console editor and begin editing.
Copy the following code into the python script - as always we recommend manually typing it out so you get a better feel for the code structure.
# MQTT Client demo # Continuously monitor two different MQTT topics for data, # check if the received data matches two predefined 'commands' import paho.mqtt.client as mqtt # The callback for when the client receives a CONNACK response from the server. def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) # Subscribing in on_connect() - if we lose the connection and # reconnect then subscriptions will be renewed. client.subscribe("CoreElectronics/test") client.subscribe("CoreElectronics/topic") # The callback for when a PUBLISH message is received from the server. def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) if msg.payload == "Hello": print("Received message #1, do something") # Do something if msg.payload == "World!": print("Received message #2, do something else") # Do something else # Create an MQTT client and attach our routines to it. client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect("test.mosquitto.org", 1883, 60) # Process network traffic and dispatch callbacks. This will also handle # reconnecting. Check the documentation at # https://github.com/eclipse/paho.mqtt.python # for information on how to use other loop*() functions client.loop_forever()
Save the file (if you’re in nano press Ctrl+X and you'll see the prompt below. Strike Y and then Enter to save the changes to the file.)
Let’s peek at the code a moment. Just like the comment at the top says, this file will subscribe to a MQTT topic on a free MQTT server (test.mosquitto.org). If any data is published to the topics that this client is interested in, it will print them to the shell. The real power here comes from the decision making that is included – a couple of if statements check to see if the received data matches some predefined strings, and if so, can choose to do other things. This could be anything from blinking an LED to turning on the pool-pump and watering the garden.
Lines beginning with def are functions. These functions are attached to the mqqt-client object that we’ve defined as client. When certain events like a successful connection is established or a message is received, client triggers the functions that we attached to client.on_connect and client.on_message.
Now let’s look at publishing some data for our client to receive.
Publishing
Create another file in Documents called: mqtt_publish_demo.py and enter the following code:
# MQTT Publish Demo # Publish two messages, to two different topics
import paho.mqtt.publish as publish publish.single("CoreElectronics/test", "Hello", hostname="test.mosquitto.org") publish.single("CoreElectronics/topic", "World!", hostname="test.mosquitto.org") print("Done")
Save this file.
This script publishes the data “Hello” to the topic CoreElectronics/test and then publishes the data “World!” to the topic CoreElectronics/topic.
It’s worth noting that topics do not need to be created or deleted. It’s enough to just publish and subscribe to a topic.
Now for the fun part!
Make sure your RasPi is connected to the internet. Open a terminal (I’ll refer to it as Terminal1) and make sure you’re in the Documents folder with
cd Documents
from here, we’re going to start our client. Enter:
python mqtt_client_demo.py
If everything goes well, you will shortly see a message saying Connected with result code 0
Open another terminal instance (I’ll refer to it as Terminal2). Again, navigate to Documents execute the publish-script
python mqtt_publish_demo.py
Not much happens on Terminal2, but back over on Terminal1 we should see some action:
CoreElectronics/test Hello
Received message #1, do something
CoreElectronics/topic World!
Received message #2, do something else
If you see this output, then it means everything worked! What’s more, if you build and run mqtt_publish_demo.py on any internet connected device that can run python, your RasPi will respond in exactly the same way. Try it! It doesn’t take too much imagination to see how powerful and scalable this idea is. Where the script is printing “do something,” could be something as basic as turning a light on or off, to watering the garden and feeding the fish.
When you’re ready to quit the client, just Ctrl+C in its terminal window to halt the python script.
Try changing one of the messages in mqtt_publish_demo.py and see how this might affect the output from the client script. You could try modifying the client to toggle an LED when a certain command is received! This kind of setup pairs well with other IoT devices like the ESP8266 or Particle.
To get you started on project ideas, why not bring over some of the script from this tutorial to change the colour of an LED based on what data that is published to an MQTT topic.
Data you publish to free MQTT servers are accessible by anybody. Don’t use this code for important things. If you’re unsure, ask yourself whether undesired operation of your program would have serious consequences (eg: pets not being fed by your automated pet-feeder while you’re away or the garage door randomly opening). It’s certainly best to only use this stuff in for-the-fun-of-it style projects.
For more information on the routines available, you can find the paho MQTT documentation at the paho github repository.