跳到主要内容

MQTT API

通过 MQTT 转出功能,您可以借助 MQTT Broker,以发布/订阅方式发送请求消息,调用 已开放的数据转出 HTTP API。此外,您还可以实现 心跳保活、订阅或取消订阅设备数据,以及接收设备数据变化和其他对象事件。

获取 MQTT 连接信息​

在开始发布/订阅请求消息之前,您需要在 Aqara Studio 上启用 MQTT 转出服务,选择本地 Broker 或第三方 Broker,以此获取 MQTT 连接信息。相关流程请阅读 以 MQTT 转出设备数据。

鉴权​

MQTT 通道身份认证和 Topic 访问权限由 Broker 的连接凭据与 ACL 负责。您无需使用 OpenAPI Token,也不需要发送 AuthRequest 消息进行身份认证。

对于生产环境,您应该配置 Broker ACL,使您的应用只能向分配给自己的请求 Topic 发布消息,并且只能订阅分配给自己的响应 Topic。

不要允许应用订阅 /open/api/v1/response/+。

Topic​

Topic 类型方向格式用途
请求 Topic应用到 Studio/open/api/v1/request/{clientId}API 请求、心跳、订阅和取消订阅消息
响应 TopicStudio 到应用/open/api/v1/response/{clientId}API 响应、订阅响应、推送消息和错误消息
提示

请求 Topic 和响应 Topic 开头的 / 是 Topic 名称的一部分,不能省略。

格式中的 {clientId} 是您的应用在此 MQTT 通道中的逻辑会话和响应路由标识。常规情况下,一个 MQTT 连接对应一个应用,应用应使用其连接 Broker 时在 CONNECT 报文中提交的 MQTT Client ID 作为 Topic 中的 {clientId}。

格式中的 {clientId} 不是 Aqara Studio 在 MQTT 转出页面配置的 Client ID。Aqara Studio 使用自己的单个 MQTT 连接服务多个第三方应用,因此两者不应相同。只有代理程序通过一个 MQTT 连接承载多个逻辑客户端时,Topic 中的 {clientId} 才可以与该代理连接的 MQTT Client ID 不同;生产环境应通过 Broker ACL 限制每个应用可访问的请求和响应 Topic。

clientId 长度为 1~128 个字符,只能包含字母、数字、.、_、: 和 -。

服务质量(QoS)​

建议请求发布和响应订阅均使用 QoS 1。

发送请求前,您应先订阅响应 Topic,避免遗漏立即返回的响应。

调用 HTTP 接口​

若要调用 以下已开放的数据转出 HTTP API:

请编写并发送 type 为 OpenApiRequest 的请求消息。

请求字段​

字段必填类型说明
type✔string固定为 OpenApiRequest。
version✔string固定为 v1。
msgId✔string请求标识,响应使用相同的值。长度为 1~128 个字符,只能包含字母、数字、.、_、:、@ 或 -。每个逻辑操作使用一个新值;重试同一操作时保持不变。
data.method✔string支持 GET、POST、PATCH 或 DELETE。请根据上述各 HTTP API 文档选择合适的 HTTP 方法。
data.path✔string传入上述 HTTP API 的 Endpoint,如 /open/api/v1/devices。
data.query✘objectJSON 对象形式的查询参数。值可以是字符串、数字、布尔值或这些基础类型组成的数组,具体请参考各 HTTP API 文档中的 Request - Query Parameters 说明。
data.headers✘object可选的 OpenAPI 元数据 Header,例如 Lang。不能包含 Authorization 或 Cookie;路由使用的 ClientId 取自 Topic,不能在此覆盖。
data.body✘object | nullJSON 请求 Body。接口没有请求 Body 时,此字段可以省略或传 null。具体请参考各 HTTP API 文档中的 Request - Body 说明。

请求示例​

{
"type": "OpenApiRequest",
"version": "v1",
"msgId": "devices-001",
"data": {
"method": "GET",
"path": "/open/api/v1/devices",
"query": {
"pageNum": 1,
"pageSize": 20
},
"headers": {
"Lang": "zh-CN"
},
"body": null
}
}

响应说明​

响应 Topic 会直接收到标准 HTTP OpenAPI 响应体,因此,您只需按照上述各 HTTP API 文档中的 Responses 说明解析响应体即可。

响应示例​

{
"type": "GetDeviceInfoResponse",
"version": "v1",
"msgId": "devices-001",
"code": 0,
"message": "success",
"data": {
"totalCount": 1,
"pageNum": 1,
"pageSize": 20,
"data": []
}
}

心跳与订阅续租​

MQTT 协议自身的 Keep Alive 用于维护客户端与 Broker 之间的连接。通常由 MQTT SDK 自动发送 PINGREQ 并处理 PINGRESP,不需要应用为了保持 Broker 连接而额外发布下面的 JSON ping。

本文的 ping 是 Studio 应用层的逻辑订阅续租消息,作用是告诉 Studio:该请求 Topic 对应的 clientId 仍在使用此前建立的数据订阅。请按以下规则使用:

  • 仅调用 OpenAPI、没有建立 数据订阅 的客户端,不需要周期性发送 ping。
  • 存在有效数据订阅时,发送到该 clientId 请求 Topic 的任意请求都会续期订阅;如果 30 秒内已经发送过其他请求,不需要再单独发送 ping。
  • 有效订阅处于空闲状态、没有其他请求可用于续期时,建议每 30 秒内发送一次 ping。
  • Studio 只根据请求 Topic 上收到的消息续期。客户端持续收到推送消息并不会自动续期订阅。
  • 请求 Topic 连续 90 秒没有收到任何消息时,逻辑会话会过期,Studio 将清理该 clientId 的全部订阅并停止相关推送。之后再次发送 ping 只会创建新的逻辑会话,不会恢复已经清理的订阅;客户端必须重新发送相应的订阅请求。

MQTT Keep Alive 与 Studio 逻辑订阅续租相互独立,两者不能相互替代。客户端仍应根据所使用的 MQTT SDK 和 Broker 配置合适的 MQTT Keep Alive。

请求字段​

字段必填类型说明
type✔string固定为 ping。
version✔string固定为 v1。
msgId✔string请求标识,响应使用相同的值。长度为 1~128 个字符,只能包含字母、数字、.、_、:、@ 或 -。每个逻辑操作使用一个新值;重试同一操作时保持不变。
data✘null固定为 null。

请求示例​

{
"type": "ping",
"version": "v1",
"msgId": "ping-001",
"data": null
}

响应字段​

收到对应的 pong 表示从客户端经过 Broker 到 Studio、再返回客户端的应用消息链路当前可用。若未收到 pong,客户端应先检查 MQTT 连接并保留原 msgId 重试;如果空闲时间可能已经超过 90 秒,应在链路恢复后重新订阅。

字段类型说明
typestring固定为 pong。
versionstring固定为 v1。
msgIdstring消息唯一标识。正常请求和响应使用相同 msgId 关联;解析失败、部分权限或内部异常可能返回 UNKNOWN;服务端推送由服务端生成,不等同于订阅请求 msgId。
datastring固定为 pong。
codenumber响应状态码。0 表示成功,非 0 表示失败。
messagestring响应消息。

响应示例​

{
"type": "pong",
"version": "v1",
"msgId": "ping-001",
"data": "pong",
"code": 0,
"message": "success"
}

订阅设备数据​

订阅全部或指定设备​

如需订阅全部或指定设备的数据时,发送 type 为 SubscribeAllRequest 的请求消息。相关请求字段和响应字段说明见下文。

SubscribeAllRequest 会替换当前会话的 Trait 单项订阅。

请求字段​

字段必填类型说明
type✔string固定为 SubscribeAllRequest。
version✔string固定为 v1。
msgId✔string请求标识,响应使用相同的值。长度为 1~128 个字符,只能包含字母、数字、.、_、:、@ 或 -。每个逻辑操作使用一个新值;重试同一操作时保持不变。
data✘array设备 ID 数组。当此字段被省略、为 null 或空数组时,表示订阅当前可访问的全部设备的数据;当此字段非空,为非空设备 ID 数组时,表示只订阅指定设备的数据。

请求示例​

{
"type": "SubscribeAllRequest",
"version": "v1",
"msgId": "1789909097657_777ov8",
"data": null
}

响应字段​

字段类型说明
typestring固定为 SubscribeAllResponse。
versionstring固定为 v1。
msgIdstring消息唯一标识。正常请求和响应使用相同 msgId 关联;解析失败、部分权限或内部异常可能返回 UNKNOWN;服务端推送由服务端生成,不等同于订阅请求 msgId。非空,且长度不超过 64 个字符。
datastring默认值为空。
codenumber必填。处理结果码,0 表示成功,非 0 表示失败。
messagestring处理结果描述。

响应示例​

{
"type": "SubscribeAllResponse",
"version": "v1",
"msgId": "1789909303093_0jwcut",
"data": "",
"code": 0,
"message": ""
}

取消订阅全部或指定设备​

如需取消订阅全部或指定设备的数据时,发送 type 为 UnsubscribeAllRequest 的请求消息。相关请求字段和响应字段说明见下文。

UnsubscribeAllRequest 只修改设备数据和 Trait 订阅;独立事件及对象事件必须使用各自的取消订阅消息。

请求字段​

字段必填类型说明
type✔string固定为 UnsubscribeAllRequest。
version✔string固定为 v1。
msgId✔string消息唯一标识。正常请求和响应使用相同 msgId 关联;解析失败、部分权限或内部异常可能返回 UNKNOWN;服务端推送由服务端生成,不等同于订阅请求 msgId。非空,且长度不超过 64 个字符。
data✘string[] | null设备 ID 列表。省略、为 null 或空数组时,表示取消全部设备数据订阅;非空时,表示仅取消指定设备的数据订阅。默认值为 null。
若此前已订阅全部设备数据,则仅取消部分设备不会生效,需传空值取消全部订阅。
同一连接内,UnsubscribeAllRequest 会同时清理此前通过 SubscribeTraitValueRequest 建立的 Trait 订阅。
按特定设备取消订阅只取消设备级订阅,不等同于关闭当前连接的全部推送。

请求示例​

{
"type": "UnsubscribeAllRequest",
"version": "v1",
"msgId": "1789909759573_4ozfm7",
"data": null
}

响应字段​

字段类型说明
typestring固定为 UnsubscribeAllResponse。
versionstring固定为 v1。
msgIdstring消息唯一标识。正常请求和响应使用相同 msgId 关联;解析失败、部分权限或内部异常可能返回 UNKNOWN;服务端推送由服务端生成,不等同于订阅请求 msgId。非空,且长度不超过 64 个字符。
datastring默认为空。
codenumber处理结果码,0 表示成功,非 0 表示失败。
messagestring处理结果描述。

响应示例​

{
"type": "UnsubscribeAllResponse",
"version": "v1",
"msgId": "1789909884409_ln6tck",
"data": "",
"code": 0,
"message": ""
}

订阅指定 Trait 值​

如需订阅指定 Trait 值时,发送 type 为 SubscribeTraitValueRequest 的请求消息。相关请求字段和响应字段说明见下文。

请求字段​

字段必填类型说明
type✔string固定为 SubscribeTraitValueRequest。
version✔string固定为 v1。
msgId✔string消息唯一标识。正常请求和响应使用相同 msgId 关联;解析失败、部分权限或内部异常可能返回 UNKNOWN;服务端推送由服务端生成,不等同于订阅请求 msgId。非空,且长度不超过 64 个字符。
data✔object[]需要订阅的 Trait 列表。建议传非空数组;省略 data 会解析失败。当前实现对空数组或 traitCodes 为空数组仍可能返回成功响应,但不会创建有效的 TraitValueUpdate 订阅。
data[].deviceId✔string设备 ID。
data[].endpointId✔int32端点 ID。
data[].functionCode✔string功能代码。
data[].traitCodes✔string[]Trait 功能点代码列表。建议传非空数组;为空数组时不会创建或取消具体 Trait 订阅,但当前实现仍可能返回成功响应。

请求示例​

{
"type": "SubscribeTraitValueRequest",
"version": "v1",
"msgId": "subscribe-trait-001",
"data": [
{
"deviceId": "device-001",
"endpointId": 1,
"functionCode": "Light",
"traitCodes": ["OnOff"]
}
]
}

响应字段​

字段类型说明
typestring固定为 SubscribeTraitValueResponse。
versionstring固定为 v1。
msgIdstring消息唯一标识。正常请求和响应使用相同 msgId 关联;解析失败、部分权限或内部异常可能返回 UNKNOWN;服务端推送由服务端生成,不等同于订阅请求 msgId。非空,且长度不超过 64 个字符。
datastring默认值为空。
codeint32处理结果码,0 表示成功,非 0 表示失败。
messagestring处理结果描述。可为 null。

响应示例​

{
"type": "SubscribeTraitValueResponse",
"version": "v1",
"msgId": "1789957892004_ownm4j",
"data": "",
"code": 0,
"message": ""
}

取消订阅指定 Trait 值​

如需取消订阅指定 Trait 值时,发送 type 为 UnsubscribeTraitValueRequest 的请求消息。相关请求字段和响应字段说明见下文。

请求字段​

字段必填类型说明
type✔string固定为 UnsubscribeTraitValueRequest。
version✔string固定为 v1。
msgId✔string消息唯一标识。正常请求和响应使用相同 msgId 关联;解析失败、部分权限或内部异常可能返回 UNKNOWN;服务端推送由服务端生成,不等同于订阅请求 msgId。非空,且长度不超过 64 个字符。
data✘object[]需要取消订阅的 Trait 列表。建议传非空数组。省略 data、传空数组或 traitCodes 为空数组不会取消任何 Trait 订阅,但当前实现仍可能返回成功响应。
data[].deviceId✔string设备 ID。
data[].endpointId✔int32端点 ID。
data[].functionCode✔string功能代码。
data[].traitCodes✔string[]Trait 功能点代码列表。建议传非空数组;为空数组时不会创建或取消具体 Trait 订阅,但当前实现仍可能返回成功响应。

请求示例​

{
"type": "UnsubscribeTraitValueRequest",
"version": "v1",
"msgId": "1789960932713_6yexkw",
"data": [
{
"deviceId": "lumi3.86108040f2b03a4e",
"endpointId": 2,
"functionCode": "Speaker",
"traitCodes": [
"Volume"
]
}
]
}

响应字段​

字段类型说明
typestring固定为 UnsubscribeTraitValueResponse。
versionstring固定为 v1。
msgIdstring消息唯一标识。正常请求和响应使用相同 msgId 关联;解析失败、部分权限或内部异常可能返回 UNKNOWN;服务端推送由服务端生成,不等同于订阅请求 msgId。非空,且长度不超过 64 个字符。
datastring默认值为空。
codeint32处理结果码,0 表示成功,非 0 表示失败。
messagestring处理结果描述。可为 null。

响应示例​

{
"type": "UnsubscribeTraitValueResponse",
"version": "v1",
"msgId": "1789961117378_xd3ov7",
"data": "",
"code": 0,
"message": ""
}

接收推送消息​

所有推送均发布到 /open/api/v1/response/{clientId}。

Trait 值变化​

当您 订阅设备数据 或 订阅指定 Trait 值 后,只要目标 Trait 值发生变化,Aqara Studio 就会推送 TraitValueUpdate 消息。

字段说明​

字段类型说明
typestring固定为 TraitValueUpdate。
versionstring固定为 v1。
msgIdstring消息唯一标识。由 Aqara Studio 生成,不对应某条订阅请求。
dataobject[]Trait 值变化数组。
data[].deviceIdstring设备 ID。
data[].endpointIdint32端点 ID。
data[].functionCodestring功能代码。
data[].traitCodestringTrait 功能点代码。
data[].value—Trait 功能点值,类型由具体功能点定义决定。
data[].timeint64上报时间,毫秒级 Unix 时间戳。
codeint32处理结果码,0 表示成功,非 0 表示失败。
messagestring处理结果描述。可为 null。

示例​

{
"type": "TraitValueUpdate",
"version": "v1",
"msgId": "1754469720110",
"data": [
{
"deviceId": "device-001",
"endpointId": 1,
"functionCode": "Light",
"traitCode": "OnOff",
"value": true,
"time": 1754469720110
}
],
"code": 0,
"message": ""
}

对象事件​

当您 订阅了设备数据 或 订阅了指定 Trait 值 时,只要目标设备发生增减、端点发生增减或目标 Trait 的参数发生变化,就会收到 objectEvent 类型的推送消息。具体事件类型包括:

  • DEVICE_ADDED:设备新增。
  • DEVICE_REMOVED:设备移除。
  • DEVICE_ENDPOINT_ADDED:端点新增。
  • DEVICE_ENDPOINT_REMOVED:端点移除。
  • DEVICE_TRAIT_PARAMETER_UPDATE:Trait 参数更新。

因此,当您收到此事件推送后,应该先根据 eventType 和 objectId 分发事件,再解析 data.data 内的具体数据结构。

字段说明​

字段类型说明
typestring必填。固定为 objectEvent。
versionstring必填。固定为 v1。
msgIdstring消息唯一标识。由 Aqara Studio 生成,不对应某条订阅请求。
dataobject必填。对象事件数据。
data.eventTypestring必填。对象事件类型。可能值为 DEVICE_ADDED、DEVICE_REMOVED、DEVICE_ENDPOINT_ADDED、DEVICE_ENDPOINT_REMOVED、DEVICE_TRAIT_PARAMETER_UPDATE。
data.objectIdstring必填。对象 ID,设备事件场景通常为设备 ID。
data.timeint64必填。事件发生时间戳,单位毫秒。
data.dataobject可为 null。根据 eventType 判断具体结构。
data.data.*any可为 null。属性名不固定,根据 eventType 判断具体结构。
codeint32必填。处理结果码,0 表示成功,非 0 表示失败。
messagestring必填,可为 null。处理结果描述。
{
"type": "objectEvent",
"version": "v1",
"msgId": "1789961719076_fneua4",
"data": {
"eventType": "DEVICE_ADDED",
"objectId": "14d3b91",
"time": 1754469720110,
"data": {
"deviceId": "14d3b91",
"name": "",
"deviceTypesList": [
"Light"
],
"endpointIds": [
0,
2,
3
],
"time": 1754469720110
}
},
"code": 0,
"message": "success"
}

错误响应​

当请求消息格式错误、请求消息类型不适用、路由未开放或业务处理失败时,您会收到一条 type 为 ErrorMessage 的推送消息,相关字段说明见下文。

字段说明​

字段类型说明
typestring固定为 ErrorMessage。
versionstring固定为 v1。
msgIdstring消息唯一标识。由 Aqara Studio 生成,不对应某条订阅请求。
dataobject可为 null。
codeint32错误码。
messagestring错误原因描述。

示例​

{
"type": "ErrorMessage",
"version": "v1",
"msgId": "devices-001",
"data": null,
"code": 400,
"message": "Invalid MQTT OpenAPI request"
}

投递与重试规则​

  • 单条 MQTT OpenAPI 请求不能超过 256 KiB。
  • 同一逻辑 clientId 的请求按 Broker 到达顺序处理,不同逻辑客户端可以并行处理。
  • 未收到响应时,使用原 msgId 重试同一逻辑操作。在确认实际操作状态前,不要改用新 msgId 重复执行。
  • Studio 会暂时复用写请求的最终响应,避免 QoS 1 重投造成同一修改重复执行。不同写请求复用同一 msgId 时会返回错误。
  • 重连时使用 clean session,并主动重试未收到结果的请求;不要依赖 Broker 在 Studio 断线期间积压控制请求。