doc/help/Drivers-MQTT.md
The MQTT driver lets a project subscribe to one or more broker topics and feed each received message into the regular frame pipeline as if the bytes had arrived over a serial port or TCP socket. It is the right transport when the data already lives on an MQTT broker, or when several Serial Studio instances need to consume the same telemetry without each one talking to the device directly.
Unlike UART, BLE, or CAN Bus, MQTT does not present a physical bus to Serial Studio: it runs over TCP and through a broker. The driver still slots into the same per-source architecture as every other transport, so a single project can mix MQTT subscribers with serial or network sources side by side.
If you have never used MQTT before, read MQTT Topics & Semantics first; this page assumes the protocol vocabulary.
The broker maintains a routing table. Whenever a publisher posts to a topic, the broker forwards a copy of the payload to every client whose topic filter matches. The driver opens one connection per project source, registers its topic filter at QoS 0, and from then on every matching payload triggers a messageReceived callback. The bytes are then handed to the FrameReader exactly the same way bytes off a UART would be. Empty payloads and messages that do not match the filter are discarded before they reach the FrameReader.
flowchart LR
Dev1["Device A
publishes to factory/A"] --> Broker
Dev2["Device B
publishes to factory/B"] --> Broker
Broker -- "filter: factory/+" --> SS["Serial Studio
MQTT source"]
SS --> FR["FrameReader"]
FR --> Dash["Dashboard"]
Two consequences shape how you configure the driver:
sensors/+/temp accepts payloads from many publishers on a single source, but Serial Studio cannot tell them apart at the bytes level. If the dashboard has to distinguish them, encode the publisher's identity inside the payload (an ID column in CSV, a device field in JSON) or use one source per publisher.The driver wraps Qt's QMqttClient and lives on the main thread. Per-source state — broker connection, SSL configuration, topic subscription — is kept on the driver instance itself, so each MQTT source in the project has its own independent broker session. Adding a second MQTT subscriber to the same project does not share anything with the first.
When you select MQTT Subscriber as the Bus Type for a source, the project editor exposes these fields under Connection Settings:
| Field | Controls |
|---|---|
| Hostname | Broker address (IP or hostname). Default 127.0.0.1. |
| Port | Broker TCP port. Default 1883. Set 8883 yourself for TLS brokers; toggling TLS does not change the port. |
| Topic Filter | Topic to subscribe to. Supports + (one level) and # (rest) wildcards. Required; the source will not open without one. |
| Client ID | Identifier sent on CONNECT. Auto-generated (random 16 characters) when empty. |
| Username / Password | Optional broker authentication. |
| MQTT Version | MQTT 3.1, 3.1.1, or 5.0. Default MQTT 5.0. |
| Clean Session | Discard any persisted session state on CONNECT. Default on. |
| Keep Alive (s) | Seconds between PING packets when idle. Default 60; 0 disables the mechanism. |
| Auto Keep Alive | Let the client send keep-alive pings automatically. Default on. |
| SSL/TLS Enabled | Master TLS toggle. Off by default; when on, the three fields below appear. |
| SSL Protocol | TLS protocol family: TLS 1.2, TLS 1.3, TLS 1.3 or Later, DTLS 1.2 or Later, Any Protocol, or Secure Protocols Only (default). |
| Peer Verify Mode | None, Query Peer, Verify Peer, or Auto Verify Peer (default). |
| Peer Verify Depth | Maximum certificate chain length accepted. Default 10; 0 = unlimited. |
The main window's Setup pane shows the same configuration with two extras: a Regenerate button beside Client ID, and a CA Certificates row whose Load From Folder… button imports PEM certificates for self-signed brokers. The Setup pane omits Auto Keep Alive and shortens a few labels (Version, Use SSL/TLS, Peer Verify, Verify Depth); the fields are otherwise the same.
The same fields are scriptable through the API commands project.mqtt.subscriber.getConfig, project.mqtt.subscriber.setConfig, and project.mqtt.subscriber.getStatus. setConfig patches only the keys you pass and schedules a reconnect when the driver is connected.
For step-by-step instructions, see the Protocol Setup Guides, MQTT section.
The driver is transport-only. It does not decode the payload; it hands the bytes to the project's frame parser:
23.5,48.2,1013.25\n). Each MQTT message should be a complete line.The frame-detection rules on the source still apply. If the publisher embeds start/end delimiters inside the payload, configure them; otherwise leave No Delimiters selected so each MQTT message becomes one frame.
The project editor treats MQTT subscribers the same as any other bus type, so a project with two ESP32 fleets on different brokers — one local, one cloud — is a normal multi-source project:
Two MQTT sources targeting the same broker but different topic filters are fine: the driver opens two independent CONNECT sessions and registers one subscription each. Give each source its own Client ID; brokers drop the older connection when two clients share one. There is no special "shared broker" optimization, and there does not need to be — QMqttClient is cheap to instance.
For any broker reachable from outside the local network, use TLS:
8883 (the standard MQTT-over-TLS port).Verify Peer (or the default Auto Verify Peer) for production. Drop to None only when testing against a self-signed broker certificate and never against a public broker.The TLS configuration is per-source, so two MQTT subscribers in the same project can use different brokers with different trust roots without interfering with each other.
Sensors/Temp is not the same as sensors/temp. Run mosquitto_sub -t '#' -v against the broker to see what is being published. If the publisher uses a deeper or shallower level structure than expected, the filter will silently miss everything.your/topic/# and watch what the broker delivers on connect.test.mosquitto.org round-trip through the public Internet; expect tens-to-hundreds of milliseconds of jitter. For low-latency telemetry, run Mosquitto on the same LAN.sensors/+/temp filter that catches both room1 (CSV) and room2 (JSON) cannot be parsed by a single frame parser cleanly. Either standardise the payload format or split into two sources with one filter each.