# 供水设备接入预留(2026-09-10) 目前没有厂商设备协议,**HTTP 和 MQTT 供水接入默认关闭,协议适配器为空**。不生成模拟在线状态,不自动注册设备,不操作库存、套餐权益或配送任务。 ## 预留入口 - HTTP:`POST /iot/water/report`,控制器 `app/controller/WaterDeviceController.php`。关闭时返回 HTTP 503 和 `{"code":503,"message":"设备 HTTP 接口尚未启用","data":null}`。 - MQTT:原 `MqttSubscriber` 接收消息后发送 `mqtt.message` 事件;`config/event.php` 注册 `DeviceIngress::mqtt`,供水开关关闭时直接忽略,不改变原 MQTT 订阅、发布和重连逻辑。 - 协议接口:`app/service/water/DeviceProtocolAdapter.php`。未来实现 `fromHttp(body,headers)` / `fromMqtt(topic,payload,properties)`,把厂商数据转换成内部报告;不相关消息返回 `null`。 - 内部处理:`app/service/water/DeviceReport.php`,仅接受已登记 SN,并检查关联企业、规格启用状态。无需新增数据库表。 ## 内部报告约定 以下是服务端内部格式,**不是对设备厂商协议的预设**。暂不提供可直接启用的厂商适配器。 ```json { "sn": "已登记设备SN", "kind": "heartbeat", "reported_at": "2026-09-10 12:00:00" } ``` - `kind=heartbeat`:仅更新 `sa_water_device.last_seen`。时间为北京时间 `Y-m-d H:i:s`,必须在最近5分钟内且不晚于服务端当前时间。重复、较旧时间不刷新在线状态。 - `kind=usage`:额外提供 `today_liters`(当日累计用水升数,非本次增量,最多两位小数)。仅接收当天报告,同行锁下同日取累计最大值,跨日从新累计值开始;重复或乱序较小值不重复累加。 - 总览沿用最近15分钟 `last_seen` 判断在线。设备的 `today_liters` 与 `telemetry_date` 驱动“今日用水”,不计算账户 `daily_liters` 或补货预测。 - 心跳和用量可以使用同一秒时间;用量更新独立于心跳去重。 - 未知 SN 返回404;非法报告或停用关联档案返回422。HTTP 无效接入令牌返回401,超16KB返回413,未配置适配器返回503。MQTT 失败仅写简短错误码,不写原始消息或凭据。 ## 2026-09-11 日用水历史 新增 `sa_water_device_usage` 和 `WaterDeviceUsage` 模型,部署先执行 `php scripts/migrate_water_device_usage.php --apply`。`DeviceReport` 在原设备行锁/事务内写入设备当日累计最大值,同日重复或乱序较小报告不累加,跨日保留旧记录。看板30日趋势使用该表;无报告日期保留空缺,不补造往日数据。HTTP/MQTT默认关闭和适配器为空的边界不变。详情参见 `WATER_DEVICE_DASHBOARD.md`。 ## 拿到设备后需要补齐 1. Broker 地址、TLS、认证及 ACL,订阅和下发 Topic,SN 与连接身份的对应关系。 2. 心跳频率、时间格式及时区、留存消息行为、离线遗嘱、消息唯一编号、序号与重放规则。 3. 用水量单位、增量/累计口径、设备重启清零及跨日规则;换桶、故障、控制指令和确认报文。 4. 实现厂商适配器,在适配层验证签名/设备身份及 Topic/SN 绑定,并过滤留存、重放及无关消息。不要把历史消息的接收时间伪装成最新设备心跳。仅有增量数据时,先补持久化去重与聚合,不能直接映射为累计用量。 5. 在 `config/water_device.php` 填写可信的适配器类名并测试,再启用所需通道。HTTP 当前预留给可信设备网关,使用独立的至少32字符 `WATER_DEVICE_HTTP_TOKEN`(Bearer 头,通过HTTPS传输),不复用管理员JWT;若设备直连,须按真实协议补设备级鉴权。 6. HTTP 使用 `WATER_DEVICE_HTTP_ENABLED`,MQTT 使用 `WATER_DEVICE_MQTT_ENABLED`,MQTT 还需原 `MQTT_ENABLED` 和 Broker 配置。Windows 需重启相关 HTTP/MQTT 进程加载配置。 ## 验证 `php tests/water_device_ingress_test.php`:30项检查通过,覆盖默认关闭、认证、适配器缺失、消息大小、心跳在线、重复/乱序/过期/未来时间、日累计幂等与跨日、无关Topic及库存权益隔离。数据库测试全部回滚,不启用实际网关或连接 Broker。 HTTP/MQTT 的真实设备收发、身份校验、重放防护和离线协议,待拿到设备后按上述清单联调。 本地验证:`php webman route:list` 已列出 POST 路由;重启本项目 HTTP 子进程后,实际请求 `http://127.0.0.1:8787/iot/water/report` 返回 HTTP503。原有 `php tests/water_business_test.php` 69项也通过,测试数据均回滚。MQTT 通道继续关闭,未来启用时需重启对应进程加载事件配置。