Files
LPT26x-HSF-4MB-Hilink_14.2.…/docs/serial_control_protocol.md

362 lines
14 KiB
Markdown
Raw Normal View History

# 串口控制协议
## 目录
- [1. 指令格式](#1-指令格式)
- [1.1 串口参数](#11-串口参数)
- [2. JSON 结构](#2-json-结构)
- [2.1 字段说明](#21-字段说明)
- [2.2 发送提示](#22-发送提示)
- [2.3 查询命令AT+QUERY](#23-查询命令atquery)
- [3. 支持服务与字段(详解)](#3-支持服务与字段详解)
- [3.1 switch开关](#31-switch开关)
- [3.2 brightness亮度](#32-brightness亮度)
- [3.3 cct色温](#33-cct色温)
- [3.4 lightMode场景模式](#34-lightmode场景模式)
- [3.5 progressSwitch渐变时长](#35-progressswitch渐变时长)
- [3.6 colourMode色温模式](#36-colourmode色温模式)
- [4. 约束](#4-约束)
- [5. 错误码](#5-错误码)
- [5.1 NotControllable112用法建议](#51-notcontrollable112用法建议)
- [6. 时序图示Mermaid](#6-时序图示mermaid)
- [7. 示例](#7-示例)
## 1. 指令格式
- 下发:`AT+CTRL={JSON}\r\n`
- 查询:`AT+QUERY={JSON}\r\n`
- 回执:`OK,<id>\r\n``ERROR,<code>[,<message>]\r\n`
- 异步结果:`AT+RESP={JSON}\r\n`
- 规则:
- 单行 JSON内部换行请写成 `\n`
- 行结束统一为 CRLF `\r\n`Windows 兼容)
- 接收端应兼容仅 LF `\n`
### 1.1 串口参数
- 波特率:`9600`
- 数据位:`8`
- 校验位:`None`
- 停止位:`1`
- 流控:`None`
- 编码:`UTF-8`(无 BOM
- 建议:行缓冲读取,按 CRLF `\r\n` 作为帧结束。
## 2. JSON 结构
- 单服务控制(必须携带 id
- 下发:`{"id": <u32>, "sid":"<serviceId>", "data": {<fields>}}`
- 返回:`{"id": <u32>, "sid":"<serviceId>", "data": {<fields>}, "error": <u32>, "message": "<可选>"}``error=0` 表示成功)
### 2.1 字段说明
- `id`number, u32>0必填
- 会话标识,用于将异步结果与请求一一对应、便于定位问题。
- 由发起方分配与维护,建议使用一个全局自增计数(溢出后回绕到 1
- 受控方不做去重与顺序检查,仅在 RESP 中原样回显。
- `sid`string必填
- 服务功能 ID。合法值`switch``brightness``cct``lightMode``progressSwitch``colourMode`
- 区分大小写;不在集合内的值视为不支持服务。
- `data`object必填
- 具体服务的数据负载。各服务的字段与范围见“支持服务与字段(详解)”。
- 缺字段或类型不符为业务错误RESP `error=105``message` 可携带原因)。
- `error`number, u32RESP 必带)
- 业务执行结果码:`0` 成功;非 0 失败。常见值见“错误码”。
- `message`string可选RESP 可带)
- 人类可读的错误或提示信息,用于调试。
### 2.2 发送提示
- 多次控制:请按需多次发送 `AT+CTRL=...`,每次使用不同的 `id`
- ACK 超时与重发建议:
- 发送后等待 `OK,<id>`,超时建议 `200500 ms`
- 未收到 ACK 则按原 `id` 与完全相同的 JSON 重发,重发 `23 次`,间隔 `200300 ms`
- 注意:设备不做去重,重复下发可能重复执行;建议尽量使用幂等设置(如重复设置相同亮度)。
- 结果等待与超时:
- 收到 `OK,<id>` 后等待 `AT+RESP`,建议超时阈值 `12 s`(视业务而定)。
- 超时未收到可按失败处理并在上层重试(使用新的 `id`)。
- 换行约定:所有发送与回执均以 CRLF `\r\n` 结束;示例为单行展示,实际发送需包含 CRLF。
### 2.3 查询命令AT+QUERY
- 作用:查询指定 `sid` 的当前状态(只读,不改变设备状态)。
- 下发:`AT+QUERY={"id": <u32>, "sid":"<serviceId>"}`\r\n
- 回执:`OK,<id>`\r\n
- 异步结果:`AT+RESP={"id": <u32>, "sid":"<serviceId>", "data": {<current-fields>}, "error": <u32>, "message": "<可选>"}`\r\n
- 说明:
- `data` 与“支持服务与字段(详解)”中各 `sid` 的状态格式一致(等同于 Get 接口的输出)。
-`sid` 不支持,返回 `ERROR,104,UnsupportedSid`(协议级错误)。
## 3. 支持服务与字段(详解)
### 3.1 switch开关
- 功能:控制灯具开/关。
- 下发:`{"id":<u32>,"sid":"switch","data":{"on":0|1}}`
- 返回:`{"id":<u32>,"sid":"switch","data":{"on":0|1},"error":<u32>,"message":"<可选>"}`
- 参数:`on` 为 int取值 `0` 关、`1` 开。
- 行为当处于“离家模式”mode=7收到 `on=1` 会先退出离家模式再开灯。
- 示例:
- 开灯
- 【发起方发送】`AT+CTRL={"id":101,"sid":"switch","data":{"on":1}}`
- 【受控方返回】`OK,101``AT+RESP={"id":101,"sid":"switch","data":{"on":1},"error":0}`
- 关灯
- 【发起方发送】`AT+CTRL={"id":102,"sid":"switch","data":{"on":0}}`
- 【受控方返回】`OK,102``AT+RESP={"id":102,"sid":"switch","data":{"on":0},"error":0}`
### 3.2 brightness亮度
- 功能:设置亮度百分比。
- 下发:`{"id":<u32>,"sid":"brightness","data":{"brightness":0..100}}`
- 返回:`{"id":<u32>,"sid":"brightness","data":{"brightness":<0..100>},"error":<u32>,"message":"<可选>"}`
- 参数:`brightness` 为 int范围 `0..100`;超出范围按边界钳制。
- 示例:
- 设为 60%`AT+CTRL={"id":201,"sid":"brightness","data":{"brightness":60}}`
- 最小值:`AT+CTRL={"id":202,"sid":"brightness","data":{"brightness":0}}`
- 最大值:`AT+CTRL={"id":203,"sid":"brightness","data":{"brightness":100}}`
### 3.3 cct色温
- 功能:设置色温(单位 K
- 下发:`{"id":<u32>,"sid":"cct","data":{"colorTemperature":2700..6000}}`
- 返回:`{"id":<u32>,"sid":"cct","data":{"colorTemperature":<2700..6000>},"error":<u32>,"message":"<可选>"}`
- 参数:`colorTemperature` 为 int范围 `2700..6000`;超出范围按边界钳制。
- 示例:
- 暖色 3000K`AT+CTRL={"id":301,"sid":"cct","data":{"colorTemperature":3000}}`
- 中性 4000K`AT+CTRL={"id":302,"sid":"cct","data":{"colorTemperature":4000}}`
- 冷色 6000K`AT+CTRL={"id":303,"sid":"cct","data":{"colorTemperature":6000}}`
### 3.4 lightMode场景模式
- 功能:按预设场景设置亮度与色温,或进入离家模式。
- 下发:`{"id":<u32>,"sid":"lightMode","data":{"mode":0..7}}`
- 返回:`{"id":<u32>,"sid":"lightMode","data":{"mode":<0..7>},"error":<u32>,"message":"<可选>"}`
- 参数:`mode` 为 int
- 0 customer自定义模式
- 1 relax (休闲模式)(约 50%4000K
- 2 movie观影模式约 10%3000K
- 3 dining用餐模式约 100%4000K
- 4 home回家模式约 80%3500K
- 5 winter冬天模式约 100%2700K
- 6 summer夏天模式约 100%6000K
- 7 leave离家模式直接关灯
- 示例:
- 观影模式:`AT+CTRL={"id":401,"sid":"lightMode","data":{"mode":2}}`
- 离家模式:`AT+CTRL={"id":402,"sid":"lightMode","data":{"mode":7}}`
- 回家模式:`AT+CTRL={"id":403,"sid":"lightMode","data":{"mode":4}}`
### 3.5 progressSwitch渐变时长
- 功能:设置亮度/色温变化的平滑过渡时间(秒)。
- 下发:`{"id":<u32>,"sid":"progressSwitch","data":{"fadeTime":0..30}}`
- 返回:`{"id":<u32>,"sid":"progressSwitch","data":{"fadeTime":<0..30>},"error":<u32>,"message":"<可选>"}`
- 参数:`fadeTime` 为 int范围 `0..30` 秒;`0` 表示尽快变化。
- 示例:
- 设为 5 秒:`AT+CTRL={"id":501,"sid":"progressSwitch","data":{"fadeTime":5}}`
- 立即变化:`AT+CTRL={"id":502,"sid":"progressSwitch","data":{"fadeTime":0}}`
### 3.6 colourMode色温模式
- 功能:设置色温工作模式。
- 下发:`{"id":<u32>,"sid":"colourMode","data":{"mode":0|1}}`
- 返回:`{"id":<u32>,"sid":"colourMode","data":{"mode":0|1},"error":<u32>,"message":"<可选>"}`
- 参数:`mode` 为 int`0` 单色温、`1` 双色温。
- 行为单色温0设备固定到预设色温6000K双色温1使用/保持当前色温。
- 示例:
- 单色温:`AT+CTRL={"id":601,"sid":"colourMode","data":{"mode":0}}`
- 双色温:`AT+CTRL={"id":602,"sid":"colourMode","data":{"mode":1}}`
## 4. 约束
- `{JSON}` 最大长度:≤ 1024 字节(不含前缀与行尾)。
- 单行承载,不允许真实换行;内部换行使用 `\n` 字符串。
- 行结束采用 CRLF `\r\n`;接收端应兼容仅 LF `\n`
- `id` 必须存在且为 u32>0缺失/类型不符即返回 `ERROR,105,TypeError`
## 5. 错误码
- `100` BadPrefix未以 `AT+CTRL=` 开头)
- `101` MalformedJSONJSON 语法错误)
- `102` EmptyJSON空 JSON
- `103` PayloadTooLong负载超长
- `104` UnsupportedSid不支持的 `sid`
- `105` TypeError字段缺失或类型不符
- `106` Busy设备忙
- `107` ApplyTimeout内部执行超时
- `112` NotControllable非受控状态设备处于不可被控制的模式例如升级/维护/工厂测试/安全锁定等)
- `111` RateLimited限频
### 5.1 NotControllable112用法建议
- 触发场景(示例):
- 升级进行中OTA/独立升级/固件校验)
- 维护/自检/烧录/工厂测试模式
- 安全锁定/童锁/设备被上级网关临时锁定
- 热保护/过温降额/低电量保护等安全策略生效
- 正在配网/关键迁移流程,不允许外部控制
- 返回规范:
- 收到控制后先回 ACK`OK,<id>`
- 业务结束后返回:`AT+RESP={"id":<id>,"sid":"<sid>","data":{...},"error":112,"message":"<原因>"}`
- `message` 建议取值(便于前端统一展示与日志聚合):
- `upgrading`(升级中)
- `maintenance`(维护/自检)
- `factory_test`(工厂测试)
- `locked`(安全/家长锁定)
- `thermal_protect`(热保护)
- `low_power`(低电量保护)
- `net_config`(正在配网)
- 查询建议:
- `AT+QUERY` 通常仍应返回当前状态并 `error=0`;若状态不可读,再返回 `error=112` 与合适的 `message`
## 6. 时序图示Mermaid
1) 多次控制(均成功,异步返回 `error=0`
```mermaid
sequenceDiagram
participant 发起方
participant 受控方
发起方->>受控方: AT+CTRL={"id":7001,"sid":"switch","data":{"on":1}}\r\n
受控方-->>发起方: OK,7001\r\n
note over 受控方: 执行开关控制
受控方-->>发起方: AT+RESP={"id":7001,"sid":"switch","data":{"on":1},"error":0}\r\n
发起方->>受控方: AT+CTRL={"id":7201,"sid":"lightMode","data":{"mode":2}}\r\n
受控方-->>发起方: OK,7201\r\n
note over 受控方: 执行场景模式切换
受控方-->>发起方: AT+RESP={"id":7201,"sid":"lightMode","data":{"mode":2},"error":0}\r\n
发起方->>受控方: AT+CTRL={"id":7301,"sid":"progressSwitch","data":{"fadeTime":5}}\r\n
受控方-->>发起方: OK,7301\r\n
note over 受控方: 设置渐变时长
受控方-->>发起方: AT+RESP={"id":7301,"sid":"progressSwitch","data":{"fadeTime":5},"error":0}\r\n
```
2) 协议级错误JSON 语法错误,直接 `ERROR`,不产生 RESP
```mermaid
sequenceDiagram
participant 发起方
participant 受控方
发起方->>受控方: AT+CTRL={"sid":"switch","data":{"on":1}
受控方-->>发起方: ERROR,101,MalformedJSON
note over 受控方: 帧被丢弃,无 AT+RESP
```
3) 业务错误(收到并受理,但参数类型错误)
```mermaid
sequenceDiagram
participant 发起方
participant 受控方
发起方->>受控方: AT+CTRL={"id":7501,"sid":"brightness","data":{"brightness":"sixty"}}\r\n
受控方-->>发起方: OK,7501\r\n
note over 受控方: 参数校验失败(类型错误)
受控方-->>发起方: AT+RESP={"id":7501,"sid":"brightness","data":{"brightness":50},"error":105,"message":"TypeError"}\r\n
```
4) 查询状态OK + RESP
```mermaid
sequenceDiagram
participant 发起方
participant 受控方
发起方->>受控方: AT+QUERY={"id":7101,"sid":"brightness"}\r\n
受控方-->>发起方: OK,7101\r\n
note over 受控方: 读取并打包当前亮度状态
受控方-->>发起方: AT+RESP={"id":7101,"sid":"brightness","data":{"brightness":60},"error":0}\r\n
```
## 7. 示例
1) 开关:打开
【发起方发送】
```
AT+CTRL={"id":7001,"sid":"switch","data":{"on":1}}
```
【受控方返回】
```
OK,7001
```
【受控方返回】
```
AT+RESP={"id":7001,"sid":"switch","data":{"on":1},"error":0}
```
2) 查询当前亮度
【发起方发送】
```
AT+QUERY={"id":7101,"sid":"brightness"}
```
【受控方返回】
```
OK,7101
```
【受控方返回】
```
AT+RESP={"id":7101,"sid":"brightness","data":{"brightness":60},"error":0}
```
3) 场景模式movie
【发起方发送】
```
AT+CTRL={"id":7201,"sid":"lightMode","data":{"mode":2}}
```
【受控方返回】
```
OK,7201
```
【受控方返回】
```
AT+RESP={"id":7201,"sid":"lightMode","data":{"mode":2},"error":0}
```
4) 渐变时长5 秒
【发起方发送】
```
AT+CTRL={"id":7301,"sid":"progressSwitch","data":{"fadeTime":5}}
```
【受控方返回】
```
OK,7301
```
【受控方返回】
```
AT+RESP={"id":7301,"sid":"progressSwitch","data":{"fadeTime":5},"error":0}
```
5) 色温模式:单色温
【发起方发送】
```
AT+CTRL={"id":7401,"sid":"colourMode","data":{"mode":0}}
```
【受控方返回】
```
OK,7401
```
【受控方返回】
```
AT+RESP={"id":7401,"sid":"colourMode","data":{"mode":0},"error":0}
```
6) 业务失败(类型错误)
【发起方发送】
```
AT+CTRL={"id":7501,"sid":"brightness","data":{"brightness":"sixty"}}
```
【受控方返回】
```
OK,7501
```
【受控方返回】
```
AT+RESP={"id":7501,"sid":"brightness","data":{"brightness":50},"error":105,"message":"TypeError"}
```
7) 非法 JSON协议级错误
【发起方发送】
```
AT+CTRL={"sid":"switch","data":{"on":1}
```
【受控方返回】
```
ERROR,101,MalformedJSON
```
8) 不支持的服务(协议级错误)
【发起方发送】
```
AT+CTRL={"id":7601,"sid":"foo","data":{"bar":1}}
```
【受控方返回】
```
ERROR,104,UnsupportedSid
```