# 💧 水厂智能货柜(IoT)分布式终端接入与自动化交付技术白皮书 ## 一、 业务愿景与战略定位 本方案旨在通过 **IoT(物联网)** 硬件矩阵,实现水厂饮用水交付的全面自动化与去人工化。针对**无屏幕、定位提货、套餐保值**等核心需求,构建“线上订水、LBS 匹配、无感交付”的智慧物流体系。 --- ## 二、 核心应用场景与业务需求模型 ### 1. 定位提货与套餐保值逻辑 * **需求:** 用户购买桶水套餐,不受后续调价影响;定位用户小区并呈现所有单元楼提水点,实现远程库存预览,防止用户“跑空”。 * **小程序实现:** * **权益钱包**:引入“虚拟储水池”概念,用户购买套餐后,账户记录为“待取桶数”,而非金额,实现锁价保值。 * **LBS 智能网格**:首页通过 `uni.getLocation` 获取坐标,服务器根据经纬度反向检索关联小区,并在地图上以“桩位”形式展示该小区内所有单元楼下对应的提柜状态(空闲/库存数)。 * ****【新增机制:空柜自动调导 (Self-Correction)】****:当某单元楼货柜库存为 0 时,地图图标转为置灰状态并显示“补货中”,同时系统自动计算并推荐该小区内距离最近的“有货柜机”。 ### 2. 无屏幕式“无感核销”模式(蓝牙/云端直控) * **需求:** 货柜感应 + 云端瞬时指令”**模式。 * **操作流**:用户靠近货柜 $\rightarrow$ 手机蓝牙自动识别设备号(Beacon 广播)或 LBS 确认经纬度重合 $\rightarrow$ 小程序自动弹出“当前已到达XX单元提水点” $\rightarrow$ 用户在手机点击“开门” $\rightarrow$ 云端通过 MQTT 指令开锁。 * **价值**:降低硬件成本(无屏、防暴力),提升交互流畅度。 ### 3. 故障闭环与客服联动系统 * **需求:** 下单不开门、没电、库存不足等异常,自动切入客服协助。 * **业务逻辑:** 1. **主动监测**:系统 15 秒内未收到门磁反馈,自动触发“开启失败弹窗”。 2. **一键路由**:弹窗直接集成“在线客服”与“紧急开锁申请”。对于电池电量低于 10% 或库存为 0 的柜体,小程序端自动置灰并置顶显示“联系客服维修/补货”。 ### 4. 商家端(水厂)实时监控看板 * **需求:** 实时获取补货、电量、库存等全量信息。 * **技术看板:** * **IoT 设备画像**:每个柜子都有实时“血条”(电量指示)和“胃容积”(库存比例)。 * **热力算法**:根据库存消耗频率,自动标注哪些柜子属于“急需补货”级别。 ### 5. 补货员/检修员管理系统(工单派发制) * **需求:** 考核规定时间内补货及检修。 * **小程序程序设定:** * **强时效工单**:系统检测到库存不足或电池耗尽,自动生成“4小时响应工单”指派给最近的运维员。 * **到岗打卡**:运维员必须到达柜体 5 米范围内(经纬度校验),才能开启“运维门”进行操作。 * **闭环报告**:补货完成后,自动上报最新重量数据,系统同步更新前台库存。 --- ## 三、 全链路技术架构与数据流向 ### 1. 四层架构模型 * **物理执行层(Edge)**:基于 ESP32/工业级 4G 模组的主控板,集成继电器、重力传感器、温湿度计。 * **网络传输层(Network)**:采用 **MQTT 协议**,基于 TLS/SSL 加密,确保指令在复杂小区环境下的秒级送达。 * **业务逻辑层(Service)**:负责权益校验、库存动态调拨、支付分账逻辑判断。 * **应用展示层(Application)**:用户小程序(取水/充值)、商家管理后台(核销)、补货员 App(工单管理)。 ### 2. 高级交互序列图 (Sequence Diagram) `mermaid sequenceDiagram participant U as 消费者小程序 participant S as 业务中台 (PHP/Node.js) participant M as MQTT 消息总线 (EMQX) participant C as 智能货柜终端 participant P as 微信支付分/代金券接口 U->>S: 1. 扫码查阅柜体 (LBS+设备ID) S-->>U: 2. 返回可用库存 & 专属优惠券 U->>S: 3. 点击“确认取水” (权益预扣) S->>P: 4. 冻结余额/校验代金券状态 P-->>S: 5. 状态确认 S->>M: 6. 下发指令 (QoS 1: 至少送达一次) M->>C: 7. 物理开门指令 (带加密Nonce) C->>C: 8. 传感器检测门启 C->>M: 9. 实时反馈:门已开 M-->>U: 10. 小程序提示:请取水 Note over C: 用户提取桶装水... C->>C: 11. 传感器检测门闭 & 重量减扣 C->>M: 12. 最终交易报文 (补货建议点) M->>S: 13. 结算请求 S->>S: 14. 正式扣减权益 & 生成财务报表 ` --- ## 四、 通信协议与数据字典规范 ### 1. 指令安全加固 采用 **HMAC-SHA256** 对指令进行签名,防止中间人攻击或恶意开门。 Payload 样本: `json { "header": { "sn": "WH-CAB-2024-001", "ver": "1.2.0", "nonce": "8h7g2k1l" }, "body": { "action": "REMOTE_OPEN", "params": { "slot": 1, "timeout": 30 }, "sign": "5e8f...f2a1" } } ` ### 2. 状态机定义 (State Machine) * IDLE: 空闲状态,等待指令。 * LOCKED: 权益校验通过,正在下发脉冲。 * BUSY: 用户正在交互(取水进行中)。 * MAINTENANCE: 故障或补货模式,小程序下线该节点。 --- ## 五、 核心功能模块代码深度实现 ### 1. 智能防刷与补偿逻辑 (小程序/后端) **问题场景**:用户点了开门但信号不好,或者门坏了没开,如何保证不误扣费? `javascript // 后端:具备“事务性”的开门逻辑 async function secureOpenProcess(userId, cabinetId) { const transaction = await db.startTransaction(); try { // 1. 锁券:先将福利券/水票设为“占用中” await transaction.collection('vouchers').update(query, { status: 'PENDING' }); // 2. 下发异步指令,设置 15 秒确认窗口 const result = await mqttService.publishWithAck(cabinetId, 'open', 15000); if (result.ack === 'SUCCESS') { await transaction.commit(); // 指令送达,提交事务 return { success: true }; } else { throw new Error('DEVICE_OFFLINE'); } } catch (e) { await transaction.rollback(); // 失败回滚,水票自动返还 return { success: false, reason: e.message }; } } ` ### 2. 补货员端:基于路径优化的库存盘点 `python # 逻辑伪代码:根据告警级别生成最优补货路径 def generate_refill_route(warn_cabinets): # 排列优先级:告警等级(0-100) > 距离 priority_list = sorted(warn_cabinets, key=lambda x: (x.alert_level, x.distance)) return priority_list # 返回给补货员 App 的任务流 ` --- ## 六、 智能货柜接入小程序的标准化流程 (Access Standard) ### 1. 核心逻辑:如何核验并完成取水(从下单到核销) 针对你疑惑的“下单后如何核验取水”,本项目采用 **“虚拟权益池 + 动态指令核销”** 机制。以下是详细的核验方案: #### A. 权益发放(下单阶段) 1. **资产化**:用户下单购买后,系统不只是生成一个订单,而是在数据库中为用户 `OpenID` 增加“电子水票/桶数”资产(如:可用余额 +10 桶)。 2. **权益凭证**:系统生成一组不记名的电子权益 ID,状态标记为 `UNUSED`(未使用)。 #### B. 身份与位置核验(扫码阶段) 1. **设备匹配**:用户扫码,小程序获取 `cabinet_id`。系统即刻下发 **MQTT PING** 指令确认柜机通讯链路活跃。 2. **位置强校验 **(针对无蓝牙环境增强)****: * 小程序调用 `uni.getLocation` 获取手机经纬度。 * **后端比对**:将手机位置与柜子的注册坐标进行计算(Haversine 公式)。 * **判定**:距离 < 50 米时,判定为“到店”,激活“开门按钮”;否则提示“请到达柜机旁操作”。 3. **在线预警**:若 MQTT 链路超时未响应,按钮置灰并提示“柜机离线中,请稍后再试”,防止用户重复扣款。 #### C. 权益核销(开门阶段) 1. **预锁定**:用户点击“确认开门”,后端立即执行 `Transaction`(事务): * 查询用户是否有可用余额。 * 将 1 份权益设为 `LOCKING`(锁定中),防止并发重复开启。 2. **指令下发**:通过 MQTT 向货柜发送 `UNLOCK_CABINET` 指令。 3. **状态反馈**: * **成功**:货柜反馈“门已开启”,权益标记为 `USED`(已使用),生成核销流水。 * **失败**:若 15 秒内未收到开门反馈,直接接入客服系统,让客服处理这笔订单。 ### 2. 身份识别与设备绑定(参数二维码体系) * **二维码本质**:机身二维码并非静态图片,而是携带设备 ID 的“动态索引链接”(例如:https://domain.com/q?id=10001)。 * **批量生产规范**: * **映射逻辑**:后端建立 设备SN - 设备ID - 二维码URL 的 1:1 映射表。 * **自动化生成**:通过 Node.js/Python 脚本调用 qrcode 库,根据数据库 ID 批量生成 100+ 物理贴纸。 * **施工校验**:印刷贴纸需附带明文编号,安装时由运维端扫码并上传 LBS 坐标,完成“人-机-地”三位一体绑定。 ### 2. “扫码即看”的信息同步机制 * **跳转逻辑**:利用微信“普通链接二维码跳转小程序”协议,所有货柜二维码均指向同一个小程序页面。 * **动态解析流程**: 1. **取参**:小程序在 onLoad(options) 中解析 options.q 获取 cabinet_id。 2. **溯源**:小程序以该 ID 为 Key,实时请求云端接口 /api/cabinet/info。 3. **渲染**:后端实时查询该柜体的 IoT 状态(库存剩几桶、电池余量、是否维修),前端实现“千柜千面”的精准显示。 ### 3. 前端交互与权限校验逻辑 `javascript // 基于 UniApp 的扫码取水核心逻辑 async function startWithdrawWater(cabinetId) { // A. 获取用户地理位置,确保在柜机旁 const location = await uni.getLocation({ type: 'gcj02' }); // B. 调用后端校验接口:余额充值情况 + 设备在线状态 const checkRes = await request('/api/cabinet/check', { cabinetId, userId: global.userId, lat: location.latitude, lng: location.longitude }); if (checkRes.status === 'READY') { // C. 唤起蓝牙或网络指令下发确认框 uni.showModal({ title: '发现提水点', content: '确认开启 1 号柜门取水?', success: async (res) => { if (res.confirm) { // D. 下发开门指令 const openRes = await request('/api/cabinet/open', { cabinetId }); if(openRes.code === 0) { // E. 进入倒计时监听,等待设备反馈开门信号 monitorDoorStatus(cabinetId); } } } }); } } ` ### 4. 数据通信闭环(双向反馈) * **云端指令控制**:小程序点击后,通过 HTTPS POST 请求后端,后端转发 MQTT 指令至货柜。 * **WebSocket 状态同步**:小程序前端通过 Socket 实时监听后端推送。当货柜感应器检测到“物理门已开启”或“门已关闭”,小程序界面同步切换:**[待取水] -> [取心中] -> [成功扣费/取水完成]**。 --- ## 七、 企业级安全与高可用保障 1. **容灾机制(断网续传)**:货柜具备离线存储功能。若断网期间发生本地开门(手动/钥匙),恢复后第一时间同步日志。 2. **【调整】续航与能源管理**:考虑到实际布放环境,设备采用**“大容量工业锂电池 + 定期换电/充电”**模式。系统集成低电量预警: * **电量梯级预警**:低于 20% 时推送后台补货员工单;低于 10% 时小程序端自动置灰并停止接单,防止物理开锁力矩不足。 3. **异常处理机制**:提供“远程强制开锁”与“一键报漏及退费回滚”功能,确保用户权益不受损。 **【新增:离线开门补偿逻辑】** --- ## 八、 实施路线图 (Roadmap) * **Q1-调研期**:完成 4G 模组与主控板的底层通信打通。 * **Q2-内测期**:完成试点投放,验证传感器精度。 * **Q3-商业化**:全面对接货柜节点,开启自动化交付。