Back to Serial Studio

MQTT Driver (Subscriber, Pro)

doc/help/Drivers-MQTT.md

4.0.110.6 KB
Original Source

MQTT Driver (Subscriber, Pro)

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.

What an MQTT subscriber sees

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.

mermaid
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:

  • One MQTT message is one chunk of bytes. The broker preserves payload boundaries; a 200-byte publish arrives as a single 200-byte read. The same frame-detection rules still apply (start/end delimiters, fixed length, no delimiter), but in practice each MQTT message usually already contains exactly one frame, so No Delimiters is a common choice.
  • Wildcards multiplex publishers. A filter like 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.

How Serial Studio uses it

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:

FieldControls
HostnameBroker address (IP or hostname). Default 127.0.0.1.
PortBroker TCP port. Default 1883. Set 8883 yourself for TLS brokers; toggling TLS does not change the port.
Topic FilterTopic to subscribe to. Supports + (one level) and # (rest) wildcards. Required; the source will not open without one.
Client IDIdentifier sent on CONNECT. Auto-generated (random 16 characters) when empty.
Username / PasswordOptional broker authentication.
MQTT VersionMQTT 3.1, 3.1.1, or 5.0. Default MQTT 5.0.
Clean SessionDiscard 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 AliveLet the client send keep-alive pings automatically. Default on.
SSL/TLS EnabledMaster TLS toggle. Off by default; when on, the three fields below appear.
SSL ProtocolTLS 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 ModeNone, Query Peer, Verify Peer, or Auto Verify Peer (default).
Peer Verify DepthMaximum 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.

Payload expectations

The driver is transport-only. It does not decode the payload; it hands the bytes to the project's frame parser:

  • Quick Plot mode expects comma-separated numeric values (23.5,48.2,1013.25\n). Each MQTT message should be a complete line.
  • Project File mode expects whatever the project's JavaScript or Lua parser is written to accept. JSON, CSV, fixed-byte structs, and binary protocols all work the same as on any other driver.
  • Console Only mode displays the payload as-is in the terminal.

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.

Multiple MQTT subscribers in one project

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:

  1. Add a source. In the project editor, add a new source and set its Bus Type to MQTT Subscriber.
  2. Point it at the broker. Fill in hostname, port, credentials, and topic filter for the first fleet.
  3. Repeat. Add a second source, set Bus Type to MQTT Subscriber again, and configure it for the second broker (or a different topic on the same broker).
  4. Map datasets per source. Each source has its own frame parser; the Frame builder routes parsed frames to the dashboard with the source ID preserved, exactly as for serial+network mixes.

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.

TLS / SSL

For any broker reachable from outside the local network, use TLS:

  • Set the port to 8883 (the standard MQTT-over-TLS port).
  • Enable SSL/TLS.
  • Keep Peer Verify at 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.
  • If the broker uses a private CA, click Load From Folder… under CA Certificates in the Setup pane and pick the directory containing the PEM chain.

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.

Common pitfalls

  • Subscribed but no data. Topics are case-sensitive: 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.
  • Connected but stale data shows up. A retained message on a topic above the live stream can mask new publishes for a fresh subscriber. Subscribe to your/topic/# and watch what the broker delivers on connect.
  • Client ID conflict. Brokers enforce unique client IDs. Two Serial Studio instances (or two sources within the same instance, by accident) sharing one client ID make the broker kick the older connection. Click Regenerate in the Setup pane to pick a fresh ID per source.
  • TLS handshake fails. A broker requiring TLS will reject the connection if the certificate chain is not trusted. Self-signed brokers need the CA imported explicitly via the CA Certificates field's Load From Folder… button.
  • Public-broker latency. Free public brokers like 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.
  • High publish rate stalls the dashboard. MQTT is not a streaming protocol. At thousands of messages per second, broker queues back up and the dashboard sees bursts and pauses. When per-reading granularity is not required, batch multiple readings into a single MQTT message and parse them frame-by-frame inside the project's frame parser.
  • One filter, many publishers, mixed payload formats. A 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.

Further reading

See also