Skip to content
Stand with Ukraine flag

One-way RPC over MQTT

A refrigeration controller (device SN-001) publishes temperature readings to the broker and subscribes to a command topic. An operator sets the target temperature on a dashboard Knob Control widget, and ThingsBoard sends a one-way RPC command to the device over MQTT — no device acknowledgment is expected.

  • ThingsBoard Professional Edition instance — ThingsBoard Cloud;
  • MQTT broker accessible by ThingsBoard: broker.hivemq.com (port 1883);
  • mosquitto_pub and mosquitto_sub MQTT clients to send and receive messages.

The refrigeration controller:

  • publishes temperature readings to tb/mqtt-integration-tutorial/fridge/+/temperature
  • subscribes to tb/mqtt-integration-tutorial/fridge/+/rx/set-temperature for incoming RPC commands.
  1. Go to Integrations center ⇾ Integrations and click + Add integration.
  2. Basic settings:
    • Set Integration type to MQTT and enter a name (e.g. “MQTT integration”).
    • Enable integration and Allow create devices or assets are on by default.
    • Click Next.
  1. Uplink data converter. The wizard creates the converter inline.
    • The name is auto-generated.
    • Paste the decoder script below and click Next.
/** Decoder **/
// decode payload to string
var payloadStr = decodeToString(payload);
var data = JSON.parse(payloadStr);
var deviceName = metadata.topic.split("/")[3];
// decode payload to JSON
var deviceType = 'sensor';
// Result object with device attributes/telemetry data
var result = {
deviceName: deviceName,
deviceType: deviceType,
attributes: {
integrationName: metadata['integrationName'],
},
telemetry: {
temperature: data.temperature,
}
};
/** Helper functions 'decodeToString' and 'decodeToJson' are already built-in **/
return result;
  1. Downlink data converter:
    • Click Skip — the downlink converter will be added in Step 5.
  1. Connection:
    • Set Host to broker.hivemq.com
    • Port to 1883
    • Credentials type to Anonymous
    • Add a topic filter tb/mqtt-integration-tutorial/fridge/+/temperature with QoS 0 — At most once (+ matches the device name segment)
    In Advanced settings:
    • Uncheck Clean session
    • Leave Downlink topic pattern at ${topic} — the integration will publish to metadata.topic from the downlink converter output
  2. Click Check connection — a confirmation step appears showing Connected.
  3. Click Add to complete the integration setup.

Simulate a refrigeration controller device publishing a test temperature reading to the broker:

Terminal window
mosquitto_pub -h broker.hivemq.com -p 1883 -t "tb/mqtt-integration-tutorial/fridge/SN-001/temperature" -m '{"temperature":3}'

Go to Entities ⇾ Devices. The SN-001 device is created automatically on the first uplink message. Click it and open the Latest telemetry tab to verify that temperature = 3 has been published.

Add a control widget to the dashboard that allows the operator to change the target temperature.

  1. Go to Dashboards and create a new dashboard named MQTT RPC.
  2. Click + Add new widget.
  3. Select Control widgets → Knob Control.
  4. On the Data tab, set Target device to SN-001.
  5. On the Appearance tab, set:
    • minimum value to -10
    • maximum value to 6
    • number of decimal places: 0
    • fallback initial value to 2.
  6. Click Add.
  7. Save the dashboard.

For example, the operator sets the value to 4. This value will be sent as an RPC command.

Before adding the downlink converter, verify that knob turns generate RPC messages by inspecting the Rule Engine event log.

Go to Rule Chains and open the Root Rule Chain. Open the message type switch node and enable Debug mode.

Turn the knob a few times on the dashboard.

In the message type switch node on the Events tab you should then see incoming messages with the message type RPC_CALL_FROM_SERVER_TO_DEVICE and relation type RPC Request to Device. You can check out what data and metadata was sent by the Knob Control to the Rule Engine.

The downlink converter must transform the RPC request into:

  • the MQTT topic expected by the device;
  • the JSON payload with the target temperature.
  1. Go to Integrations center ⇾ Integrations and open the MQTT integration.
  2. Click Toggle edit mode.
  3. In the Downlink data converter field, click Create new.
  4. Name it MQTT Downlink Converter.
  5. Paste the encoder script.

    /** Encoder **/
    var value = parseFloat(msg.params);
    var data = {targetTemperature: value};
    var result = {
    contentType: "JSON",
    data: JSON.stringify(data),
    metadata: {
    topic: 'tb/mqtt-integration-tutorial/fridge/' + metadata['deviceName'] + '/rx/set-temperature'
    }
    };
    return result;
  6. Click Add.
  7. Click Apply changes.

Step 6. Route RPC messages in the Rule Chain

Section titled “Step 6. Route RPC messages in the Rule Chain”

When the widget value changes, ThingsBoard generates the message type: RPC_CALL_FROM_SERVER_TO_DEVICE

To forward this message to the MQTT broker:

  1. Open the Root Rule Chain.
  2. Add an integration downlink node: Name it MQTT Integration Downlink, select your MQTT Integration, and click Add.
  3. Draw a relation from Message Type Switch to MQTT Integration Downlink with relation type RPC Request to Device.
  4. Apply changes.

After this configuration, every dashboard RPC command is forwarded to the MQTT Integration downlink converter.

The device subscribes to tb/mqtt-integration-tutorial/fridge/+/rx/set-temperature for incoming commands. Verify the downlink using mosquitto_sub:

Terminal window
mosquitto_sub -h broker.hivemq.com -p 1883 -t "tb/mqtt-integration-tutorial/fridge/+/rx/set-temperature"

Turn the knob on the dashboard. The terminal will receive messages like:

Terminal window
{"targetTemperature":-5.0}
{"targetTemperature":4.0}

The Knob Control widget generates an RPC_CALL_FROM_SERVER_TO_DEVICE message with method: setValue and the knob value as params. The oneway: true flag is set automatically by the widget — ThingsBoard neither tracks the delivery nor waits for a reply, and no timeout or retry applies.

params is always a string in the RPC payload — the encoder uses parseFloat(msg.params) to convert it to a number before building the JSON payload.

The Rule Engine routes the message via the RPC Request to Device relation to the Integration Downlink node, which passes it to the downlink converter. The encoder wraps the value into {targetTemperature: value} JSON and sets metadata.topic to the device-specific command topic. Because the integration’s Downlink topic pattern is ${topic}, the MQTT integration reads metadata.topic and publishes the payload to exactly that topic.