How does MQTT work

❗️This exercise requires an MQTT server. If you're participating in a Ferrous Systems training, login credentials for a server operated by Espressif will be made available in the workshop, otherwise you can use one listed at https://test.mosquitto.org/ or install one locally.

To conclude the introductory course, let's add some IoT functionality to the board. Our goal here is have it send out real-time updates of sensor values without having to poll repeatedly, like we would with an HTTP server, and also receive commands to change the board LED color.

This can be modeled using a publish-subscribe architecture, where multiple clients publish messages in certain channels/topics, and can also subscribe to these topics to receive messages sent by others. Dispatching of these messages is coordinated by a message broker - in our case, this is done an MQTT server.

MQTT messages

An MQTT message consists of two parts - topic and payload.

The topic serves the same purpose as an email subject or a label on a filing cabinet, whereas the payload contains the actual data. The payload data format is not specified, although JSON is common.

🔎 The most recent version of the MQTT standard (MQTT 5) supports content type metadata.

When sending a MQTT message, a Quality of Service (QoS) parameter needs to be defined, indicating delivery guarantees:

  • at most once
  • at least once
  • exactly once.

For the purpose of this exercise it does not matter which quality you choose.

MQTT topics

MQTT topics are UTF-8 strings representing a hierarchy, with individual levels separated by a / slash character. A leading slash is supported but not recommended. Some example topics are:

home/garage/temperature
beacons/bicycle/position
home/alarm/enable
home/front door/lock

Here a sensor would periodically publish the garage temperature which then gets broadcast to every subscriber, just as the bicycle beacon publishes its GPS coordinates. The alarm and lock topics serve as a command sink for specific devices. However, nothing prevents additional subscribers from listening in on these commands, which might provide useful for auditing purposes.

🔎 Topics starting with $ are reserved for statistics internal to the broker. Typically the topic will begin with $SYS. Clients cannot publish to these topics.

❗️Since all workshop participants will be sharing the same MQTT server, some measures are required to prevent crosstalk between different projects. The exercise skeleton will generate a unique, random ID (in the UUID v4 format) for each repository checkout. You can also manually generate your own online. Your UUID should be used as leading part of the message topics sent between computer and board, roughly resembling this pattern:

6188eec9-6d3a-4eac-996f-ac4ab13f312d/sensor_data/temperature
6188eec9-6d3a-4eac-996f-ac4ab13f312d/command/board_led

Subscribing to topics

A client sends several subscribe messages to indicate they're interested in receiving certain topics. Wildcards are optionally supported, both for a single hierarchy level and as a catch-all:

  • home/garage/temperature - subscribes only to this specific topic
  • home/# - the hash character is used as multi-level wildcard and thus subscribes to every topic starting with home/ - home/garage/temperature, home/front door/lock and home/alarm/enable would all match, but beacons/bicycle/position won't. The multi-level wildcard must be placed at the end of a subscription string.
  • home/+/temperature - the plus character serves as single-level wildcard to subscribe to home/garage/temperature, home/cellar/temperature, etc.