by Professor Petabyte
MQTT stands for Message Queuing Telemetry Transport. It is a lightweight messaging protocol designed for constrained devices and unreliable networks, making it ideal for Internet of Things (IoT) applications.
This page includes lots of code samples. For clarity, they have colour coded backgroungs like this:-
Commands to be run on a Linux command line.
Python code.
SQL code/queries
HTML script
Anything outside of the above categories
Essentially, MQTT provides a simple and efficient way for diverse devices to exchange information, even in challenging network conditions, which is essential for the growth and functionality of the IoT ecosystem.
home/bedroom/fan
home/+/fanmatches all fans within home, whilst
home/bedroom/#matches everything in bedroom
MQTT Quality of Service (QoS) controls message delivery guarantees between client and broker. It's important when reliability matters — for example, in sensor networks or industrial systems where data loss or duplication can be a problem.
There are three levels of service:
How QoS is specified depends on the client library being used. Here are two common examples:
import paho.mqtt.client as mqtt client = mqtt.Client() client.connect("broker.hivemq.com", 1883) # Publish with QoS 1 client.publish("home/light", "on", qos=1) # Subscribe with QoS 2 client.subscribe("home/light", qos=2)
For umqtt.simple (QoS 0 only) — you need umqtt.robust or another library for higher QoS
client.subscribe(b"home/light", qos=1) # if supported client.publish(b"home/light", "on", qos=1)
N.B. Not all libraries or brokers support QoS 2, especially in constrained devices like microcontrollers.
There are many ways in which MQTT can be demonstrated / used / tested. This is a step-by-step example of how it can be demonstrated on a standard Ubuntu PC.
sudo apt update
sudo apt install -y mosquitto mosquitto-clients
sudo systemctl enable mosquitto
sudo systemctl start mosquitto
mosquitto_sub -h localhost -t test/topic
mosquitto_pub -h localhost -t test/topic -m "What hath God wrought"
If you want to access the MQTT broker remotely, Open MQTT Port (1883) in Firewall
sudo ufw allow 1883
A username and password can be set in the /etc/mosquitto/mosquitto.conf file and generate credentials with:
sudo mosquitto_passwd -c /etc/mosquitto/passwd myuser
This is a walk through setting up a secure Mosquitto MQTT broker on Ubuntu with username/password authentication and TLS encryption.
sudo apt install -y mosquitto mosquitto-clients
sudo mosquitto_passwd -c /etc/mosquitto/passwd myuser
sudo nano /etc/mosquitto/conf.d/default.confPaste the following minimal secure config:
allow_anonymous false password_file /etc/mosquitto/passwd listener 1883
You can add listener 8883 and TLS settings later for encrypted comms.
sudo systemctl restart mosquitto
mosquitto_sub -h localhost -t test/topic -u myuser -P yourpasswordAnd in another terminal, publish:
mosquitto_pub -h localhost -t test/topic -u myuser -P yourpassword -m "What hath God wraught"If you see the message, authentication works.
sudo mkdir -p /etc/mosquitto/certs cd /etc/mosquitto/certs sudo openssl req -x509 -newkey rsa:2048 -nodes -days 365 \ -keyout mosquitto.key -out mosquitto.crt \ -subj "/CN=yourdomain.com"
listener 8883 cafile /etc/mosquitto/certs/mosquitto.crt certfile /etc/mosquitto/certs/mosquitto.crt keyfile /etc/mosquitto/certs/mosquitto.key require_certificate false
sudo systemctl restart mosquitto
mosquitto_sub --cafile /etc/mosquitto/certs/mosquitto.crt -h localhost -p 8883 -t test/topic -u myuser -P yourpassword
Here's a that securely subscribes and publishes to your Mosquitto MQTT broker with username/password and optional TLS.
pip install paho-mqtt
import paho.mqtt.client as mqtt # Broker config broker = "localhost" port = 8883 # TLS port topic = "secure/topic" username = "myuser" password = "yourpassword" # TLS config cafile = "/etc/mosquitto/certs/mosquitto.crt" # path to your broker's cert # Create client instance client = mqtt.Client() # Set credentials client.username_pw_set(username, password) # Enable TLS client.tls_set(cafile=cafile) # Connect and publish client.connect(broker, port) client.publish(topic, "Hello from secure Python client!") client.disconnect()
import paho.mqtt.client as mqtt broker = "localhost" port = 8883 topic = "secure/topic" username = "myuser" password = "yourpassword" cafile = "/etc/mosquitto/certs/mosquitto.crt" # Callback when a message is received def on_message(client, userdata, msg): print(f"Received: {msg.topic} -> {msg.payload.decode()}") client = mqtt.Client() client.username_pw_set(username, password) client.tls_set(cafile=cafile) client.on_message = on_message client.connect(broker, port) client.subscribe(topic) print("Listening for secure messages...") client.loop_forever()
Below is a secure Python MQTT subscriber that connects to your Mosquitto broker, receives messages, and inserts them into a MariaDB database.
pip install paho-mqtt mysql-connector-python
CREATE DATABASE mqtt_data; USE mqtt_data; CREATE TABLE messages ( id INT AUTO_INCREMENT PRIMARY KEY, topic VARCHAR(255), payload TEXT, received_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
import paho.mqtt.client as mqtt import mysql.connector from datetime import datetime # MQTT configuration broker = "localhost" port = 8883 topic = "secure/topic" username = "myuser" password = "yourpassword" cafile = "/etc/mosquitto/certs/mosquitto.crt" # MariaDB configuration db_config = { "host": "localhost", "user": "mqtt_user", # Create this user with necessary rights "password": "mqtt_password", # Replace with your real password "database": "mqtt_data" } # Callback: when message is received def on_message(client, userdata, msg): payload = msg.payload.decode() print(f"[{datetime.now()}] {msg.topic} => {payload}") # Save to MariaDB try: db = mysql.connector.connect(**db_config) cursor = db.cursor() sql = "INSERT INTO messages (topic, payload) VALUES (%s, %s)" cursor.execute(sql, (msg.topic, payload)) db.commit() cursor.close() db.close() except mysql.connector.Error as err: print(f"Database error: {err}") # Setup MQTT client client = mqtt.Client() client.username_pw_set(username, password) client.tls_set(cafile=cafile) client.on_message = on_message client.connect(broker, port) client.subscribe(topic) print("MQTT subscriber connected and logging to MariaDB...") client.loop_forever()
CREATE USER 'mqtt_user'@'localhost' IDENTIFIED BY 'mqtt_password'; GRANT INSERT, SELECT ON mqtt_data.* TO 'mqtt_user'@'localhost'; FLUSH PRIVILEGES;
mosquitto_pub -h localhost -p 8883 --cafile /etc/mosquitto/certs/mosquitto.crt \ -u myuser -P yourpassword -t secure/topic -m "Hello MariaDB!"
SELECT * FROM mqtt_data.messages;
This can be extended to also retrieve and display data in a web page. PHP or a framework such as FLASK can be used for this. The following is how to do it with FLASK, the Python framework for Web apps.
pip install flask mysql-connector-python
mqtt_viewer/ ├── app.py └── templates/ └── index.html
from flask import Flask, render_template import mysql.connector app = Flask(__name__) # MariaDB connection config db_config = { "host": "localhost", "user": "mqtt_user", "password": "mqtt_password", "database": "mqtt_data" } @app.route("/") def index(): try: db = mysql.connector.connect(**db_config) cursor = db.cursor(dictionary=True) cursor.execute("SELECT * FROM messages ORDER BY received_at DESC LIMIT 100") messages = cursor.fetchall() cursor.close() db.close() except mysql.connector.Error as err: return f"<h1>Database Error</h1><p>{err}</p>" return render_template("index.html", messages=messages) if __name__ == "__main__": app.run(debug=True)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MQTT Message Viewer</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ccc; padding: 8px; }
th { background: #f4f4f4; }
</style>
</head>
<body>
<h1>MQTT Messages</h1>
<table>
<tr>
<th>ID</th>
<th>Topic</th>
<th>Payload</th>
<th>Received At</th>
</tr>
{% for msg in messages %}
<tr>
<td>{{ msg.id }}</td>
<td>{{ msg.topic }}</td>
<td>{{ msg.payload }}</td>
<td>{{ msg.received_at }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
In the mqtt_viewer/ folder:
python app.py
Open a brower and go to
http://localhost:5000
By combining all these elements, MTQQ, Bash scripts, MySQL, Python and FLASK, it is possible to very quickly and easily create a way to capture data with either a single or a network of Raspberry Pi Picos, wirelessly transmit the data in real time to a Raspberry Pi, store it in an SQL database, and do all kinds of other data processing & analysis. The sensors could be logging all kinds of data:
MTQQ can also be used to send messages between networked computers, e.g. a simple messaging service between co-workers, e.g.
"Are you ready to go to lunch?" -- reply: "Almost, give me ten minutes."