MQTT Guide

Subscribe to topics, publish data, and run an embedded broker.

Overview

ControlBird's MQTT integration runs in two modes. In client mode it connects to an external MQTT broker, subscribes to topics, and maps incoming payloads directly into entity fields, it can also publish field values back out to topics. In broker mode it hosts an embedded MQTT broker so devices and other systems can publish and subscribe against ControlBird itself. Both modes are configured entirely through the Device Manager app, no configuration files are required.

The integration supports MQTT 3.1.1 and 5.0, topic wildcards, QoS levels 0/1/2, retained messages, Last Will Testament, TLS, and three payload formats (String, JSON, and Binary). Inbound JSON payloads can be reduced to a single value with a JSONPath expression and coerced to the target field's type.

New to device configuration?

If this is your first integration, start with walkthrough step 7: Connect a Device for a hands-on introduction to controllers and mappers, then return here for MQTT specifics.

Architecture

MQTT follows ControlBird's standard controller/mapper pattern. A controller owns the connection (or the listener, in broker mode) and is configured through an endpoint that holds the connection settings. In client mode you attach mappers to the controller, and each mapper binds one topic to one entity field.

Both modes appear in the Device Manager under the name MQTT, and you choose the Client or Server role when you create the controller. In a multi-node deployment the controllers coordinate so that only one node runs the active connection or broker at a time, which means traffic is never doubled up and failover is automatic.

The broker does not use mappers

In broker mode ControlBird is a pure message broker. Clients connect to it over standard MQTT and publish/subscribe directly, there is no entity bridging on the broker side. Add mappers to a client-mode controller when you want topics mapped to entity fields.

Client mode: connecting to a broker

  1. Open the Device Manager app in the ControlBird control plane.
  2. Create a new protocol controller and select MQTT in the Client role.
  3. Configure the endpoint with the broker Host and Port (default 1883 for plain, 8883 for TLS).
  4. Optionally set Username and Password for authentication.
  5. Set client behavior: ClientId, CleanSession (default true), and KeepAliveSeconds (default 60).
  6. Add one or more mappers, one per topic pattern.

Client endpoint fields

FieldDescriptionDefault
HostBroker hostname or IP address.none
PortBroker TCP port.1883 / 8883 (TLS)
ClientIdMQTT client identifier (a per-controller/node suffix is appended automatically).auto
Username / PasswordOptional credentials.none
CleanSessionStart a fresh session on each connect.true
KeepAliveSecondsHeartbeat interval.60
TlsEnabledEnable MQTTS/TLS.false
CertificateCertificate entity supplying CA (and optional client cert/key).none
LoggingEnable TX/RX packet logging.off
MaxLogFiles / MaxLogSizeMbLog rotation limits.n/a
MinRetryBackoffMs / MaxRetryBackoffMsReconnect backoff bounds.1000 / 60000

ClientId is unique per node

ControlBird derives a distinct effective client identifier for each node, so leaving ClientId empty (or setting one) still produces a unique value per node. This prevents the broker from evicting and re-admitting connections in a reconnection storm when multiple ControlBird nodes share a configuration.

Mappers: binding topics to fields

Each mapper connects a single MQTT topic to one entity field. The SourcePath is the topic pattern, TargetEntity and TargetField identify where values are read or written, and the remaining fields control direction, payload handling, and MQTT publish options.

FieldValuesPurpose
SourcePathtopic stringMQTT topic pattern (supports + and # wildcards).
TargetEntity / TargetFieldentity / fieldThe Store field that receives values (inbound) or supplies them (outbound).
DirectionRead, Write, ReadWriteInbound only, outbound only, or bidirectional.
ReadModeSubscribe, PollSubscribe (event-driven, default) or Poll on an interval.
QoSAtMostOnce, AtLeastOnce, ExactlyOnceQuality of service (default AtLeastOnce).
RetainboolPublish as a retained message (default false).
PayloadFormatString, Json, BinaryHow payload bytes are interpreted.
JsonPathJSONPath stringExtract a single value from a JSON payload (e.g. $.brightness).
ByteOrderBigEndian, LittleEndianByte order for Binary payloads.
PollIntervalMsmillisecondsInterval used when ReadMode=Poll.
DisabledboolDisable the mapper without deleting it.

Topic wildcards

MQTT topics are hierarchical, separated by /. Two wildcards are supported in subscription patterns:

  • + matches exactly one topic level, e.g. sensors/+/value.
  • # matches the remaining levels and must be the last character, e.g. house/#.

Payload formats

FormatBehavior
StringRaw text. The payload is stored as-is.
JsonParsed as a JSON object. An optional JsonPath extracts one value; without it the whole object is used.
BinaryRaw bytes parsed using the selected ByteOrder (BigEndian or LittleEndian).

Type coercion

Extracted JSON values are automatically converted to the target field's type, Bool, Int, Float, String, or Choice. A JSON boolean mapped onto a Choice field becomes 0/1, and a JSON string mapped onto a Choice field is treated as a numeric index when it parses as a number, otherwise it is preserved as a String so the choice label can be resolved (for example "ON" / "OFF").

Examples

Subscribe to a plain-text temperature topic:

SourcePath:    sensors/temperature
PayloadFormat: String
Direction:     Read

Extract a single value from a JSON payload via JSONPath:

SourcePath:    zigbee/light/brightness
PayloadFormat: Json
JsonPath:      $.brightness
Direction:     Read

Publish a setpoint as a retained message at QoS 1:

SourcePath: control/setpoint
Direction:  Write
QoS:        AtLeastOnce
Retain:     true

Subscribe with wildcards across many sensors or an entire subtree:

SourcePath: sensors/+/value   PayloadFormat: String  Direction: Read
SourcePath: house/#           PayloadFormat: Json    Direction: Read

Bidirectional state mirroring (subscribe and publish on one topic):

SourcePath:    devices/light/state
Direction:     ReadWrite
PayloadFormat: String

Parse a binary payload with an explicit byte order:

SourcePath:    modbus/holding/registers
PayloadFormat: Binary
ByteOrder:     BigEndian
Direction:     Read

Resolve a Choice field from a JSON string (e.g. "ON" / "OFF"):

SourcePath:    switch/status
PayloadFormat: Json
JsonPath:      $.state
Direction:     Read

Security and reliability

TLS / MQTTS

Set TlsEnabled on the endpoint and attach a Certificate entity. The CA certificate is required to validate the broker; a client certificate and key are optional and enable mutual TLS. TLS connections typically use port 8883. See the certificates guide for managing certificate material.

Quality of service

QoSNameGuarantee
0AtMostOnceFire and forget, no delivery guarantee.
1AtLeastOnceDelivered at least once (default), duplicates possible.
2ExactlyOnceDelivered exactly once via a four-way handshake.

Retained messages and Last Will

Publishing with Retain=true stores the last message on the broker so new subscribers receive it immediately on subscription. Per the MQTT 3.1.1 specification, retained messages are still delivered on reconnect even when CleanSession=true. The client also supports a Last Will Testament: a will message the broker publishes automatically if the client disconnects ungracefully.

Reconnect behavior

On connection failure the client retries with exponential backoff bounded by MinRetryBackoffMs (default 1000) and MaxRetryBackoffMs (default 60000). The keep-alive heartbeat (default 60 seconds) lets the broker detect a dead client.

Broker mode: hosting an embedded broker

Create a controller in the Server role and configure its endpoint. Bind to 0.0.0.0 to accept connections on all interfaces, choose a listen Port (default 1883), and set resource limits. Enable TLS by setting TlsEnabled and attaching a Certificate.

FieldDescriptionDefault
HostBind address (e.g. 0.0.0.0).none
PortListen port.1883
MaxConnectionsMaximum concurrent client connections.100
MaxQueuedMessagesMaximum queued messages per client.256
KeepAliveSecondsKeep-alive interval for connected clients.60
TlsEnabled / CertificateEnable TLS and supply certificate material.false
Logging / MaxLogFiles / MaxLogSizeMbPacket logging and rotation.None
MinRetryBackoffMs / MaxRetryBackoffMsBackoff bounds.1000 / 60000
Host:              0.0.0.0
Port:              1883
MaxConnections:    1000
MaxQueuedMessages: 512

Limitations

  • The embedded broker does not bridge entities, it is a pure pub/sub broker with no mappers.
  • Publishing to topics beginning with $ (reserved system topics) is not allowed; system topics can still be subscribed to and read.
  • Topic length is capped at 65535 bytes (the MQTT specification limit).
  • Wildcard subscriptions apply to client read operations; the broker does not subscribe to external clients on your behalf.
  • JSONPath extraction returns only the first match.
  • Binary payloads require PayloadFormat=Binary explicitly, format is never auto-detected because binary and text are ambiguous.

Observability

Set Logging=Enabled on either endpoint to record all MQTT TX/RX packets, with rotation governed by MaxLogFiles and MaxLogSizeMb. In a multi-node deployment, only one node holds the active connection or broker at a time, and the role moves automatically if that node becomes unavailable. For broader device setup, return to step 7: Connect a Device.