传输、主题与 CRC
支持的传输模式
IoT 中间件安装包
CoreCharge 可以提供可部署的中间件安装包。设备通信使用 MQTT 封装,运营方系统通过 HTTP POST 调用中间件并接收回调。HTTP 业务 API 与本设备协议分别进行版本管理。
一机一密 IoT 接入
每台机柜获得 ProductKey、DeviceName 和 DeviceSecret。默认主题模板如下:
| 方向 | 主题 |
|---|---|
| 设备订阅 | /{ProductKey}/{DeviceName}/user/get |
| 设备发布 | /{ProductKey}/{DeviceName}/user/update |
通用 MQTT Broker
运营方提供经批准的 Broker 域名和端口、认证方式以及主题配置。认证可以使用一机一密,也可以为受控设备组使用带权限范围的统一账号。选定配置提供 ProductKey 和 DeviceName 时,可以沿用上述默认主题模板。
生产配置
本公开网站不会出现 Broker 地址、端口、用户名、密码、设备密钥、Wi-Fi 凭据或真实设备号。这些值不公开,不影响协议本身的完整性。
CRC16/MODBUS 规则
- 去掉最外层大括号和最后的 CRC 字段。
- 保留指令、全部业务字段以及最后一个业务字段后的逗号,内容必须与发送值完全一致。
- 取配置项
PW的前 6 个字符;不足 6 位时在右侧补0。 - 把这 6 位密钥拼接到上一步字符串后。
- 对 ASCII 字节执行 CRC-16/MODBUS:初始值
0xFFFF,反射形式多项式0xA001。 - 将 16 位结果输出为 4 位大写十六进制字符,高字节在左。
当查询可见字段为 CQ,17000000,0,非生产 PW 为 DEMO00 时:
CRC input: CQ,17000000,0,DEMO00
CRC result: 6F75
Wire frame: {CQ,17000000,0,6F75}
PW 密钥后缀不会出现在传输帧中。
参考实现
export function crc16ModbusAscii(input) {
let crc = 0xffff;
for (const byte of new TextEncoder().encode(input)) {
crc ^= byte;
for (let bit = 0; bit < 8; bit += 1) {
crc = (crc & 1) ? ((crc >>> 1) ^ 0xa001) : (crc >>> 1);
}
}
return (crc & 0xffff).toString(16).toUpperCase().padStart(4, '0');
}
export function protocolCrc(dataWithoutCrc, password) {
const secret = String(password ?? '').slice(0, 6).padEnd(6, '0');
return crc16ModbusAscii(`${dataWithoutCrc},${secret}`);
}
可以下载完整的帧构造与校验代码。
接收与重试
- 设备发送
CN后,在收到服务端确认前每 60 秒重发一次。 - 设备发送
DS后,在收到确认前每 60 秒重发一次。 AC或CQ默认库存上报周期为 180 秒。AE默认扩展上报周期为 600 秒。- 对具有幂等要求的租借指令,同一订单 ID 的重复请求必须返回设备缓存的上一次结果。
BR确认必须使用新的消息 ID,不能复用请求 ID。- CRC 通过、指令被接受、物理动作成功是三个独立状态。
解析顺序
- 定位一个完整的
{...}帧。 - 校验 ASCII 编码和起止字符。
- 按英文逗号拆分。
- 根据指令与协商的固件配置选择字段模式。
- 校验字段数、类型、范围和标识符长度。
- 使用已配置的 PW 后缀重新计算 CRC,并进行恒定时间比较。
- 应用消息 ID 和订单 ID 的幂等规则。
- 处理指令,并分别保存传输、业务和物理结果。