Skip to content

MQTT协议

入门

MQTT基础

MQTT是一种轻量级的发布-订阅消息传递协议,它可能最适合各种物联网设备。

你可以在此处找到有关MQTT的更多信息,蟹立方物联网平台服务器支持QoS级别0(最多一次)和QoS级别1(至少一次)以及一组预定义主题的MQTT代理。

客户端

你可以在网上找到大量的MQTT客户端库,本文中的示例将基于Mosquitto和MQTT.js您可以使用我们的Hello World指南中的说明。

MQTT连接

我们将在本文中使用令牌凭据对进行设备访问,这些凭证稍后将称为$ACCESS_TOKEN应用程序需要发送用户名包含$ACCESS_TOKEN的MQTT CONNECT消息。

连接状态码说明:

  • 0x00 连接成功 - 成功连接
  • 0x04 连接失败 - 用户名或密码错误。
  • 0x05 连接未授权 - -用户名包含无效的 $ACCESS_TOKEN。

Key-value格式

蟹立方物联网平台支持以JSON格式的key-value字符串值可以是string、bool、float、long或者二进制格式的序列化字符串;有关更多详细信息请参见协议自定义。

{
 "stringKey":"value1", 
 "booleanKey":true, 
 "doubleKey":42.0, 
 "longKey":73, 
 "jsonKey": {
    "someNumber": 42,
    "someArray": [1,2,3],
    "someNestedObject": {"key": "value"}
 }
}

遥测上传API

发布遥测数据到蟹立方物联网平台服务端必须PUBLISH消息发送到下面主题:

v1/devices/me/telemetry

支持的最简单的数据格式是:

{"key1":"value1", "key2":"value2"}

或者

[{"key1":"value1"}, {"key2":"value2"}]

请注意 在这种情况下服务端时间戳将分配给上传的数据!

如果您的设备能够获得客户端时间戳,则可以使用以下格式:

{"ts":1451649600512, "values":{"key1":"value1", "key2":"value2"}}

在上面的示例中我们假设“1451649600512”是具有毫秒精度的Unix时间戳。 例如:值’1451649600512’对应于’2016年1月1日 星期五 12:00:00.512 GMT’

# Publish data as an object without timestamp (server-side timestamp will be used). Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mosquitto_pub -d -q 1 -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/telemetry" -u "$ACCESS_TOKEN" -m "{"temperature":42}"
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mosquitto_pub -d -q 1 -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/telemetry" -u "ABC123" -m "{"temperature":42}"

# Publish data as an object without timestamp (server-side timestamp will be used) using data from file. Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mosquitto_pub -d -q 1 -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/telemetry" -u "$ACCESS_TOKEN" -f "telemetry-data-as-object.json"
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mosquitto_pub -d -q 1 -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/telemetry" -u "ABC123" -f "telemetry-data-as-object.json"

# Publish data as an array of objects without timestamp (server-side timestamp will be used) using data from file. Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mosquitto_pub -d -q 1 -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/telemetry" -u "$ACCESS_TOKEN" -f "telemetry-data-as-array.json"
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mosquitto_pub -d -q 1 -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/telemetry" -u "ABC123" -f "telemetry-data-as-array.json"

# Publish data as an object with timestamp (telemetry timestamp will be used) using data from file. Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mosquitto_pub -d -q 1 -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/telemetry" -u "$ACCESS_TOKEN" -f "telemetry-data-with-ts.json"
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mosquitto_pub -d -q 1 -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/telemetry" -u "ABC123" -f "telemetry-data-with-ts.json"
# Publish data as an object without timestamp (server-side timestamp will be used). Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mqtt pub -v -q 1 -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/telemetry" -u '$ACCESS_TOKEN' -m "{"temperature":42}"
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mqtt pub -v -q 1 -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/telemetry" -u 'ABC123' -m "{"temperature":42}"

# Publish data as an object without timestamp (server-side timestamp will be used). Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
cat telemetry-data-as-object.json | mqtt pub -v -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/telemetry" -u '$ACCESS_TOKEN' -s -m ""
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
cat telemetry-data-as-object.json | mqtt pub -v -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/telemetry" -u 'ABC123' -s -m ""

# Publish data as an array of objects without timestamp (server-side timestamp will be used). Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
cat telemetry-data-as-array.json | mqtt pub -v -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/telemetry" -u '$ACCESS_TOKEN' -s -m ""
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
cat telemetry-data-as-array.json | mqtt pub -v -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/telemetry" -u 'ABC123' -s -m ""

# Publish data as an object with timestamp (telemetry timestamp will be used). Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
cat telemetry-data-with-ts.json | mqtt pub -v -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/telemetry" -u '$ACCESS_TOKEN' -s -m ""
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
cat telemetry-data-with-ts.json | mqtt pub -v -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/telemetry" -u 'ABC123' -s -m ""
{
  "stringKey": "value1",
  "booleanKey": true,
  "doubleKey": 42.0,
  "longKey": 73,
  "jsonKey": {
    "someNumber": 42,
    "someArray": [1,2,3],
    "someNestedObject": {"key": "value"}
  }
}
[{"key1":"value1"}, {"key2":true}]
{
  "ts": 1451649600512,
  "values": {
    "stringKey": "value1",
    "booleanKey": true,
    "doubleKey": 42.0,
    "longKey": 73,
    "jsonKey": {
      "someNumber": 42,
      "someArray": [1, 2, 3],
      "someNestedObject": {
        "key": "value"
      }
    }
  }
}

属性API

蟹立方物联网平台属性API能够使设备具备如下功能

  • 将客户端设备属性上传到服务端
  • 从服务端请求客户端和共享属性
  • 从服务端订阅共享属性

通过服务端发布客户端属性 通过蟹立方物联网平台服务端发布客户端属性必须PUBLISH消息到下面主题:

v1/devices/me/attributes
# Publish client-side attributes update. Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mosquitto_pub -d -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/attributes" -u "$ACCESS_TOKEN" -m "{"attribute1": "value1", "attribute2": true}"
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mosquitto_pub -d -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/attributes" -u "ABC123" -m "{"attribute1": "value1", "attribute2": true}"

# Publish client-side attributes update from file. Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mosquitto_pub -d -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/attributes" -u "$ACCESS_TOKEN" -f "new-attributes-values.json"
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mosquitto_pub -d -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/attributes" -u "ABC123" -f "new-attributes-values.json"
# Publish client-side attributes update. Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
cat new-attributes-values.json | mqtt pub -d -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/attributes" -u '$ACCESS_TOKEN' -s -m ""
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
cat new-attributes-values.json | mqtt pub -d -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/attributes" -u 'ABC123' -s -m ""
{
  "attribute1": "value1",
  "attribute2": true,
  "attribute3": 42.0,
  "attribute4": 73,
  "attribute5": {
    "someNumber": 42,
    "someArray": [1,2,3],
    "someNestedObject": {"key": "value"}
  }
}

通过服务端获取属性值 通过蟹立方物联网平台服务端获取客户端属性或共享属性必须PUBLISH消息到下面主题:

v1/devices/me/attributes/request/$request_id

其中$request_id表示整数的请求标识符。

在发送带有请求的PUBLISH消息之前客户端需要订阅。

v1/devices/me/attributes/response/+

以下示例是用javascript基于mqtt.js编写的代码。 命令行示例不可用因为订阅和发布需要在同一mqtt会话中进行。

通过设备的访问令牌替换$ACCESS_TOKEN并将”mqtt-js-attributes-request.js”文件中的主机名替换为”demo.蟹立方物联网平台.io”。 在此示例中主机名参考演示服务器。

export TOKEN=$ACCESS_TOKEN
node mqtt-js-attributes-request.js
var mqtt = require('mqtt')
var client  = mqtt.connect('mqtt://demo.蟹立方物联网平台.io',{
    username: process.env.TOKEN
})

client.on('connect', function () {
    console.log('connected')
    client.subscribe('v1/devices/me/attributes/response/+')
    client.publish('v1/devices/me/attributes/request/1', '{"clientKeys":"attribute1,attribute2", "sharedKeys":"shared1,shared2"}')
})

client.on('message', function (topic, message) {
    console.log('response.topic: ' + topic)
    console.log('response.body: ' + message.toString())
    client.end()
})
{"client":{"attribute1":"value1","attribute2":true}}

请注意:客户端和共享设备属性键的交集是不好的做法!但是对于客户端、共享和服务端属性仍然可能具有相同的密钥。

通过服务端订阅属性 通过服务端订阅共享属性必须SUBSCRIBE消息到下面主题:

v1/devices/me/attributes

如果服务端组件(例如REST API或规则链)更改了共享属性时客户端就会收到对应属性值:

{"key1":"value1"}
# Subscribes to attribute updates. Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mosquitto_sub -d -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/attributes" -u "$ACCESS_TOKEN"
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mosquitto_sub -d -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/attributes" -u "ABC123"
# Subscribes to attribute updates. Replace $蟹立方物联网平台_HOST_NAME and $ACCESS_TOKEN with corresponding values.
mqtt sub -v -h "$蟹立方物联网平台_HOST_NAME" -t "v1/devices/me/attributes" -u '$ACCESS_TOKEN'
# For example, $蟹立方物联网平台_HOST_NAME reference live demo server, $ACCESS_TOKEN is ABC123:
mqtt sub -v -h "demo.蟹立方物联网平台.io" -t "v1/devices/me/attributes" -u 'ABC123'

支持JSON

我们在遥测和属性API中增加了对JSON数据结构的支持,以简化设备配置的工作。JSON支持使您既可以从设备上传嵌套对象,也可以向设备推送嵌套对象。您可以将一个配置JSON作为共享属性存储,并将其推送到设备。此外,您还可以在规则引擎中处理JSON数据,并触发警报等。

因此,这一改进减少了蟹立方物联网平台存储数据时所需的数据库操作次数。例如,在SQL或NoSQL数据库中,“温度”和“湿度”会被存储为单独的行,以便高效地聚合这些数据以供可视化使用。由于不需要聚合JSON数据,我们可以将所有内容存储为一行,而不是为每个配置项存储单独的行。在一些环境中,通过将多个参数聚合到一个JSON中,我们可以将数据库操作次数减少10倍以上。

要了解有关JSON值支持的更多信息,请观看视频。

RPC API

服务端

客户端订阅服务端RPC命令必须SUBSCRIBE消息发送下面主题:

v1/devices/me/rpc/request/+

订阅后客户端会收到一条命令作为对相应主题的PUBLISH命令:

v1/devices/me/rpc/request/$request_id

$request_id表示请求的整型标识符。

客户端PUBLISH下面主题进行响应:

v1/devices/me/rpc/response/$request_id

以下示例是用javascript基于mqtt.js编写的代码。 命令行示例不可用因为订阅和发布需要在同一mqtt会话中进行。

通过设备的访问令牌替换$ACCESS_TOKEN并将”mqtt-js-rpc-from-server.js”文件中的主机名替换为”xieiip.com”。 在此示例中主机名参考演示服务器。

  • 使用RPC debug terminal在仪表板调试
  • 订阅服务器RPC命令
  • 请求”connect”发送到设备
  • 收到设备的响应

alt textalt textalt text

export TOKEN=$ACCESS_TOKEN
node mqtt-js-rpc-from-server.js
var mqtt = require('mqtt');
var client  = mqtt.connect('mqtt://demo.蟹立方物联网平台.io',{
    username: process.env.TOKEN
});

client.on('connect', function () {
    console.log('connected');
    client.subscribe('v1/devices/me/rpc/request/+')
});

client.on('message', function (topic, message) {
    console.log('request.topic: ' + topic);
    console.log('request.body: ' + message.toString());
    var requestId = topic.slice('v1/devices/me/rpc/request/'.length);
    //client acts as an echo service
    client.publish('v1/devices/me/rpc/response/' + requestId, message);
});

如果你的MQTT设备是网关则蟹立方物联网平台将发送服务器端RPC(通知)了解已配置设备实体的更改。 你的MQTT网关设备将收到删除或重命名设备的服务RPC解决事件。

客户端

将RPC命令发送到服务端必须PUBLISH消息发送到下面主题:

v1/devices/me/rpc/request/$request_id

$request_id表示请求的整型标识符服务端必须发布到下面主题:

v1/devices/me/rpc/response/$request_id

以下示例是用javascript基于mqtt.js编写的代码。 命令行示例不可用因为订阅和发布需要在同一mqtt会话中进行。

通过设备的访问令牌替换$ACCESS_TOKEN并将”mqtt-js-rpc-from-server.js”文件中的主机名替换为”xieiip.com”。 在此示例中主机名参考演示服务器。

  • 在规则链中添加两个节点”script”和”rpc call reply”

  • 在script中输入函数:

return {msg: {time:String(new Date())}, metadata: metadata, msgType: msgType};
  • 将请求发送到服务器
  • 收到服务器的响应 alt textalt textalt text
export TOKEN=$ACCESS_TOKEN
node mqtt-js-rpc-from-client.js
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://demo.蟹立方物联网平台.io', {
    username: process.env.TOKEN
});

client.on('connect', function () {
    console.log('connected');
    client.subscribe('v1/devices/me/rpc/response/+');
    var requestId = 1;
    var request = {
        "method": "getCurrentTime",
        "params": {}
    };
    client.publish('v1/devices/me/rpc/request/' + requestId, JSON.stringify(request));
});

client.on('message', function (topic, message) {
    console.log('response.topic: ' + topic);
    console.log('response.body: ' + message.toString());
});

声明设备

请参阅相应的文章以获取有关声明设备功能的更多信息。

启动声明设备请将POST请求发送到以下URL:

v1/devices/me/claim

支持的数据格式为:

{"secretKey":"value", "durationMs":60000}

请注意上述字段是可选的如果未指定secretKey则使用空字符串作为默认值。 如果未指定durationms则使用系统参数device.claim.duration(在文件/etc/etting/themings/conf/conf/thexboard.yml中使用)。

设备预配置

请参阅相应的文章并获取有关[设备供应]Device provisioning功能的更多信息。

启动设备配置请将发布请求发送到以下URL:

/provision

将username或clientId设为provision。

支持数据格式如下:

{
  "deviceName": "DEVICE_NAME",
  "provisionDeviceKey": "u7piawkboq8v32dmcmpp",
  "provisionDeviceSecret": "jpmwdn8ptlswmf4m29bw"
}

硬件API

当蟹立方物联网平台通过HTTP启动固件更新时它会设置FW_TITLE,FW_VERSION,FW_CHECKSUM,FW_CHECKSUM_ALGORITHM共享属性。

要接收共享属性更新该设备必须获取请求。

v1/devices/me/attributes/response/+

说明

+是通配符。

当MQTT设备收到FW_TITLE和FW_Version共享属性的更新时,必须它将发布消息发送到

v2/fw/request/${requestId}/chunk/${chunkIndex}

说明

${requestId} - 与固件更新相对应的数字每个固件更新${requestId}必须不同。 ${chunkIndex} - 与固件块索引相对应的数字${chunkID}是从0开始计数。 MQTT payload为字节中固件块的大小。

对于每个新的固件更新需要更改请求ID并订阅

v2/fw/response/+/chunk/+

说明

+是通配符。

自定义协议

通过更改相应的模块可以针对特定用例完全定制HTTP传输。