Repository navigation
RaftMQTTManagerSysMod
Built-in SysMod (registered as
MQTTMan) that connects to an MQTT broker and exposes per-topic Comms Channels. Messages received on inbound (subscribed) topics are handled as REST API commands, like commands arriving over BLE or HTTP; messages sent on an outbound topic's channel are published to the broker.Source:
RaftSysMods/components/MQTTManager/and the client inRaftCore/components/core/MQTT/
- Single-connection MQTT 3.1.1 client (
RaftMQTTClient) over a plain TCP socket, with auto-reconnect, keep-alive and optional username/password. - Publishes at QoS 0 or 1 (QoS 2 is sent as QoS 1), with optional retain. QoS 1 publishes are tracked until the broker acknowledges them (PUBACK).
- Subscribes to inbound topics (filters may use
+and#) and passes received messages to the command handler. - One comms channel per topic, named after the topic's
name. - Optional StatePublisher subscriptions per outbound topic (
pubSources), so data is published to MQTT without a client having to subscribe.
| Top-level key | Type | Default | Meaning |
|---|---|---|---|
enable |
bool | false |
Master switch |
brokerHostname |
string | "" |
MQTT broker hostname (resolved by DNS) or IP address |
brokerPort |
int | 1883 |
Broker port |
clientID |
string | "" |
Prefix of the MQTT client identifier, to which the system unique string is appended. When absent or "" the SystemName is the prefix. (In RaftSysMods 1.29.0 and earlier an absent key used the unique string as the prefix, so it appeared twice.) |
username |
string | "" |
Username sent in CONNECT. Not sent if empty. |
password |
string | "" |
Password sent in CONNECT. Only sent when username is also set. |
keepAliveSecs |
int | 30 |
Keep-alive interval sent to the broker; 0 or values over 65535 use the default. A PINGREQ is sent every keepAliveSecs / 2. |
topics |
array | [] |
Per-topic configuration array |
| Topic key | Type | Default | Meaning |
|---|---|---|---|
name |
string |
topic<n> (1-based) |
Name of the topic's comms channel (and the name used internally to refer to the topic) |
inbound |
bool | true |
true: subscribe to path; messages received are handled as commands. false: publish-only. |
path |
string | "" |
MQTT topic. For an inbound topic this is a topic filter and may contain + and #. {uid} is replaced by the system unique string, so devices sharing one config get their own topics. An outbound topic with an empty path can't publish. |
qos |
int | 0 |
QoS for publishes (outbound) or requested in the subscription (inbound). 0 or 1; higher values are treated as 1. |
retain |
bool | false |
Set the retain flag on publishes (outbound only) |
pubSources |
array | none | Outbound only: StatePublisher subscriptions created at startup for this topic's channel - see below |
All channels use the RICJSON codec.
Each inbound topic gets its own channel. A message received on a subscribed topic is matched against the inbound topics' filters in config order; the first match gets it and it is passed to CommsCore on that topic's channel, where the RICJSON codec treats it as a JSON command frame and runs it through the REST API: {"cmdName":"x","a":1} runs x?a=1.
- A message received at QoS 1 is acknowledged (PUBACK) to the broker.
- There is no reply path: the REST response is discarded, and anything sent on an inbound topic's channel is dropped. Results a remote client needs must be published on an outbound topic.
- An inbound packet longer than 1024 bytes (or malformed) closes the connection, which is then re-established.
A message sent on an outbound topic's channel is published to the topic's path at its qos and retain.
- While not connected to the broker the channel reports no connection and messages are discarded.
- While 8 QoS 1 publishes are awaiting PUBACK, further messages wait in the channel's queue.
- A QoS 1 publish not acknowledged within 10 s closes the connection. Publishes still unacknowledged when the connection closes (for any reason) are counted as lost; they are not resent.
A SysMod can tell when its QoS 1 messages have reached the broker from the named values below (e.g. wait for pubInFlight to reach 0 and pubAcked to have increased before entering deep sleep).
In postSetup(), each entry in an outbound topic's pubSources creates a StatePublisher subscription for that topic's channel (with createSubscription):
| Key | Default | Meaning |
|---|---|---|
pubTopic |
(required) | StatePublisher topic, e.g. devjson
|
rateHz |
1.0 |
Publish rate |
trigger |
"timeorchange" |
time, change or timeorchange
|
minMs |
50 |
Minimum time between messages |
These subscriptions are kept while the broker isn't connected (unlike a client's subscription, which StatePublisher removes when its channel has no connection) and publish once it connects - see Subscription Mechanism. (RaftSysMods versions after 1.29.0; earlier, a publish made before the broker connected removed them.)
- Connection attempts start once the network is up and are retried every 5 s after a failure. While an attempt fails at once for lack of network (no address for the broker yet, or
connect()failing immediately with no route) it is retried every 250 ms, so the connection is made as soon as the network comes up (e.g. on wake from deep sleep). - The broker hostname is looked up with
DNSResolver. The first lookup isn't delayed and a lookup isn't attempted (or counted as failed) until the device has an IP address; after a failed lookup the next is made 5 s later. A resolved address is kept. - Timeouts that close the connection: socket connect 5 s, CONNACK 5 s, PINGRESP 10 s, PUBACK 10 s. A CONNACK refusing the connection (e.g. code 4, bad username or password; 5, not authorised) is logged and the connection retried.
- Inbound topics are subscribed each time the connection is made (clean session).
getStatusJSON() (e.g. sysmodinfo/MQTTMan) returns:
{"conn":1,"inFlight":0,"acked":42,"lost":0,"rx":3}The same values are available through the named-value mechanism (getNamedValue("MQTTMan", ...)):
| Name | Status key | Meaning |
|---|---|---|
connected |
conn |
1 when connected to the broker, else 0
|
pubInFlight |
inFlight |
QoS 1 messages published and not yet acknowledged |
pubAcked |
acked |
QoS 1 messages acknowledged by the broker (count since startup) |
pubLost |
lost |
QoS 1 messages not acknowledged before the connection closed (count since startup) |
rxMsgs |
rx |
Messages received on inbound topics (count since startup) |
None — MQTTManager is purely a transport.
- Comms Channels
- StatePublisher SysMod
- Network Manager SysMod — required for an active network connection
Getting Started
- Quick Start
- Architecture at a Glance
- Writing Your First SysMod
- Adding a Comms Channel
- Adding an I2C Device Type
Scaffolding & Building
- Raft CLI
- Web Apps (Device Types, Flasher)
- SysTypes
- Top-Level SysType
- Build Process
- WebUI Build Pipeline
- File System
- Partitions & Flash
- Local Dev Libraries
- Library Developer Guide
Architecture
Built-in SysMods
- NetworkManager
- WiFi Troubleshooting
- BLEManager
- WebServer
- MQTTManager
- SerialConsole
- CommandSerial
- CommandSocket
- CommandFile
- FileManager
- LogManager
- ESPOTAUpdate
- StatePublisher
- Remote Logging
- Data Source Registration
Comms & Protocols
- Stack Overview
- Comms Channels
- ProtocolExchange
- RICREST Protocol
- Real-Time Streams
- Adding REST Endpoints
- Built-in REST Endpoints
- File Download (OKTO)
- OTA Update Flow
Devices & Buses
- DeviceManager
- Device Manager REST API
- Device Factory & Classes
- Device Type Records
- Adding an I2C Device Type
- Device Data Publishing
- Data Logger
- I2C Bus
- I2C Device Scanning
- I2C ID & Polling
- MotorControl Overview
- MotorControl Config
- MotorControl Commands
- Camera
ROS 2
Helpers
Reference