外观
WebSocket 接口
平台提供 WebSocket 长连接通道,用于持续获取设备状态类数据,替代高频 HTTP 轮询。
本文档只收录了一个 WebSocket 接口
接口文档只描述了 /ws/device-status 一个 WebSocket 接口。 本页另外两个接口(/ws/set-value、/ws/sensor-data/weather-station-data/{deviceCode}) 来自平台服务端的实际接口定义(不在文档范围内),一并列出便于对接。 每个接口的来源都已标注。
通道总览
| 通道 | 来源 | 用途 |
|---|---|---|
/ws/device-status | 接口文档 | 推送指定设备的控制参数(天窗、风机、湿帘等状态) |
/ws/sensor-data/weather-station-data/{deviceCode} | 服务端实际定义 | 推送气象站数据 |
/ws/set-value | 服务端实际定义 | 推送设定值 |
通用接入方式
| 项 | 约定 |
|---|---|
| 域名 | mqtt.iot.auto-control.com.cn(与 HTTP 实时接口同域) |
| 协议 | ws://(建议生产使用 wss://) |
| 订阅方式 | 建立连接后,客户端主动发一条 JSON 消息指定设备,不是 URL 参数 |
| 数据格式 | JSON,结构与对应的 HTTP 接口一致 |
通用注意事项
- 必须先发送订阅消息(指定
deviceCode),否则收不到任何推送 - 部分通道(如
/ws/device-status)在收到空消息或非 JSON 消息时会结束推送 - 必须实现断线重连(指数退避,避免重连风暴)
- 必须实现心跳 / 超时检测(长时间无推送则主动重连)
- 生产环境建议用
wss://,并校验服务端证书
一、控制参数推送 /ws/device-status
来源:接口文档
接口说明
建立连接后发送一条包含 deviceCode 的 JSON 消息,服务端随后持续推送该设备的控制参数。
请求地址
text
ws://mqtt.iot.auto-control.com.cn/ws/device-status1
请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceCode | String | 是 | 设备编码,通过第一条 WebSocket 消息发送 |
推送频率
实测推送间隔约 7 秒
实测连续两次推送的间隔为 7.3 秒(服务端默认推送周期为 7 秒,可通过环境变量调整)。 这是服务端配置,平台不承诺固定频率 —— 请在客户端做超时检测,不要假设固定间隔。
推送字段
推送体是双层嵌套,不是与 HTTP 版相同的结构
这是本通道最容易踩的坑。实测推送体:
json
{
"code": 200,
"data": {
"code": 200,
"data": [ { "name": "一级风机", "status": "00000100", ... } ]
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
控制项数组在 body.data.data,不是 body.data。
如果按 HTTP 版 读取控制参数 的结构去取(body.data 直接当数组), 会拿到一个对象,遍历时报错或什么也读不到。
| 字段名 | 类型 | 说明 |
|---|---|---|
code | Int | 外层状态码,200 为成功 |
data | Object | 内层包装对象(不是数组!) |
data.code | Int | 内层状态码,200 为成功 |
data.data | Array | 控制项数组 |
data.data[].name | String | 控制项名称 |
data.data[].status | String | Int | 状态值,语义见 status 位语义 |
data.data[].order | Int | 同名控制项的序号 |
data.data[].position | String | Int | 开合位置 |
data.data[].deviceTypeNumber | Int | 设备类型编号 |
data.data[].isBit | Int | 该控制项是否是位串语义 |
data.data[].suffix | String | 补充说明文字 |
示例
javascript
const ws = new WebSocket('wss://mqtt.iot.auto-control.com.cn/ws/device-status')
ws.onopen = () => ws.send(JSON.stringify({ deviceCode: '0010202606040002' }))
ws.onmessage = (e) => {
const body = JSON.parse(e.data)
if (body.code !== 200) return
// ⚠️ 注意是 body.data.data,控制项数组在第二层
const items = body.data?.data ?? []
items.forEach(i => console.log(i.name, i.status, i.position, i.isBit))
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
python
import asyncio
import json
import websockets
async def watch(device_code: str):
async with websockets.connect(
"wss://mqtt.iot.auto-control.com.cn/ws/device-status",
ping_interval=30,
) as ws:
await ws.send(json.dumps({"deviceCode": device_code}))
async for raw in ws:
body = json.loads(raw)
if body.get("code") != 200:
continue
# ⚠️ 注意是 body["data"]["data"]
for item in (body.get("data") or {}).get("data") or []:
print(item["name"], item["status"], item["position"], item["isBit"])
asyncio.run(watch("0010202606040002"))1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
推送内容示例
json
{
"code": 200,
"data": {
"code": 200,
"data": [
{ "name": "左向天窗", "status": "00000101", "order": 0, "position": "100", "deviceTypeNumber": 1, "isBit": 1, "suffix": "" },
{ "name": "一级风机", "status": "00000100", "order": 0, "position": 0, "deviceTypeNumber": 16, "isBit": 1, "suffix": "" },
{ "name": "二级风机", "status": "00000100", "order": 0, "position": 0, "deviceTypeNumber": 17, "isBit": 1, "suffix": "" },
{ "name": "三级风机", "status": "00000100", "order": 0, "position": 0, "deviceTypeNumber": 18, "isBit": 1, "suffix": "" },
{ "name": "湿帘", "status": "00000100", "order": 0, "position": 0, "deviceTypeNumber": 19, "isBit": 1, "suffix": "" }
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
二、气象站数据推送
来源:服务端实际接口定义(平台文档未收录)
接口说明
持续推送指定设备的气象站数据(室外温度、湿度、光照、风速风向、降雨量等)。
请求地址
text
ws://mqtt.iot.auto-control.com.cn/ws/sensor-data/weather-station-data/{deviceCode}1
注意路径参数的位置
本通道的设备编码在 URL 路径里({deviceCode}), 不是通过第一条消息发送 —— 与 /ws/device-status 不同。
推送频率
数据未变化时推送空数组
服务端按固定间隔轮询(默认 5 秒),但只在数据发生变化时才推送实际数据。
实测:连接建立后会立即收到一条消息;若当前无有效数据,内容是空数组 []。 之后设备没有新数据时,会长时间收不到消息 —— 这是正常行为,不代表连接断了。
请把「收到 []」当作有效心跳,不要因此判定连接异常。
推送字段
推送内容是一个纯数组(没有 code / message 包装),元素结构参照 传感器实时数据:
| 字段名 | 类型 | 说明 |
|---|---|---|
name | String | 传感器名称(中文) |
factor | String | 因子缩写,见 因子对照表 |
value | Number | 物理值 |
unit | String | 单位 |
dateTime | String | 采集时间 |
字段以实际返回为准
本通道的推送元素结构与 传感器实时数据 同族, 但平台未提供该通道的字段表。上表依据同族接口整理,请以实际返回为准。
示例
javascript
const deviceCode = '0010202606040002'
const ws = new WebSocket(
`wss://mqtt.iot.auto-control.com.cn/ws/sensor-data/weather-station-data/${deviceCode}`
)
ws.onmessage = (e) => {
const readings = JSON.parse(e.data) // 纯数组,可能是空数组 []
if (readings.length === 0) return // 空数组 = 当前无数据,属正常
readings.forEach(r => console.log(r.name, r.value, r.unit, r.dateTime))
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
三、设定值推送 /ws/set-value
来源:服务端实际接口定义(平台文档未收录)
接口说明
建立连接后发送订阅消息,服务端按 intervalTime 持续推送指定地址的当前值。
请求地址
text
ws://mqtt.iot.auto-control.com.cn/ws/set-value1
请求参数
连接建立后发送一条 JSON 消息:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
deviceCode | String | 是 | 设备编码 | 0010202606040002 |
address | String | 是 | 要监听的控制地址 | 3112 |
intervalTime | Int | 是 | 推送间隔(秒) | 5 |
deviceTypeId | Int | 是 | 设备类型 ID,取值见 映射表 | 10 |
customDataId | Int | 是 | 自定义数据配置 ID;未配置时会返回「未配置」并断开连接 | 1 |
实测:上述参数组合可用
用 deviceCode=0010202606040002、address=3112、intervalTime=5、 deviceTypeId=10、customDataId=1 实测连接成功, 连续收到 3 条推送,间隔分别约 5.7 秒 / 5.3 秒(与 intervalTime=5 吻合)。
本通道依赖「自定义数据配置」
服务端在读取不到缓存值时,会按 customDataId 查一条自定义数据配置来解析地址值。 未配置该 ID 时,服务端会返回「未配置」并主动断开连接。
该通道原本是给平台自己的「设定值页面」的自定义地址使用的。 第三方对接前请与运营方确认你的设备上是否有可用的 customDataId。
推送字段
| 字段名 | 类型 | 说明 |
|---|---|---|
code | Int | 状态码,200 为成功 |
data.address | String | 本次推送的地址 |
data.value | String | 该地址当前的值 |
推送示例
json
{
"code": 200,
"data": {
"address": "3112",
"value": "00001"
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
javascript
const ws = new WebSocket('ws://mqtt.iot.auto-control.com.cn/ws/set-value')
ws.onopen = () => ws.send(JSON.stringify({
deviceCode: '2022070314150044',
address: '3112',
intervalTime: 5,
deviceTypeId: 3,
customDataId: 1
}))
ws.onmessage = (e) => {
const body = JSON.parse(e.data)
console.log(body.data?.address, body.data?.value)
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
选型建议:HTTP 轮询 还是 WebSocket
| 场景 | 建议 |
|---|---|
| 进页面看一次当前状态 | HTTP(/api/device_status) |
| 页面常驻、需要状态变化及时反映 | WebSocket |
| 定时巡检全部设备在线状态 | HTTP(/api/control/mqtt,5~10 分钟一次) |
| 采集环境数据入库 | HTTP(按数据上报周期轮询,或直接用 WebSocket) |
| 服务端批量拉取历史数据 | HTTP |
先测数据变化频率,再决定要不要 WebSocket
实测经验:部分控制器几分钟才上报一条环境数据。这种情况下 WebSocket 的优势用不上, 定时轮询(甚至「进页面调一次」)就够了。 不要因为「需求里写了实时」就默认必须用 WebSocket。
WebSocket 的连接数成本
一个设备一个连接。监控 100 台设备就要 100 条长连接。 请评估你的网关/浏览器的并发连接上限(HTTP/1.1 下浏览器单域名通常 6 条)。 需要大量连接时,建议由服务端统一建连再对内分发。
下一步
- → 读取控制参数:
/ws/device-status的 HTTP 版本 - → 传感器实时数据:实时数据的 HTTP 版本
- → address 控制地址全量表