docs(protocol): 脱机事件日志命令规范 — MQTT V1.06 + TCP JSON V1.02

新增 3 命令 (两协议同步):
- log_stat: 日志统计/分页定位 (stream/boot_seq/count/capacity/seq_first/seq_last)
- log_query: 按全局序号分页拉取, count≤4 (受 500B 发布限制)
- log_clear: 清除+审计留痕 (log_clear 事件不可清除)

日志时间戳语义 (§2.3 补充): 每条记录 ts_ms(相对) + unix_ts(已同步,
0=未同步), 锚点回算规则; 10 类事件类型表 (boot/iot_*/evt_*/coil/
time_anchor/log_clear) 带 data 字段解析。

同步: README/CHANGELOG/产品手册/技术规格书 协议矩阵
(MQTT V1.05→V1.06, TCP JSON V1.01→V1.02)

注: 固件命令分发 (log_stat/log_query/log_clear 处理) 待 P1.3 实现,
本文档为协议先行
This commit is contained in:
wangfq
2026-08-04 18:34:31 +08:00
parent 90755bf465
commit 08893d5134
6 changed files with 255 additions and 10 deletions
+146
View File
@@ -110,6 +110,12 @@ dld960/{dev_serial}/{direction}
- 校准前(含首个 `initialize`),`ts` 为上电秒数;平台应能容忍并可按数量级区分。
- 设备重启后需重新校准(无掉电保持)。平台在每次设备 `initialize` 后都应下发一次带 `ts``report_config`
**脱机日志时间戳语义(V1.06 起)**
- 设备侧事件日志(`log_query` 拉取)每条记录携带双时间戳:`ts_ms`(boot 内相对时间,单位 ms,断电归零)+ `unix_ts`(已同步 Unix 秒,**0 = 未同步**)。
- 设备经本协议同步成功后,其后记录的 `unix_ts` 均为真实 Unix 时间;同步前(含每次上电的 `boot` 事件)`unix_ts = 0`,仅 `ts_ms` 相对时间。
- 回算规则:`绝对时间 = 锚点.unix_ts + (记录.ts_ms - 锚点.ts_ms)/1000`,锚点取该 boot 段内第一条 `time_anchor` 事件(`unix_ts` 即平台下发值,严格一致)。从未同步过的 boot 段只有相对时间。
---
# 3 命令详表
@@ -131,6 +137,9 @@ dld960/{dev_serial}/{direction}
| `loop_param_set` | 设置车检器多路参数 | srv→dev | 0x63 |
| `loop_param_query` | 读取车检器多路参数 | srv→dev | 0x64 |
| `report_config` | 设置主动上报 | srv→dev | 0xC5 |
| `log_stat` | 查询脱机事件日志统计 | srv→dev | — |
| `log_query` | 分页拉取脱机事件日志 | srv→dev | — |
| `log_clear` | 清除脱机事件日志(审计留痕) | srv→dev | — |
| `initialize` | 设备上电初始化登陆 | dev→srv | — |
| `loop_data` | 线圈传感数据上报 | dev→srv | 0xC0 |
| `event_report` | 事件上报(**平台须应答**,见 §5.3 | dev→srv | — |
@@ -639,6 +648,142 @@ dld960/{dev_serial}/{direction}
---
## 4.16 查询脱机事件日志统计 `log_stat`
> Topic: `dld960/{sn}/srv`
> 设备本地 W25Q32 环形事件日志(256KB / 8064 条,掉电不丢)。用于日志拉取前的分页定位。
**请求:**
```json
{
"msg_id": 16,
"cmd": "log_stat",
"ts": 1719000000,
"data": {}
}
```
**响应 data**
```json
{
"stream": "event",
"enabled": true,
"boot_seq": 2,
"count": 1234,
"capacity": 8064,
"seq_first": 100,
"seq_last": 1333
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `stream` | string | 日志流,当前仅 `event`(快照流预留) |
| `enabled` | bool | 日志功能是否启用(Flash 初始化成功) |
| `boot_seq` | uint16 | 当前启动序号(每次上电 +1,区分复位段) |
| `count` | uint16 | 有效记录条数(0~8064,环形覆盖后 < capacity |
| `capacity` | uint16 | 容量上限(8064 |
| `seq_first` | uint32 | 逻辑首条记录全局序号(`seq_last - count + 1` |
| `seq_last` | uint32 | 最新一条记录全局序号(跨 boot 单调递增) |
---
## 4.17 分页拉取脱机事件日志 `log_query`
> Topic: `dld960/{sn}/srv`
> **分页按全局序号,不按时间**(未同步段时间不可靠)。`count` 上限 **4**(受 MQTT 发布 ≤500B 限制,MSS=576 教训)。
**请求:**
```json
{
"msg_id": 17,
"cmd": "log_query",
"ts": 1719000000,
"data": {
"start_seq": 1330,
"count": 4
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `start_seq` | uint32 | 起始全局序号(含);越界(< `seq_first` 或 > `seq_last`)返回空 `records` |
| `count` | uint8 | 拉取条数,**上限 4**,超限按 4 处理 |
**响应 data**
```json
{
"start_seq": 1330,
"records": [
{
"seq": 1330,
"boot_seq": 2,
"ts_ms": 456789,
"unix_ts": 1784768575,
"type": "iot_ready",
"data": null
}
]
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| `seq` | uint32 | 全局序号 |
| `boot_seq` | uint16 | 所属启动段 |
| `ts_ms` | uint32 | boot 内相对时间(ms,断电归零) |
| `unix_ts` | uint32 | 已同步 Unix 秒;**0 = 未同步**(回算见 §2.3 |
| `type` | string | 事件类型名(下表) |
| `data` | object/null | 类型相关参数 |
**事件类型表:**
| type | 含义 | data 字段 |
|------|------|-----------|
| `boot` | 上电/复位 | `{"rst": 复位原因寄存器原始值}`,位解析:bit31=IWDG(看门狗) bit30=WWDG bit29=LPWR bit26=NRST引脚 bit25=POR(真断电) bit24=软件复位 |
| `iot_connect` | MQTT TCP 连接成功 | null |
| `iot_ready` | MQTT 订阅完成 → 发 initialize | null |
| `iot_disconnect` | MQTT 断连 | `{"reason": N}`1=断开 2=超时 3=CONNACK拒绝 4=连接超时 |
| `iot_reconn` | 重连退避 | `{"backoff_ms": 5000}` |
| `evt_retry` | event_report ACK 超时重发 | `{"msg_id":5,"retry":2}` |
| `evt_giveup` | event_report 重试耗尽挂起 | `{"msg_id":5}` |
| `coil` | 线圈事件 | `{"sub":"car_enter","ch":1,"value":97}`sub: car_enter/car_leave/loop_cut/loop_restorevalue 为 50ms 单位时间量 |
| `time_anchor` | 时钟同步锚点 | null`unix_ts` 即平台下发值,严格一致) |
| `log_clear` | 日志清除(审计) | null |
---
## 4.18 清除脱机事件日志 `log_clear`
> Topic: `dld960/{sn}/srv`
> ⚠ **高风险操作**:清除动作本身写入事件流(`log_clear` 审计——谁在何时清了日志,留痕不可清除)。平台侧应做权限控制。
**请求:**
```json
{
"msg_id": 18,
"cmd": "log_clear",
"ts": 1719000000,
"data": {
"stream": "event"
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `stream` | string | 日志流,当前仅 `event`;缺省等同 `event` |
**响应:** 标准成功/失败。成功后 `log_stat``count` 归 1(仅剩审计记录),`seq_last` 继续递增(序号不复位)。
---
# 5 设备主动上报
## 5.1 设备上电登陆信息 `initialize`
@@ -893,4 +1038,5 @@ dld960/{dev_serial}/{direction}
| V1.03 | 2026-07-09 | 增加设备上电初始化指令 | wangfq |
| V1.04 | 2026-07-15 | `event_report` 增加**平台必答**机制:应答格式(回显 `msg_id`)、设备 5s 超时重发(同 `msg_id`/`ts`,最多 3 次)、待发队列合并上报、平台去重与先落库后应答要求 | wangfq |
| V1.05 | 2026-07-15 | 增加**设备时钟同步**(§2.3,方案B):设备无 RTC,`initialize` 上线后平台经 `report_config` 命令下发 Unix `ts`,设备据此校准,之后上行 `ts` 为真实 Unix 时间;校准前为上电秒数 | wangfq |
| V1.06 | 2026-08-04 | 增加**脱机事件日志**命令:`log_stat`(统计/分页定位)、`log_query`(按全局序号分页,count≤4)、`log_clear`(清除+审计留痕);§2.3 补充日志双时间戳语义(`ts_ms` 相对 + `unix_ts` 已同步,0=未同步,锚点回算规则) | wangfq |