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.

MQTT Wildcards

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

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.

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 with home/.

Differences Between + and #

FeatureSingle-level Wildcard (+)Multi-level Wildcard (#)
Match RangeMatches only one levelMatches all sublevels from a specified level
Position RestrictionCan appear in any level of the topicCan only appear at the end of the topic
Typical UsageWhen you care about a specific levelWhen 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 wildcard home/+/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!