交互场景
大约 4 分钟deviceshadowscenario
一、典型业务场景
场景一:智能空调远程控温
用户在手机 App 上将空调目标温度设为 26°C。
| 步骤 | 操作 | 影子变化 |
|---|---|---|
| ① | 手机 App → PUT /shadow/desired | desired.temperature = 26 |
| ② | 平台合并 desired,计算 delta | delta = { "temperature": 26 } |
| ③ | 空调在线,平台推送 Delta | 设备收到并执行调温 |
| ④ | 空调上报 reported | reported.temperature = 26 |
| ⑤ | 平台检测 desired 已满足 | 自动清理 desired 和 delta |
场景二:离线设备批量预设
工厂设备下班后全部断电,管理员预设次日开机参数。
| 步骤 | 操作 | 影子变化 |
|---|---|---|
| ① | 管理后台 → PUT /shadow/desired | desired = { "mode": "production", "speed": 80 } |
| ② | 设备离线,desired 暂存 | 三级存储持久化 |
| ③ | 次日设备上电上线 | 平台检测到 delta 非空 |
| ④ | 平台自动补推 Delta | 设备按预设参数启动生产 |
场景三:设备状态监控面板
运维人员在监控大屏实时查看全部设备运行状态。
| 步骤 | 操作 | 说明 |
|---|---|---|
| ① | 大屏前端 → GET /shadow/detail | 逐台获取设备影子文档 |
| ② | 提取 reported 字段 | 展示温度、湿度、电量等实时指标 |
| ③ | 检查 delta 字段 | 识别存在未执行指令的设备并标红提示 |
| ④ | 设备离线仍可展示 | reported 为云端持久化快照,不依赖设备在线 |
场景四:撤销错误指令
误操作将温度设为 5°C,需紧急撤回。
| 步骤 | 操作 | 影子变化 |
|---|---|---|
| ① | 管理后台 → DELETE /shadow/desired | 移除 desired.temperature |
| ② | 平台清理 desired,重算 delta | delta 不再包含 temperature |
| ③ | 设备在线则推送更新后的 delta | 设备不会执行错误指令 |
场景五:设备退役重置
设备退役前清除所有云端影子状态。
| 步骤 | 操作 | 影子变化 |
|---|---|---|
| ① | 管理后台 → DELETE /shadow/remove | 发起影子清除请求 |
| ② | 平台清除影子文档 | Database 标记删除 + Redis / Caffeine 缓存失效 |
| ③ | 设备再次上线 | 视为全新设备,影子文档为空 |
场景六:设备启动自检
设备上电后主动获取影子,检查有无待执行指令。
| 步骤 | 操作 | 说明 |
|---|---|---|
| ① | 设备 → MQTT shadow/get | 请求完整影子文档 |
| ② | 平台返回影子文档 | 包含 reported、desired、delta、version |
| ③ | 设备检查 delta | 有 delta → 逐项执行,完成后上报 reported |
| 无 delta → 无待执行任务,进入正常运行 |
二、数据流向总览
| 影子字段 | 数据流向 | 价值 |
|---|---|---|
reported | 设备 → 影子 → 应用端展示 | 设备状态的云端持久化快照,离线可查 |
desired | 应用 → 影子 → 暂存 | 期望值的持久化存储,设备上线后自动同步 |
delta | 影子 → 设备 | 差量推送,仅传输 reported 与 desired 的差异 |
version | 影子内部 | 乐观锁并发控制,防止多写冲突 |
metadata | 影子内部 → 应用端查询 | 属性级时间戳,追踪每个字段的最后更新时间 |
三、常见问题
Q:影子和时序数据库有什么区别?
时序数据库存储的是设备的历史数据流(每个时间点的值),影子存储的是设备的当前快照(最后一个值)。前者回答"过去发生了什么",后者回答"现在是什么状态"。
Q:设备必须走影子专用 Topic 才能同步影子吗?
不是。平台在 EventPropertyPostFunction 中实现了旁路同步——设备通过标准属性上报主题 thing.event.property.post 上报数据时,平台会自动将属性同步到影子的 reported 中。即使设备完全不感知影子系统的存在,影子也能保持最新状态。
Q:应用设置 desired 后设备不在线怎么办?
desired 通过三级存储持久化至 Database。设备上线后,MqttConnectStatusListener 或 LoginFunction 触发 onDeviceOnline(),自动检测并补推 delta。即使平台重启、Redis 缓存全部失效,只要 Database 中有数据就能恢复推送。
Q:多个应用同时设置 desired 会冲突吗?
不会丢失数据。所有写操作在设备级分布式锁内串行执行,每次写前从 Redis / Database 读取最新状态(绕过本地缓存),确保合并基于最新快照。携带 version 参数时,版本不一致将返回 6300 错误码,调用方可重新读取后重试。
Q:desired 会一直保留吗?
不会。当设备上报的 reported 满足了 desired 中的某个属性(值相等),平台自动清理该属性。全部满足后 desired 与 delta 均变为空。也可通过 REST API 或 MQTT 手动清除指定的 desired 属性。
