本指南将帮助您熟悉 ThingsBoard IoT 网关的 MQTT 扩展配置。使用常规配置启用此扩展。我们将在下面描述扩展配置文件。

扩展配置: mqtt-config.json

Extension configuration is a JSON file that contains information about how to connect and monitor a list of MQTT brokers. The root JSON element should contain “brokers” array. Each broker in the array is configured using following properties:扩展配置是一个 JSON 文件,包含关于如何连接和并监控 MQTT 代理列表的信息。根 JSON 元素应该包含 “代理” 数组。数组中的每个代理都使用以下属性配置:

基本连接属性

属性 描述 默认值
host MQTT 代理地址 localhost
port MQTT 代理端口 1883
ssl 启用/禁用 加密连接的布尔标志位 false
truststore 用于加密连接的 Truststore 文件的路径
truststorePassword Truststore 的密码
retryInterval 重连间隔(毫秒) 3000
clientId MQTT 客户端ID。如果没有设置,则使用自动生成的UUID。 随机 UUID

例如:

  1. {
  2. "brokers": [
  3. {
  4. "host": "localhost",
  5. "port": 1883,
  6. "ssl": false,
  7. "retryInterval": 3000
  8. ...
  9. }
  10. ]
  11. }

客户端身份属性

MQTT 扩展支持以下客户端认证:

  • anonymous
  • basic
  • cert.PEM

匿名身份配置示例:

  1. {
  2. ...
  3. "credentials": {
  4. "type": "anonymous"
  5. }
  6. ...
  7. }

基本身份配置示例:

  1. {
  2. ...
  3. "credentials": {
  4. "type": "basic",
  5. "username": "Your username",
  6. "password": "Your password"
  7. }
  8. ...
  9. }

PEM 证书身份配置示例:

  1. {
  2. ...
  3. "credentials": {
  4. "type": "cert.PEM",
  5. "caCert" : "Path to Your CA certificate file",
  6. "privateKey" : "Path to Your private key file",
  7. "cert" : "Path to Your certificate file"
  8. }
  9. ...
  10. }

映射

本节将描述各种配置选项,允许指定 ThingsBoard 功能和现有/遗留设备协议之间的映射。

属性和时间序列数据上传

MQTT 主题监控的 “映射” 配置设置规则,并将数据转换为 ThingsBoard 键值格式。例如:

  1. {
  2. ...
  3. "mapping": [
  4. {
  5. "topicFilter": "sensors",
  6. "converter": {
  7. "type": "json",
  8. "filterExpression": "",
  9. "deviceNameJsonExpression": "${$.serialNumber}",
  10. "timeout": 60000,
  11. "attributes": [
  12. {
  13. "type": "string",
  14. "key": "model",
  15. "value": "${$.model}"
  16. }
  17. ],
  18. "timeseries": [
  19. {
  20. "type": "double",
  21. "key": "temperature",
  22. "value": "${$.temperature}"
  23. }
  24. ]
  25. }
  26. }
  27. ...
  28. ]
  29. }

注意: 可以在数组中指定多个映射对象。
映射过程使用映射对象的 topicFilter 参数订阅 MQTT 主题。分析其他设备或应用程序发布到本主题的每条消息,以提取设备名称和设备数据 (属性或时间序列值)。默认情况下,网关使用 Json 转换器,但是您可以自定义这种行为并实现自己的转换器。有关更多详细信息,请参见转换器接口
转换器基于 JsonPath 库,提供 JSON 结构的灵活映射和过滤能力。您可以根据路径过滤器示例定义 filterExpression
deviceNameJsonExpression 映射参数用于从传入的 JSON 消息中提取设备名称。
timeout 映射参数是非活跃超时 (毫秒)选项。如果指定了此参数,一旦在特定超时内没有新的遥测或属性更新,网关将报告设备断开。
例如,如果您有以下消息:

  1. {"serialNumber":"SN-001", "model":"T1000", "temperature":36.6}

${$.serialNumber}“ 表达式将会返回“SN-001”设备名称。类似的, “Device ${$.serialNumber} (${$.model})”将会返回 “Device SN-001 (T1000)” 设备名称。
假如设备名称是 MQTT 主题的一部分,你可以使用 deviceNameTopicExpression 参数,这是一个基于 Java 的正则表达式。
举个例子, 如果你有 “sensor/SN-001/temperature”主题, ”(?<=sensor\/)(.*?)(?=\/temperature)” 表示将会返回“SN-001” 设备名称.
类似的 JsonPath 映射规则会被用于属性时序的值:

  • key - 常量属性或时间序列 ThingsBoard 键。
  • type - either boolean, long, double or string.
  • value - 用 ${} 包裹的基于 JsonPath 语法的表达式

    设备连接和断开请求

    ThingsBoard 允许向设备发送关于设备属性更新的 RPC 命令和通知。但是为了发送它们,平台需要知道目标设备是否连接,以及目前使用什么网关或会话来连接设备。如果您的设备不断发送遥测数据,ThingsBoard 已经知道如何推送通知。如果您的设备刚刚连接到 MQTT 代理并等待命令/更新,您需要向网关发送一条消息,并通知设备已连接到代理。
    connectRequests” 和 “disconnectRequests” 允许将 MQTT 消息转换为相应的事件,这些事件将通过网关传递给 ThingsBoard。例如:
    1. {
    2. ...
    3. "connectRequests": [
    4. {
    5. "topicFilter": "sensors/connect",
    6. "deviceNameJsonExpression": "${$.serialNumber}"
    7. },
    8. {
    9. "topicFilter": "sensor/+/connect",
    10. "deviceNameTopicExpression": "(?<=sensor\/)(.*?)(?=\/connect)"
    11. }
    12. ]
    13. ...
    14. }
    TopicFilter 接受通配符 (‘+’ 和 ‘#’)。设备名称可以用 deviceNameTopicExpression 从主题中获取,也可以从传入的 json 消息中获取。
    在这种情况下,以下消息是有效的:
    1. mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensors/connect" -m '{"serialNumber":"SN-001"}'
    2. mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/SN-001/connect" -m ''
    注意:connectRequests” 和 “disconnectRequests” 的配置结构和语法是相同的。

    设备属性请求

    ThingsBoard 允许提供设备属性并从设备应用程序中获取其中的一些属性。您可以将此视为设备的远程配置。您的设备能够从 ThingsBoard 请求客户端和共享属性。有关更多详细信息,请参见用户指南
    attributeRequests” 配置允许配置相应属性请求和响应消息的格式。
    例如:
    1. {
    2. ...
    3. "attributeRequests": [
    4. {
    5. "topicFilter": "sensors/attributes",
    6. "deviceNameJsonExpression": "${$.serialNumber}",
    7. "attributeKeyJsonExpression": "${$.key}",
    8. "requestIdJsonExpression": "${$.requestId}",
    9. "clientScope": false,
    10. "responseTopicExpression": "sensors/${deviceName}/attributes/${responseId}",
    11. "valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}"
    12. },
    13. {
    14. "topicFilter": "sensors/+/attributes/+/request/+",
    15. "deviceNameTopicExpression": "(?<=sensors\/)(.*?)(?=\/attributes)",
    16. "attributeKeyTopicExpression": "(?<=attributes\/)(.*?)(?=\/request)",
    17. "requestIdTopicExpression": "(?<=request\/)(.*?)($)",
    18. "clientScope": false,
    19. "responseTopicExpression": "sensors/${deviceName}/attributes/${attributeKey}/response/${requestId}",
    20. "valueExpression": "${attributeValue}"
    21. }
    22. ]
    23. ...
    24. }
    下表列出了相应的配置属性及其描述。
属性 描述 强制 例子
topicFilter 允许通配符 (‘+’ 和 ‘#’)的主题过滤器 yes sensors/+/attributes/+/request/+
deviceNameJsonExpression 从消息JSON中提取设备名称JsonPath 表达式 deviceNameJsonExpressiondeviceNameTopicExpression 二选一 ${$.serialNumber}
attributeKeyJsonExpression 从消息JSON中提取属性键JsonPath 表达式 attributeKeyJsonExpression attributeKeyTopicExpression 二选一 ${$.key}
requestIdJsonExpression 从消息JSON中提取请求 idJsonPath 表达式 requestIdJsonExpressionrequestIdTopicExpression 二选一 ${$.requestId}
deviceNameTopicExpression 从主题中获取设备名称的正则表达式 deviceNameTopicExpressiondeviceNameJsonExpression 二选一 (?<=sensors\/)(.*?)(?=\/attributes)
attributeKeyTopicExpression 从主题中获取属性键的正则表达式 attributeKeyTopicExpression attributeKeyJsonExpression 二选一 (?<=attributes\/)(.*?)(?=\/request)
requestIdTopicExpression 从主题中获取请求id的正则表达式 requestIdTopicExpressionrequestIdJsonExpression 二选一 (?<=request\/)(.*?)($)
clientScope 标识属性的范围:客户端或共享 yes true 表示客户端属性,false 表示其他
responseTopicExpression 将要发布的响应对应的主题的表达式。 您可以在此表达式中使用 ${deviceName}${requestId}${attributeKey} yes sensors/${deviceName}/attributes/${attributeKey}/response/${requestId}
valueExpression 将要发布的响应消息的表示,你可以在表示式中使用 ${deviceName},${requestId} ${attributeKey}${attributeValue} yes ${attributeValue}

在这种情况下,以下消息是有效的:

  1. mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensors/attributes" -m '{"serialNumber":"SN-001", "key":"dataUploadFrequency", "requestId": 123}'
  2. mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensors/SN-001/attributes/dataUploadFrequency/request/123" -m ''

设备属性更新

ThingsBoard 允许订阅设备应用程序中共享设备属性的更改。有关更多详细信息,请参见用户指南
“attributeUpdates” 配置允许配置相应订阅消息的格式。
例如:

  1. {
  2. ...
  3. "attributeUpdates": [
  4. {
  5. "deviceNameFilter": ".*",
  6. "attributeFilter": ".*",
  7. "topicExpression": "sensor/${deviceName}/${attributeKey}",
  8. "valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}"
  9. }
  10. ]
  11. ...
  12. }

如您所见,您可以过滤掉设备和属性,并将此更新转发到特定主题。主题和值表达式支持以下内容
参数: ${deviceName},${requestId} ${attributeKey}${attributeValue}.

服务器端 RPC 命令

ThingsBoard 允许向直接或通过网关连接到 ThingsBoard 的设备发送 RPC 命令
serverSideRpc“ 允许配置请求和响应 MQTT 消息的格式。例如:

  1. {
  2. ...
  3. "serverSideRpc": [
  4. {
  5. "deviceNameFilter": ".*",
  6. "methodFilter": "echo",
  7. "requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
  8. "responseTopicExpression": "sensor/${deviceName}/response/${methodName}/${requestId}",
  9. "responseTimeout": 10000,
  10. "valueExpression": "${params}"
  11. },
  12. {
  13. "deviceNameFilter": ".*",
  14. "methodFilter": "no-reply",
  15. "requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
  16. "valueExpression": "${params}"
  17. }
  18. ]
  19. ...
  20. }

正如您可以使用 deviceNameFilter methodFilter 为不同的设备/方法应用不同的映射规则一样。一旦网关从服务器接收到设备的 RPC 请求,它将基于 requestTopicExpressionvalueExpression 发布相应的消息。如果您期望来自设备的请求得到回复,您还应该指定 responseTopicExpressionresponseTimeout。网关将订阅 “response” 主题,并等待设备回复,直到检测到 “timeout”。
用 javascript 编写的设备应用程序示例:

  1. var mqtt = require('mqtt');
  2. var broker = 'mqtt://127.0.0.1:1883';
  3. var device = 'SN-001';
  4. var client = mqtt.connect(broker, {
  5. // Will topic to report that device is disconnected
  6. will: {topic: 'sensor/' + device + '/disconnect', payload: '', qos: 1}
  7. });
  8. client.on('connect', function () {
  9. console.log('connected');
  10. // Report that device is connected to the gateway
  11. client.publish('sensor/' + device + '/connect', '');
  12. // Subscribe to RPC requests topic
  13. client.subscribe('sensor/' + device + '/request/+/+');
  14. });
  15. client.on('message', function (topic, message) {
  16. console.log('request.topic: ' + topic);
  17. console.log('request.body: ' + message.toString());
  18. console.log('response.topic: ' + topic.replace('request','response'));
  19. // Publish the response that will simply echo the request.
  20. client.publish(topic.replace('request','response'), message);
  21. });

需要从服务器发送的 RPC 请求 (rpc-request.json) 示例:

  1. {
  2. "method": "echo",
  3. "params": {
  4. "message": "Hello!"
  5. },
  6. "timeout": 5000
  7. }

使用 CURL 的 POST 命令示例:

  1. $ SERVER_BASE_URL=http://localhost:8080
  2. $ JWT_TOKEN=YOUR_TOKEN_HERE
  3. $ DEVICE_ID=YOUR_DEVICE_ID_HERE
  4. $ curl -v -X POST -d @rpc-request.json $SERVER_BASE_URL/api/plugins/rpc/twoway/$DEVICE_ID \
  5. --header "Content-Type:application/json" \
  6. --header "X-Authorization: Bearer $JWT_TOKEN"

下一步

探索例子:

探索与主要 ThingsBoard 功能相关的指南: