Unlocking the Power of MQTT Wildcards | A Deep Dive into + and # for Greater IoT Efficiency
In the Internet of Things (IoT) domain, MQTT Wildcards play a critical role in simplifying topic subscriptions and enhancing system flexibility. MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol widely used for communication between devices. It follows a publish/subscribe model, organizing message flow through topics. For developers, the design of topics and the subscription model are crucial, and understanding how to effectively use MQTT Wildcards can significantly improve the scalability and maintainability of the system.
If you’ve ever worked with MQTT topics, you know that subscribing to a specific topic can become cumbersome, especially when your system involves many variables and levels. This is where MQTT Wildcards come into play, helping to simplify topic subscriptions and making your system more flexible and scalable.
Table of Contents
What are MQTT Wildcards?
In MQTT, topics are used to identify the “address” of message streams. Each device, sensor, or application sends or receives messages based on specific topics. However, sometimes you don’t want to subscribe to a particular topic but instead want to receive multiple topics that match certain patterns. This is where MQTT Wildcards are useful.
MQTT Wildcards allow you to subscribe to multiple topics that match a pattern, which not only reduces the number of subscriptions but also enhances the scalability and flexibility of your system. MQTT supports two commonly used wildcards: single-level wildcard (+) and multi-level wildcard (#).
Detailed Explanation of MQTT Wildcards
Single-level Wildcard (+)
The + is a single-level wildcard that matches one level of a topic. If the topic structure has multiple levels, + can only match one level at a time.
For example, suppose your topic structure is as follows:
home/livingroom/temperature
home/kitchen/temperature
home/livingroom/humidity
If you subscribe to home/+/temperature
, you will receive messages from:
home/livingroom/temperature
home/kitchen/temperature
But home/livingroom/humidity
will not match because + only matches the temperature level and does not span across child levels.
Use Case:
- When you want to subscribe to all topics under a specific level, you can use + to replace the exact level.
- For instance, in a home automation system, you could subscribe to
home/+/temperature
, and you would receive the temperature data from each room without needing to subscribe to each individual room.
Multi-level Wildcard (#)
The # is a multi-level wildcard that matches all sub-levels under a specific level. This is the most powerful wildcard in MQTT, especially useful when there are many devices or a complex hierarchical topic structure. # can only appear at the end of a topic. If placed elsewhere, the subscription will fail.
For example, with the following topic structure:
home/livingroom/temperature
home/kitchen/temperature
home/livingroom/temperature/room1
home/livingroom/humidity
If you subscribe to home/#
, you will receive:
home/livingroom/temperature
home/kitchen/temperature
home/livingroom/temperature/room1
home/livingroom/humidity
This is because # matches all subtopics under home/
.
Use Case:
- When you want to receive all messages within a certain range, # is the ideal choice. For example, if you have many rooms and want to receive data from all rooms, you can subscribe to
home/#
, which will automatically capture all data that starts withhome/
.
Differences Between + and #
Feature | Single-level Wildcard (+) | Multi-level Wildcard (#) |
---|---|---|
Match Range | Matches only one level | Matches all sublevels from a specified level |
Position Restriction | Can appear in any level of the topic | Can only appear at the end of the topic |
Typical Usage | When you care about a specific level | When you need to subscribe to multiple levels |
How to Use MQTT Wildcards
Let’s look at how to use these wildcards in MQTT using the Python client with the paho-mqtt
library.
Install the paho-mqtt client library
pip install paho-mqtt
Code
import paho.mqtt.client as mqtt
import warnings
# Disable DeprecationWarnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
# Set the MQTT broker address (using HiveMQ broker)
broker = "broker.hivemq.com"
# Set the topic to subscribe to
topic = "home/+/temperature"
# Callback function that gets triggered when a message is received
def on_message(client, userdata, message):
# Decode the payload (message content)
payload = message.payload.decode()
print(f"Received message: {payload}")
# If the message contains 'Temperature', extract and print the temperature value
if "Temperature" in payload:
# Extract the numeric part of the temperature (e.g., "23°C")
temperature = float(payload.split(":")[1].strip().replace("°C", ""))
print(f"Temperature value: {temperature}°C")
# If the message is a numeric value (e.g., 29.60), process it
elif payload.replace(".", "", 1).isdigit():
value = float(payload) # Convert the string to a float
print(f"Numeric value: {value}")
# If the message does not match any expected pattern
else:
print("Received message in unexpected format")
# Create an MQTT client instance
client = mqtt.Client(client_id="pythonClient", protocol=mqtt.MQTTv5)
client.on_message = on_message # Assign the callback function to handle incoming messages
# Connect to the MQTT broker
client.connect(broker)
# Subscribe to the topic with a wildcard to capture all temperature readings
client.subscribe(topic)
# Keep the client running to wait for messages
client.loop_forever()
Code Explanation
warnings.filterwarnings("ignore", category=DeprecationWarning)
:This line is used to suppress DeprecationWarnings to prevent them from printing in the console.
on_message
回呼函数:This function is triggered whenever an MQTT message is received. It first prints the received message. If the message contains “Temperature”, it extracts and prints the temperature (assuming the message format is “Temperature: 23°C”). If the message is a number (like 29.60), it processes it as a floating-point value.
client.connect(broker)
:Connects to the specified MQTT server.
client.subscribe(topic)
:Subscribes to a topic with wildcards. In this case, the wildcardhome/+/temperature
allows the client to receive messages from all rooms’ temperature data.
client.loop_forever()
:Starts the MQTT client’s loop to continuously receive and process messages.
Output
Assuming the MQTT broker publishes the following messages:
"Temperature: 23°C"
"29.60"
"2"
The output will be:
Received message: Temperature: 23°C
Temperature value: 23.0°C
Received message: 29.60
Numeric value: 29.6
Received message: 2
Numeric value: 2.0
Why Use MQTT Wildcards?
- Reduce the Number of Subscriptions
MQTT Wildcards allow you to simplify the subscription process by enabling you to subscribe to higher-level topics and receive messages from different devices without needing to subscribe to each individual device - Increase Flexibility
As your system grows, traditional manual subscriptions can become tedious and difficult to manage. Using MQTT Wildcards, you can easily handle message flows from various levels without hardcoding each device’s topic. - Enhance Maintainability
MQTT Wildcards make it easier to add new devices or features without changing the subscription logic. You only need to ensure that new devices’ topics follow the existing structure.
IoT Smart Home System Example
Imagine you have a smart home system with multiple rooms, each having different sensors such as temperature, humidity, and light. The traditional method would require you to subscribe to each sensor’s topic in each room, leading to a large number of subscriptions that are hard to manage. After using MQTT Wildcards, you only need to subscribe to:
home/+/temperature
:To receive temperature data from all rooms.home/#
:To receive all data (temperature, humidity, etc.) from all rooms.
This makes your subscriptions simpler and allows you to easily handle new rooms or devices.
Conclusion
MQTT Wildcards are an indispensable tool for developers when building IoT systems. Whether it’s the single-level wildcard (+) or the multi-level wildcard (#), both help simplify subscription logic and enhance the flexibility and scalability of your system. Understanding and using these MQTT Wildcards effectively can significantly improve development efficiency and lay a solid foundation for future expansion and maintenance.
I hope this article helps you better understand and utilize MQTT Wildcards in your IoT development!