Skip to content
Stand with Ukraine flag

Integration with ThingsBoard

This guide shows how to connect ThingsBoard to TBMQ using the ThingsBoard MQTT Integration, so that data published by MQTT clients to TBMQ becomes device telemetry in ThingsBoard.

The ThingsBoard MQTT Integration acts as an ordinary MQTT client: it connects to TBMQ, subscribes to a topic filter, and converts each received message into telemetry and attribute updates using an uplink data converter. This guide configures it as an APPLICATION client with a persistent session, so messages published while ThingsBoard is offline are queued by TBMQ and delivered on reconnect.

  • A running ThingsBoard PE instance, or a ThingsBoard Cloud tenant with integrations enabled
  • A running TBMQ instance reachable from ThingsBoard
  • The mosquitto_pub MQTT client, to publish a test message

Four settings decide whether ThingsBoard receives every message or only the ones published while it happens to be connected. Three of them live on the ThingsBoard side, one on the TBMQ side:

Setting Configured in Value used here Why it matters
Client type TBMQ client credentials Application TBMQ creates a dedicated Kafka topic, tbmq.msg.app.$CLIENT_ID, for each persistent APPLICATION client and delivers from it with a per-client consumer. This is the high-throughput path intended for a backend consumer such as ThingsBoard.
Clean session ThingsBoard integration → Advanced settings off Makes the MQTT session persistent, so TBMQ retains the subscription and queues matching messages while ThingsBoard is disconnected. Left on (the ThingsBoard default), nothing is queued and offline messages are lost.
Client ID ThingsBoard integration → Advanced settings fixed, e.g. tbpeintegration The per-client Kafka topic is derived from the client ID. With the ThingsBoard default of an auto-generated ID, every reconnect produces a different ID, so the integration resumes a brand-new empty session instead of the one holding its queued messages.
QoS ThingsBoard integration → topic filter 1 or 2 Persistence applies only at QoS 1 and above. If either the subscriber or the publisher uses QoS 0, the message takes the non-persistent path and is dropped when the subscriber is offline.

Create the client credentials that ThingsBoard will use to connect.

These credentials use Basic authentication, which is the one authentication provider TBMQ enables out of the box. If it was turned off on your instance, re-enable it on the Authentication → Providers page before continuing.

  1. In the TBMQ UI, go to Authentication → Credentials and click Add (+).
  2. Enter a credential name and select Application as the client type.
  3. Select Basic as the credentials type.
  4. Enter a Username and Password (e.g., tb-pe / secret).
  5. Click Add.

The uplink converter parses each incoming MQTT message — payload plus metadata such as the topic it arrived on — into the device name, attributes, and telemetry that ThingsBoard stores.

In ThingsBoard, go to Integrations center → Data converters and add a converter. Name it TBMQ Uplink Converter, select type Uplink, and paste the decoder script below.

The script takes the device name from the fourth topic segment, so a message on tb/mqtt-integration-tutorial/sensors/SN-001/temperature is attributed to device SN-001.

/** Decoder **/
// decode payload to string
var payloadStr = decodeToString(payload);
var data = JSON.parse(payloadStr);
var deviceName = metadata.topic.split("/")[3];
var deviceType = 'sensor';
// Result object with device attributes/telemetry data
var result = {
deviceName: deviceName,
deviceType: deviceType,
attributes: {
integrationName: metadata['integrationName'],
},
telemetry: {
temperature: data.value,
}
};
/** Helper functions 'decodeToString' and 'decodeToJson' are already built-in **/
return result;
  1. Go to Integrations center → Integrations and click + Add integration. Set Integration type to MQTT, name it MQTT Integration, and continue to the next step.
  2. Select the TBMQ Uplink Converter you just created.
  3. Leave the Downlink data converter field empty and click Skip — a downlink converter is only needed to send commands back to devices, which is covered in Downlink and RPC.
  4. Specify the TBMQ Host and Port (1883 for the default TBMQ TCP listener). Select Basic credentials and enter the username and password created above. Add the topic filter tb/mqtt-integration-tutorial/sensors/+/temperature and set QoS to 1 or 2.
  5. Open Advanced settings. Uncheck Clean session and set Client ID to tbpeintegration.
  6. (Optional) Click Check connection to verify TBMQ is reachable. Click Add to create the integration.

Once the integration is created, open the Sessions page in the TBMQ UI. A session for client ID tbpeintegration should be listed with status Connected, client type APPLICATION, and marked as persistent.

Because the client is a persistent APPLICATION client, TBMQ has also created its dedicated Kafka topic. Open Kafka management → Topics and look for tbmq.msg.app.tbpeintegration, listed with its partitions, replicas, and size.

Publish a temperature reading as a device would. Replace the host and credentials with your own if you changed them:

Terminal window
mosquitto_pub -h localhost -p 1883 -q 1 \
-t "tb/mqtt-integration-tutorial/sensors/SN-001/temperature" \
-m '{"value":25.1}' -u "tb-pe" -P "secret"

The -q 1 is deliberate: at QoS 0 the message would skip the persistent path, so it would be lost rather than queued if ThingsBoard happened to be disconnected.

In ThingsBoard, open the MQTT integration and go to its Events tab. An uplink event should show the message as received and converted.

Then go to Entities → Devices. The integration provisions a device named SN-001 on first message. Open it and switch to the Latest telemetry tab — the temperature key should hold 25.1.

To confirm the offline queueing actually works, disable the integration in ThingsBoard, publish a few more messages at QoS 1, then re-enable it. The messages queued in TBMQ are delivered as soon as the integration reconnects.

This guide covers uplink only. To send commands from ThingsBoard back to devices through TBMQ, add a downlink data converter to the integration: ThingsBoard encodes the Rule Engine message and publishes it to TBMQ, where the device is subscribed. The downlink topic comes from the integration’s Downlink topic pattern setting, which resolves metadata.topic from the converter output.

The encoder API and the RPC walkthroughs live in the ThingsBoard documentation:

Symptom Likely cause What to check
Integration status is Disconnected, no session in TBMQ TBMQ is not reachable, or the connection was refused Confirm the host and port, and that a firewall or security group is not blocking 1883. Use Check connection in the integration settings.
Connection refused and the client appears under Authentication → Unauthorized clients in TBMQ Wrong username or password, or Basic authentication is disabled The Unauthorized clients table records the reason for each rejected CONNECT. Verify the credentials and that the Basic provider is enabled.
Session connects but is not persistent, and TBMQ warns about it Clean session is still enabled on the integration Uncheck Clean session in the integration’s Advanced settings.
Live messages arrive, but nothing published while ThingsBoard was down QoS 0 somewhere in the chain, or a non-persistent session Both the publisher and the integration’s topic filter must use QoS 1 or 2. See Quality of service.
A new Kafka topic appears after each reconnect, queued messages are never delivered Client ID is left empty, so ThingsBoard generates a new one per connection Set a fixed Client ID in Advanced settings. Messages queued under a previous ID stay in that session’s topic until the session is cleared.
Connection rejected even though credentials are correct The broker’s APPLICATION client limit is reached MQTT_APPLICATION_CLIENTS_LIMIT caps the total number of persistent APPLICATION clients and external system integrations. It defaults to 0, which disables the limit.
Events appear in TBMQ but the converter produces no telemetry The payload does not match the decoder script Open the converter’s Events tab in ThingsBoard to see the raw payload and the conversion output. The sample script expects JSON shaped like {"value":25.1} and a five-segment topic.