docs(M06-C-R1): 回填协议纠偏与游标
This commit is contained in:
@@ -120,9 +120,9 @@ WSL 已验证:EMQX `5.8.9`、MQTTX CLI `1.13.0`、EMQX 服务 `active (running
|
||||
|
||||
项目已开发部分模块。具体完成度不得从 README 猜测,必须以现有代码、测试、数据库迁移、Git 历史以及 `docs/current-baseline.md`、`docs/module-status.md`、`docs/feature-status.md` 为准。
|
||||
|
||||
- 当前执行游标:`M06-C-R1`(DOING);`M09-A-RECOVERY` 已完成,真实团购商家授权、微信和硬件现场验收保持 `BLOCKED_EXTERNAL`。
|
||||
- 最近工程提交:`9b2f055` / `M09-A保洁任务事务与并发收口`,真实 MySQL 8.4.10 已验证并发 claim 单赢家、事件失败回滚、重指派清理、`SKIP LOCKED` 批量回收和订单唯一建任务。
|
||||
- 下一工程目标:按 V5.6 固定队列执行 M06-C-R1,依据智慧插座协议原件修正 wire schema、fixture、标准化字段和消息落库。
|
||||
- 当前执行游标:`M06-E-R1`(DOING);`M09-A-RECOVERY` 与 `M06-C-R1` 已完成,真实团购商家授权、微信和硬件现场验收保持 `BLOCKED_EXTERNAL`。
|
||||
- 最近工程提交:`dabc656` / `M06-C-R1控制箱与门锁协议校正`,真实 MySQL 8.4.10 已验证精确 Wire JSON、两阶段配对、结果失败状态、凭据脱敏、事件语义和原始遗嘱离线落库。
|
||||
- 下一工程目标:完成 M06-E-R1,依据智慧插座协议原件修正 `workInfo/localtask/protectOff/parameter/special` 的 wire schema、fixture、标准化字段和消息落库。
|
||||
|
||||
## 版本递进
|
||||
|
||||
|
||||
@@ -70,6 +70,13 @@ MYSQL_DATABASE=<以项目实际数据库名为准>
|
||||
- 后端使用 MQTT 3.1(`protocolVersion: 3`)和 QoS 1,订阅 `/devicesend/+`、`/devicewill/+`,发布 `/deviceaccept/{DeviceID}`。
|
||||
- `/app-api/ready`、`/admin-api/ready` 返回 `mqttConfigured`、`mqttConnected`、`mqttSubscriptionsReady`,只有真实连接并恢复订阅后后两项才为真。
|
||||
|
||||
### 硬件烟测变量
|
||||
|
||||
- 基础开关:`QIPAI_HARDWARE_SMOKE_ENABLE`、`QIPAI_HARDWARE_SMOKE_ALLOW_ACTIONS`、`QIPAI_HARDWARE_SMOKE_TIMEOUT_MS`。
|
||||
- 设备:`QIPAI_HARDWARE_CONTROL_BOX_DEVICE_ID`、`QIPAI_HARDWARE_SMART_SOCKET_DEVICE_ID`、`QIPAI_HARDWARE_SUB_LOCK_SUB_ID`、`QIPAI_HARDWARE_SUB_LOCK_SUBTYPE`。
|
||||
- `QIPAI_HARDWARE_SUB_LOCK_SUBTYPE` 只允许 `14`(701C)或 `15`(701G);缺少 subtype 时不得生成 `CtrlDevice` 实物动作。
|
||||
- MQTT 地址和账号复用 `QIPAI_HARDWARE_MQTT_URL`、`QIPAI_HARDWARE_MQTT_USERNAME`、`QIPAI_HARDWARE_MQTT_PASSWORD`,仅写 Git 忽略的本地配置或 `/etc/qipai/qipai.secrets`。
|
||||
|
||||
## 微信支付 v3
|
||||
|
||||
- 运行变量:`QIPAI_WECHAT_PAY_CREDENTIALS`。
|
||||
@@ -113,3 +120,4 @@ MYSQL_DATABASE=<以项目实际数据库名为准>
|
||||
- 2026-06-22:M05-C 增加 `QIPAI_THIRD_PARTY_CREDENTIALS`、人工/Mock/API 模式、回调 HMAC 和券码哈希规则。
|
||||
- 2026-06-22:M05-D 增加门店收款账户、`profitShareReceivers` 环境映射、分账授权状态和非生产 Mock 门禁。
|
||||
- 2026-08-10:总纲升级为 V5.6;同步最新源码接管、M09-A-RECOVERY 完成证据和 M06-C-R1 固定执行游标,既有凭据与配置位置不变。
|
||||
- 2026-08-10:M06-C-R1 增加门锁烟测 subtype 变量,确保实物 `CtrlDevice` 始终携带 14/15;未增加任何仓库内明文凭据。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# 当前开发成果基线
|
||||
|
||||
> V5.0 首次核验日期:2026-06-16
|
||||
> audited_commit: `9b2f055`
|
||||
> next_engineering_target: 按 V5.6 固定队列进入 M06-C-R1,依据智慧插座协议原件返工 wire schema、fixture 与消息落库
|
||||
> audited_commit: `dabc656`
|
||||
> next_engineering_target: 按 V5.6 固定队列进入 M06-E-R1,依据智慧插座协议原件返工 wire schema、fixture 与消息落库
|
||||
> 事实源:当前工作区、Git 历史、状态文档、Windows/WSL 检查脚本。
|
||||
|
||||
## 总体结论
|
||||
@@ -11,10 +11,10 @@
|
||||
|---|---|---|---|
|
||||
| 总纲版本 | V5.6 已成为当前权威总纲,V5.4 及更早版本仅作历史备份 | 根目录 `V5.6.md` 的第 29 章固定队列 | 必须按 V5.6 游标开发,不得回退到历史队列 |
|
||||
| Git 远端 | `origin=ssh://git@git.txyundm.cn:2222/panda/qipai.git`,分支 `main` | `git rev-list main...origin/main` 为 `0 0` | 本地与远端同步 |
|
||||
| 正式后端 | 已完成 Fastify、迁移兼容、outbox/worker、多应用租户、微信与后台密码身份/可撤销会话、六角色 RBAC、门店范围,以及 M03-M08 业务 API;M09-A 已完成保洁任务事务与并发收口 | `backend/src/**`、`database/migrations/**`、`backend/tests/**`、工程提交 `9b2f055` | M01-M04、M07 已完成;M05/M06/M08 可独立工程内容完成但外部联调保持 PARTIAL;M09-A-RECOVERY 已完成,当前进入 M06-C-R1 协议返工 |
|
||||
| 正式后端 | 已完成 Fastify、迁移兼容、outbox/worker、多应用租户、微信与后台密码身份/可撤销会话、六角色 RBAC、门店范围,以及 M03-M08 业务 API;M09-A 已完成事务收口,M06-C-R1 已完成控制箱与门锁协议纠偏 | `backend/src/**`、`database/migrations/**`、`backend/tests/**`、工程提交 `9b2f055`、`dabc656` | M01-M04、M07 已完成;M05/M06/M08 可独立工程内容完成但外部联调保持 PARTIAL;当前进入 M06-E-R1 智慧插座协议返工 |
|
||||
| 后台管理端 | 已建立 Vue3 + Vite + TypeScript + Element Plus 工程,完成正式租户账号登录、短期访问令牌、轮换刷新令牌、当前会话、注销、401 自动续期/清理和服务端权限菜单,并覆盖 M08-D 计划内运营工作区;应用页按平台/租户权限分层,敏感审计 metadata 递归脱敏且不读写 AppSecret | `admin/src/App.vue`、`admin/src/components/AdminLoginPanel.vue`、`admin/src/api.ts`、`backend/src/routes/admin-auth.ts`、`backend/src/auth/admin-auth-repository.ts`、`scripts/check-admin-m08-d.mjs` | M08-D 可独立工程内容完成;真实外部联调仍使 M08 保持 PARTIAL,游标进入 M09-A |
|
||||
| 微信小程序 | 已纳管微信原生模板,并完成顾客端订单、充值、权益明细、下单抵扣主体链路、保洁任务端照片上传/补做主体链路,以及管理员门店/房态/订单/代下单/验券/会员/员工/保洁/设备/经营统计 | `miniapp/pages/index`、`miniapp/pages/store/detail`、`miniapp/pages/room/detail`、`miniapp/pages/orders/*`、`miniapp/pages/recharge/*`、`miniapp/pages/profile/*`、`miniapp/pages/cleaner/*`、`miniapp/pages/manager/*`、`miniapp/utils/api.js`、`scripts/check-miniapp-m08-a.mjs`、`scripts/check-miniapp-m08-c.mjs` | M08-A/B/C/D 可独立工程内容完成,执行游标进入 M09-A;真实团购、微信和硬件现场验收保持外部阻塞,M08 维持 PARTIAL |
|
||||
| 数据库迁移 | 已形成 M01-B 至 M08-D 连续 up/down/verify 计划、最小脱敏 seed、旧库 fixture、执行 CLI、验证结果门禁和 MySQL 8 集成测试;M09-A 将真实保洁并发与事务场景纳入同一往返测试 | `database/migrations/**`、`database/seeds/2026061601_m01b_minimal_seed.sql`、`backend/src/db/migration-runner.ts`、`backend/tests/mysql-migration-roundtrip.test.mjs` | WSL MySQL 8.4.10 已完成 144 up、124 verify、140 down 往返;并实测并发 claim 单赢家、事件失败回滚、三种重指派、`SKIP LOCKED` 批量回收、已结算成员保护和订单 FINISHED 唯一建任务 |
|
||||
| 数据库迁移 | 已形成 M01-B 至 M08-D 连续 up/down/verify 计划、最小脱敏 seed、旧库 fixture、执行 CLI、验证结果门禁和 MySQL 8 集成测试;M09-A 事务并发和 M06-C-R1 协议落库均纳入同一往返测试 | `database/migrations/**`、`database/seeds/2026061601_m01b_minimal_seed.sql`、`backend/src/db/migration-runner.ts`、`backend/tests/mysql-migration-roundtrip.test.mjs` | WSL MySQL 8.4.10 已完成 144 up、124 verify、140 down;除 M09-A 并发外,实测两阶段配对、任务失败结果、未知结果协议死信、凭据脱敏、非 ACK 事件及裸遗嘱离线 |
|
||||
| M00 部署脚本 | 已有菜单、状态、HTTPS、Certbot、EMQX、备份检查模板 | `setup.sh`、`scripts/setup/`、`deploy/` | PARTIAL,生产未执行 |
|
||||
| 发布清单 dry-run | 可基于当前 HEAD 输出 `deployed=false` 的 release manifest,记录后端/后台/迁移尚未生成而跳过 | `scripts/setup/deploy-business.sh --dry-run .`、`scripts/dev/windows/check-release-manifest.ps1` | 可在 M00 验证结构;真实构建与生产发布待 M01/M09 后接入 |
|
||||
| 参考资料 | 已有清单、脱敏日志、页面/接口/表结构摘要 | `docs/reference-*`、`docs/db-schema-inventory.md` | PARTIAL,仍需按模块迁移正式实现 |
|
||||
@@ -24,7 +24,7 @@
|
||||
## 状态校准
|
||||
|
||||
- `docs/module-status.md` 中 M00 仍为 `PARTIAL` 是正确的:生产 Ubuntu 初始化、部署与运维验收尚未执行;后端、后台和小程序源码已在后续模块建立。
|
||||
- M01-M04 与 M07 已具备模块工程验收;M05、M06、M08 因真实厂商/硬件/生产条件保持 `PARTIAL`;M09-A-RECOVERY 已完成,当前按 V5.6 返回 M06-C-R1 内部协议返工,M10 尚未进入。
|
||||
- M01-M04 与 M07 已具备模块工程验收;M05、M06、M08 因真实厂商/硬件/生产条件保持 `PARTIAL`;M09-A-RECOVERY 与 M06-C-R1 已完成,当前按 V5.6 执行 M06-E-R1,M10 尚未进入。
|
||||
- 任何“目录存在”只能证明骨架存在,不能证明模块完成。
|
||||
|
||||
## Git 历史敏感信息核验
|
||||
@@ -35,6 +35,6 @@
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 进入 M06-C-R1:依据智慧插座协议原件修正 `workInfo`、本地任务、保护参数、特殊事件和遗嘱 payload 的 wire schema、fixture 与标准化落库。
|
||||
2. 随后执行 M06-E-R1 控制箱/门锁结果码与字段返工,再进入 M06-R-REGRESSION;四个 `check-*.mjs` 的中文/空格路径修复归入该回归阶段。
|
||||
1. 进入 M06-E-R1:依据智慧插座协议原件修正 `workInfo`、本地任务、保护参数、特殊事件的 wire schema、fixture 与标准化落库。
|
||||
2. 随后进入 M06-R-REGRESSION;四个 `check-*.mjs` 的中文/空格路径修复归入该回归阶段,并统一关闭协议资料缺失的历史问题。
|
||||
3. M06-G 真实硬件联调仍等待生产 MQTT 账号/ACL、DeviceID 和现场实物配线;该外部阻塞不阻断内部 R1 队列。
|
||||
|
||||
@@ -14,3 +14,11 @@
|
||||
- 设备事件按租户、设备、Topic 和 payload 哈希唯一;重复消息只增加计数。
|
||||
- 死信按 Topic 和 payload 哈希唯一。
|
||||
- down 迁移仅删除 M06-C 三张表,不影响设备资产和拓扑。
|
||||
|
||||
## M06-C-R1 语义收口(2026-08-10)
|
||||
|
||||
- 本阶段不新增表或迁移版本;沿用既有 JSON 与状态列修正协议语义。
|
||||
- 未知厂商结果的事件写 `processing_status=PROTOCOL_ERROR`,原结果保留在 `raw_payload`,标准化结果写 `UNKNOWN_VENDOR_RESULT`,相关命令写 `FAILED/UNKNOWN_VENDOR_RESULT`,并新增协议死信和开放告警。
|
||||
- 门锁密码/卡号请求和 `record.content` 在写入 `request_payload/raw_payload/normalized_payload/response_payload` 前哈希与脱敏。
|
||||
- `AddDevice` 首 ACK 保持命令 `PUBLISHED`,携带 `subtype/subID` 的最终 ACK 才转 `ACKED` 并创建 701C/701G 拓扑。
|
||||
- WSL MySQL 8.4.10 一次性数据库已验证上述语义及裸 `devicewill=close` 离线落库;完整迁移往返仍为 144 up、124 verify、140 down。
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
- 起始 commit:`c96045f`
|
||||
- 工程 commit:`e795cdb`
|
||||
- ENGINEERING_DELTA=YES
|
||||
- 子阶段状态:DONE(可独立工程范围);PDF 原件复核为外部阻塞
|
||||
- 子阶段状态:M06-C-R1 DONE;实物行为仍为 M06-G 外部阻塞
|
||||
|
||||
## 工程增量
|
||||
|
||||
@@ -25,10 +25,22 @@
|
||||
- 非法 Topic 实测进入 `qipai_iot_dead_letters`。
|
||||
- 工程 commit 已 push,`HEAD == origin/main == e795cdb6935568611a5d27d78991bf9e7ee2f7df`。
|
||||
|
||||
## M06-C-R1 协议纠偏(2026-08-10)
|
||||
|
||||
- 工程 commit:`dabc656`
|
||||
- `PlayTTS` 由友好 DTO 生成精确 `vol/firstPlay/loop/speaker/style/speed/intona/id`,并按原件范围校验。
|
||||
- `AddDevice` 只发送 `time`;首个无 `subtype/subID` 的 ACK 不提前结束配对,最终包才 ACK 并固化父子拓扑。
|
||||
- `CtrlDevice` 强制 `subtype=14/15`,凭据使用 `value`;密码为连续 6 位分组、卡号为连续 8 位十六进制分组,清空全部和恢复出厂均有平台超管二次确认。
|
||||
- 上行按命令判别结果;未知结果落 `UNKNOWN_VENDOR_RESULT`、失败命令、协议告警和死信,不崩溃、不误 ACK。
|
||||
- `record` 与命令凭据在命令、事件、死信持久化前哈希/脱敏;`magstate/taskfinish/Poweron/connected` 保持事件语义。
|
||||
- `/devicewill/{DeviceID}` 接受原始 `close` 并更新离线,不进入 JSON 解析死信。
|
||||
- Windows 后端全量 `npm test` 通过;WSL MySQL 8.4.10 原生副本完成 144 up、124 verify、140 down 的 `up → verify → down → up → verify`,并实测上述命令状态、配对、脱敏、事件和遗嘱落库。
|
||||
- 工程提交已 push,`HEAD == origin/main == dabc656f6319235f1f35106da493d24ced37d19a`。
|
||||
|
||||
## 资料边界
|
||||
|
||||
当前工作区与现有压缩包未找到 V5.4 点名的两份协议 PDF。实现依据为 V5.4 已固化的协议章节;PDF 页码级复核登记为 `ISSUE-013/BLOCKED_EXTERNAL`。
|
||||
V5.6 已记录并固化两份厂商协议原件的审计差异,资料缺失不再构成外部阻塞。当前未具备的是实物、生产 DeviceID、MQTT 账号/ACL 和现场配线,继续登记在 M06-G。
|
||||
|
||||
## 后续
|
||||
|
||||
执行游标进入 M06-D:控制箱和门锁业务能力。
|
||||
执行游标进入 M06-E-R1:智慧插座 Wire schema、标准化状态、保护事件和数据库告警纠偏。
|
||||
|
||||
@@ -91,11 +91,11 @@
|
||||
| BKG-007 | 后台微信支付配置 | M05-D/M08 | PARTIAL | `4eac99d` | 已提供收款账户、分账接收方、门店/全局比例策略和授权状态 API;Vue 后台支持环境引用配置、授权状态、脱敏接收方、比例策略、分账记录、微信退款、对账单请求和分账执行;私钥/APIv3 Key 不读取或回显。M08-B 保洁转账预检仍提供商户资料与转账前阻断。 | 真实商户与服务商授权、微信后台场景报备和生产小额退款/分账仍需现场联调。 | 授权后完成生产退款、对账与分账验收。 |
|
||||
| DEV-003 | 设备管理 | M06-B/M08 | PARTIAL | `5c9fd69` | 已实现并在管理员小程序/Vue 后台展示 DeviceID、IMEI/ICCID、型号、固件、信号、能力、状态快照、控制通道、Sub-1G 父子拓扑、开放告警和维护记录;后台可按授权门店入库、绑定、维护并下发门锁/控电/插座命令。 | 真实硬件在线、ACK、计量和保护断电仍需 M06-G 实物更新。 | 取得实物和生产 MQTT 条件后执行硬件矩阵并回填命令 ACK 证据。 |
|
||||
| BKG-004 | 后台设备管理 | M06-B/M08 | PARTIAL | `5c9fd69` | Vue 后台已接入设备入库、列表、拓扑、通道绑定、Sub-1G 绑定、告警、维护和现场控制;同一房间控制目标唯一,危险命令二次确认,并明确“发布不等于 ACK”。 | 真实设备扫码输入和现场结果未验证。 | M06-G/M10 以真实控制箱、门锁和插座完成扫码入库与控制验收。 |
|
||||
| IOT-006 | MQTT 消息幂等 | M01/M06-C | DONE | `e795cdb` | 上行按租户、设备、Topic 和 payload SHA-256 唯一;QoS 1 重复消息只增加 `receive_count`,不重复更新命令或设备副作用;WSL MySQL 8.4.9 实测两次 ACK 仅一条事件。 | - | M06-D/E 继续复用同一消费链路。 |
|
||||
| IOT-007 | 命令状态机 | M01/M06-C | DONE | `e795cdb` | 已实现 `PENDING/PUBLISHED/ACKED/FAILED/TIMEOUT/UNKNOWN/CANCELLED` 数据模型,发布失败、ACK 结果、超时和 13 位命令 ID 均有测试;发布成功不等于 ACK。 | - | M06-D/F 接入业务权限、补偿与过期取消。 |
|
||||
| IOT-006 | MQTT 消息幂等 | M01/M06-C | DONE | `dabc656` | 上行按租户、设备、Topic 和 payload SHA-256 唯一;QoS 1 重复消息只增加 `receive_count`,不重复更新命令或设备副作用;WSL MySQL 8.4.10 实测两次 ACK 仅一条事件,裸遗嘱也走同一去重入口。 | - | M06-E-R1 继续复用同一消费链路。 |
|
||||
| IOT-007 | 命令状态机 | M01/M06-C | DONE | `dabc656` | `PENDING/PUBLISHED/ACKED/FAILED/TIMEOUT/UNKNOWN/CANCELLED` 数据模型可用;结果按命令判别,未知结果持久化为 `UNKNOWN_VENDOR_RESULT` 并失败命令、写告警/死信;AddDevice 首 ACK 不提前完成。 | - | M06-E-R1 补齐插座命令结果判别。 |
|
||||
| DEV-001 | 一键开门与设备动作 | M06-D/M06-F/M08 | PARTIAL | `874b9b8` | 已提供控制箱控电、磁力锁、TTS、LED、订单任务、Sub-1G 门锁和智慧插座控制服务;M08-A 新增顾客端订单权限开门入口,按本人有效订单和时间窗口校验后下发普通开门命令,命令返回 PUBLISHED 而非假成功;顾客端续费/同门店换房入口已接入订单调整 API。 | 真实硬件属于 M06-G;小程序真机开门、续费/换房后的设备动作仍待现场联调。 | 取得硬件后执行真实开门、续费和换房设备联动矩阵。 |
|
||||
| IOT-002 | 控制箱接入 | M06-D | PARTIAL | `d15fd3f` | `ConctolPower/Crldoor/PlayTTS/stopTTS/CrlLED/task/addtask/canceltask` 已通过适配器、命令持久化和 API 接入。 | 缺控制箱实物逐路负载、门磁、TTS 和任务回包联调。 | M06-G 执行实物矩阵。 |
|
||||
| IOT-003 | Sub-1G 门锁绑定 | M06-D | PARTIAL | `d15fd3f` | `AddDevice` 下发、超时窗口、回包 subID/subtype、701C/701G 型号映射和父子拓扑自动固化已实现。 | 缺现场 `*789#` 与实物配对。 | M06-G 现场配对、超时和换绑验收。 |
|
||||
| IOT-004 | Sub-1G 门锁控制 | M06-D | PARTIAL | `d15fd3f` | `CtrlDevice` 开关门、密码/卡片和恢复出厂适配器已实现;危险清空/恢复出厂仅平台管理员加确认短语;record 内容哈希脱敏,低电量及 timeout/full/unconfirm 告警。 | 缺 701C/701G 实物及密码/卡片现场验收。 | M06-G 完成实物控制与故障场景。 |
|
||||
| IOT-002 | 控制箱接入 | M06-D | PARTIAL | `dabc656` | `PlayTTS` 已精确发送 `vol/firstPlay/loop/speaker/style/speed/intona` 并按原件范围校验;任务 busy/unconfirm/fail 均保持失败,`record/magstate/taskfinish/Poweron/connected` fixture 与 MySQL 落库通过。 | 缺控制箱实物逐路负载、门磁、TTS 和任务回包联调。 | M06-G 执行实物矩阵。 |
|
||||
| IOT-003 | Sub-1G 门锁绑定 | M06-D | PARTIAL | `dabc656` | `AddDevice` 已发送 `time`;首 ACK 保持 PUBLISHED,最终 subID/subtype 回包才 ACK 并自动固化 701C/701G 父子拓扑,真实 MySQL 已验证。 | 缺现场 `*789#` 与实物配对。 | M06-G 现场配对、超时和换绑验收。 |
|
||||
| IOT-004 | Sub-1G 门锁控制 | M06-D | PARTIAL | `dabc656` | `CtrlDevice` 强制 subtype 14/15,密码/卡片使用 `value` 并精确校验、持久化前哈希脱敏;清空全部和恢复出厂仅平台管理员加确认短语;timeout/full/unconfirm 不会成功 ACK。 | 缺 701C/701G 实物及密码/卡片现场验收。 | M06-G 完成实物控制与故障场景。 |
|
||||
| IOT-005 | 智慧插座接入 | M06-E | PARTIAL | `9144fa8` | `basicInfo/workInfo` 查询、`on/off`、`localtask/clearTask` 已通过适配器、命令持久化和后台 API 接入;本地任务限制 20 条;过载、过温、过流、过压/欠压、功率和温度阈值写入设备告警;Windows 全量后端回归通过。 | 缺 4G 智慧插座实物、DeviceID、生产 MQTT 账号/ACL 和现场负载,未执行真实计量与保护断电联调。 | M06-F 接入订单自动联动;M06-G 完成实物计量、开关、本地任务和保护事件矩阵。 |
|
||||
| IOT-008 | 设备告警与离线 | M06/M10 | PARTIAL | `d01f771` | `/devicewill/{DeviceID}` 可更新离线状态;低电量、timeout/full/unconfirm、插座过载、过温、过流、过压/欠压、功率和温度阈值可写入开放告警;订单联动任务失败会进入异步任务重试/补偿;真实硬件烟测运行器可等待 ACK 并输出 JSON 报告。 | 缺真实硬件离线、保护断电、任务结束和弱信号事件矩阵。 | 取得实物和生产 MQTT 账号后执行硬件烟测矩阵;当前旁路进入 M07-A。 |
|
||||
| IOT-008 | 设备告警与离线 | M06/M10 | PARTIAL | `dabc656` | `/devicewill/{DeviceID}` 已兼容原始 `close` 并在 MySQL 标记 OFFLINE,不进入非法 JSON 死信;低电量、timeout/full/unconfirm 和未知结果可写开放告警。智慧插座保护告警旧字段结论已撤销,等待 M06-E-R1 按 `special.closeReason` 重建。 | 缺真实硬件离线、保护断电、任务结束和弱信号事件矩阵。 | 先完成 M06-E-R1,再由 M06-G 执行实物烟测。 |
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
| 设备 | 当前资料 | 状态 | 下一步 |
|
||||
|---|---|---|---|
|
||||
| 4G 智能门禁控电箱 | V5.4 已固化命令与字段;PDF 原件未在当前仓库找到 | PARTIAL | M06-D 完成业务权限和控制;取得 PDF 后逐页复核。 |
|
||||
| Sub-1G 智能门锁 | V5.4 已固化 `AddDevice/CtrlDevice`、subID/subtype 和结果码;PDF 原件缺失 | PARTIAL | M06-D 完成绑定、控制、安全门禁与事件。 |
|
||||
| 4G 智慧插座 | V5.4 已固化查询、开关、本地任务和事件;PDF 原件缺失 | PARTIAL | M06-E 已完成查询、开关、本地任务和保护告警;M06-G 补实物计量与保护断电矩阵。 |
|
||||
| 4G 智能门禁控电箱 | 两份厂商协议原件的审计结论已固化到 V5.6;M06-C-R1 已校正 TTS、结果码、事件和原始遗嘱 | PROTOCOL_FIXTURE_PASS | M06-G 取得实物后验证逐路负载、TTS、门磁和任务回包。 |
|
||||
| Sub-1G 智能门锁 | 原件已确认 `AddDevice.time`、`CtrlDevice.subtype/subID/value` 与密码/卡号格式 | PROTOCOL_FIXTURE_PASS | M06-G 以 701C/701G 实物验证配对、开锁、凭据和故障结果。 |
|
||||
| 4G 智慧插座 | 原件差异已审计并列入 V5.6;旧实现仍含不兼容本地任务和假告警字段 | M06-E-R1 DOING | 立即完成 `workInfo/localtask/protectOff/parameter/special` 校正,再由 M06-G 补实物矩阵。 |
|
||||
| EMQX Broker | 固定主机 `101.42.38.246`;已生成安装说明、ACL 模板、菜单检查和硬件烟测运行器 | PARTIAL | 生产 Ubuntu 安装、端口限制、账号 ACL、DeviceID 和实物到位后运行 `node dist/devices/hardware-smoke-runner.js`。 |
|
||||
|
||||
协议资料可用不等于实物验收通过。当前仅可声明 `PROTOCOL_FIXTURE_PASS`;控制箱、门锁、插座、生产 DeviceID、MQTT 账号/ACL 和现场配线仍属于 M06-G `BLOCKED_EXTERNAL`。
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
```yaml
|
||||
execution_cursor:
|
||||
current_module: M06
|
||||
current_stage: M06-C-R1
|
||||
current_stage: M06-E-R1
|
||||
stage_status: DOING
|
||||
last_completed_stage: M09-A-RECOVERY
|
||||
next_stage: M06-E-R1
|
||||
last_engineering_commit: `9b2f055`
|
||||
last_completed_stage: M06-C-R1
|
||||
next_stage: M06-R-REGRESSION
|
||||
last_engineering_commit: `dabc656`
|
||||
last_push_verified: true
|
||||
base_branch: main
|
||||
blocked_reason: "M08-A 真机合法域名、真实微信支付和实物开门验证缺微信后台/商户/硬件现场条件;M08-B 可独立工程内容已完成,真实商户凭据、微信后台配置、生产小额转账和实物硬件结果保持 BLOCKED_EXTERNAL;M08-C 可独立工程内容已完成,真实美团/抖音/快手商家授权与真机验券保持 BLOCKED_EXTERNAL,已按规则旁路进入 M08-D。M06-G 真实硬件联调仍缺生产 MQTT 账号/ACL、DeviceID、控制箱、门锁、插座和现场配线。"
|
||||
updated_at: 2026-08-10T14:48:36+08:00
|
||||
updated_at: 2026-08-10T16:02:09+08:00
|
||||
```
|
||||
|
||||
| 模块 | 状态 | 最近提交 | 最近开发日志 | 备注 |
|
||||
@@ -22,7 +22,7 @@ execution_cursor:
|
||||
| M03 门店、房间、价格、营业时间 | DONE | `d563078` | docs/devlogs/2026-06-18-M03-D-场景码NFC与WiFi.md | M03-A/B/C/D 已完成门店房间、装修广告、媒体、地图选店、场景码/NFC 页面导航和受控 Wi-Fi;真实微信小程序码图片生成留待 M08 真机联调。 |
|
||||
| M04 订单、时段锁定、支付闭环 | DONE | `91801fe` | docs/devlogs/2026-06-20-M04-D-订单分享.md | M04-A/B/C/D 已完成可信定价、并发预占、订单状态机、续费取消换房、管理员调整、代下单和最小权限分享;Windows 全量回归与 WSL MySQL 8.4.9 模块回归通过。 |
|
||||
| M05 会员、余额、套餐、优惠券 | PARTIAL | `1680d73` | docs/devlogs/2026-06-22-M05-D-分账与收款配置.md | M05-A/B/C/D 工程闭环已完成:统一支付、微信支付退款、团购直订、门店收款账户、分账接收方、比例策略、授权门禁、幂等分账和对账查询均通过 Windows 与 WSL MySQL 回归;真实微信/团购/分账权限未提供,模块保持 PARTIAL/BLOCKED_EXTERNAL。 |
|
||||
| M06 设备、MQTT 与真实硬件联动 | PARTIAL | `d01f771` | docs/devlogs/2026-06-24-M06-G-真实硬件联调.md | M06-A 至 F 原工程存在,但 V5.6 审计确认协议 fixture/映射与两份厂商原件不一致;当前进入 M06-C-R1/M06-E-R1 内部返工。M06-G 仍缺生产 MQTT 账号/ACL、DeviceID 和实物配线,保持 BLOCKED_EXTERNAL。 |
|
||||
| M06 设备、MQTT 与真实硬件联动 | PARTIAL | `dabc656` | docs/devlogs/2026-06-22-M06-C-协议适配与消息幂等.md | M06-C-R1 已按原件校正控制箱/Sub-1G Wire JSON、结果、事件、脱敏和裸遗嘱并通过真实 MySQL;当前进入 M06-E-R1 智慧插座返工。M06-G 仍缺生产 MQTT 账号/ACL、DeviceID 和实物配线,保持 BLOCKED_EXTERNAL。 |
|
||||
| M07 会员、余额、充值、优惠券和套餐营销 | DONE | `ed0d455` | docs/devlogs/2026-06-24-M07-D-会员管理.md | M07-A 已完成现金/赠送双余额账本;M07-B 已完成充值优惠;M07-C 已完成优惠券/套餐权益底表和冻结、确认、退回的可靠补偿核销服务;M07-D 已完成会员画像、订单、消费、余额、充值、优惠券和套餐聚合查询。 |
|
||||
| M08 微信原生小程序完整业务 | PARTIAL | `0511008` | docs/devlogs/2026-08-10-M08-D-Vue平台后台.md | M08-A/B/C/D 可独立工程内容已完成;Vue 后台已覆盖正式密码登录、短期访问令牌、轮换刷新令牌、401 清理、服务端权限菜单及计划内运营工作区。真实微信、团购和硬件现场验收按 BLOCKED_EXTERNAL 保持 PARTIAL,执行游标已旁路进入 M09-A。 |
|
||||
| M09 保洁任务、结算、商品和库存 | DOING | `9b2f055` | docs/devlogs/2026-06-25-M08-B-保洁端.md | M09-A-RECOVERY 已完成:状态、负责人/成员和事件同事务;真实 MySQL 8.4.10 已验证 claim 单赢家、失败回滚、重指派清理、`SKIP LOCKED` 回收和订单唯一建任务。按 V5.6 固定队列暂返 M06-R1,完成后再进入 M08-D-R1/M09-B。 |
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# MQTT 协议映射
|
||||
|
||||
M06-C 已按 V5.4 中固化的厂商协议字段实现适配器、上行解析、命令关联、消息幂等与死信。仓库当前未找到总纲点名的两份 PDF 原件,因此尚不能完成 PDF 页码级复核;不得把此状态写成“PDF 已阅读”。
|
||||
M06-C-R1 已依据 V5.6 中完成的两份厂商协议原件审计,校正控制箱与 Sub-1G 门锁的 Wire JSON、上行结果、事件、脱敏和离线处理。智慧插座的原件差异已识别,当前游标在 M06-E-R1,未完成前不得沿用旧 `powerW/temperature/overLoad` 假字段作为有效协议结论。
|
||||
|
||||
| 设备 | Topic/命令 | 方向 | 字段 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| 4G 智能门禁控电箱 | `/devicesend/{DeviceID}`、`/devicewill/{DeviceID}`、`/deviceaccept/{DeviceID}` | 双向 | `basicInfo/mqttConfig/startVoice/task/taskconfig`、`ConctolPower`、`Crldoor`、`PlayTTS/stopTTS`、`CrlLED`、`task/addtask/canceltask` | PARTIAL |
|
||||
| Sub-1G 智能门锁 | 经父控制箱使用相同三个 Topic | 双向 | `AddDevice`、`CtrlDevice`;`open/close/setkey/delkey/setcard/delcard/factoryreset` | PARTIAL |
|
||||
| 4G 智慧插座 | `/devicesend/{DeviceID}`、`/devicewill/{DeviceID}`、`/deviceaccept/{DeviceID}` | 双向 | `basicInfo/workInfo`、`on/off`、`localtask`、`clearTask`;过载、过温、过流、过压/欠压、功率和温度阈值告警 | PARTIAL |
|
||||
| 4G 智能门禁控电箱 | `/devicesend/{DeviceID}`、`/devicewill/{DeviceID}`、`/deviceaccept/{DeviceID}` | 双向 | `basicInfo/mqttConfig/startVoice/task/taskconfig`、`ConctolPower`、`Crldoor`、`PlayTTS/stopTTS`、`CrlLED`、`task/addtask/canceltask` | PROTOCOL_FIXTURE_PASS |
|
||||
| Sub-1G 智能门锁 | 经父控制箱使用相同三个 Topic | 双向 | `AddDevice`、`CtrlDevice`;`open/close/none/setkey/delkey/setcard/delcard/factoryreset` | PROTOCOL_FIXTURE_PASS |
|
||||
| 4G 智慧插座 | `/devicesend/{DeviceID}`、`/devicewill/{DeviceID}`、`/deviceaccept/{DeviceID}` | 双向 | `basicInfo/workInfo/localtask/mqttConfig`、`on/off`、`localtask/clearTask`、保护配置与特殊断电事件 | M06-E-R1 DOING |
|
||||
|
||||
## M06-A ACL 基线
|
||||
|
||||
@@ -22,7 +22,18 @@ M06-C 已按 V5.4 中固化的厂商协议字段实现适配器、上行解析
|
||||
|
||||
- 命令 ID 只允许 1-13 位数字,默认生成 10 位秒时间戳加 3 位滚动序号。
|
||||
- 下发先写 `qipai_iot_commands=PENDING`,MQTT 发布成功后转 `PUBLISHED`,有效 ACK 才转 `ACKED`。
|
||||
- `fail/busy/unconfirm/timeout/full` 统一转 `FAILED` 并保留厂商结果码;超时扫描可把未回包命令转 `TIMEOUT`。
|
||||
- 上行先校验 Topic、资产 DeviceID 和 JSON;异常 Topic、未知设备、非法 JSON/字段进入 `qipai_iot_dead_letters`。
|
||||
- 结果按命令判别:`task` 接受 `ok/busy/fail/unconfirm`,`CtrlDevice` 接受 `ok/fail/timeout/full`,`PlayTTS` 接受 `ok/paraerror`;其他已知结果还包括 `error/update`。
|
||||
- 未知或不属于当前命令的结果保存原值并标准化为 `UNKNOWN_VENDOR_RESULT`,命令转 `FAILED`,同时写协议告警和死信;不得让消费进程崩溃或误判成功。
|
||||
- 上行先校验 Topic、资产 DeviceID 和消息边界;异常 Topic、未知设备、非法 JSON/字段进入 `qipai_iot_dead_letters`。`/devicewill/{DeviceID}` 明确兼容原始文本 `close`,此情形直接更新离线状态,不作为非法 JSON。
|
||||
- QoS 1 重复消息命中唯一键后只增加 `receive_count`,不重复执行 ACK、状态快照或后续业务副作用。
|
||||
- 原始 JSON 与标准化 JSON 分开保存;协议字段大小写和拼写不得在适配器外重新拼装。
|
||||
- 原始 JSON 与标准化 JSON 分开保存;`record.content` 和门锁密码/卡号 `value` 在持久化前只保留 SHA-256 与脱敏尾号,协议字段大小写和拼写不得在适配器外重新拼装。
|
||||
|
||||
## M06-C-R1 精确出站映射
|
||||
|
||||
| 领域输入 | Canonical Wire | 约束 |
|
||||
|---|---|---|
|
||||
| TTS `volume/firstPlay/loop/speaker/style/speed/intonation` | `action=PlayTTS` + `vol/firstPlay/loop/speaker/style/speed/intona/id` | `vol 0-10`、`firstPlay 0/1`、`speaker 0-5`、`style 0-2`、`speed/intona 0-10` |
|
||||
| 配对等待 `timeout` | `action=AddDevice,time,id` | 首个无 `subtype/subID` 的 `ok` 只表示进入配对窗口;最终包才将命令 ACK 并固化拓扑 |
|
||||
| 门锁动作 | `action=CtrlDevice,subtype,subID,order,id[,value]` | `subtype` 仅 14/15;密码按连续 6 位分组,卡号按连续 8 位十六进制分组;卡号发送大写 |
|
||||
|
||||
`delkey/delcard value=all` 与 `factoryreset` 仅平台管理员加固定确认短语可下发;凭据管理至少要求门店管理员权限。`magstate`、`taskfinish`、`Poweron`、`connected` 和 `record` 均按事件处理,不进入命令 ACK。
|
||||
|
||||
Reference in New Issue
Block a user