iotsaas/docs/产品管理模块设计.md
2995840376 0ce191c448 chore: 初始化 iotsaas 版本库基线
纳入范围:
- backend/  Spring Boot 多模块后端(iot-common/device/rule/data/alarm/auth)
- frontend/admin/  Vue3 + Element Plus 管理后台
- Android/   涂鸦原生 APP (com.xhai.iot)
- backend/sql/  Flyway 风格迁移脚本(V2~V21)
- docs/       对接文档与设计文档

排除范围:
- 构建产物: node_modules/ target/ build/ dist/ .gradle/
- 签名密钥: *.jks *.keystore (严禁入库)
- 本机配置: Android/local.properties
- 运行日志: logs/ *.log
- AI 协作本地数据 .codebuddy/ 与第三方 demo tuya-demo/

.gitattributes 统一以 LF 存储, Windows 批处理保留 CRLF
2026-10-27 12:00:41 +08:00

14 KiB
Raw Blame History

产品管理模块(Product & TSL & OTA)分析设计

状态:分析设计(待评审,先不开发) 日期:2026-09-19 目标:论证并设计中控屏/IoT 平台所需的"产品管理"能力(产品参数、物模型 TSL、固件 OTA)


1. 结论先行(建议)

非常需要,且应尽快立项。 当前系统是"设备直管"模式,缺少产品(Product)这一层抽象,导致物模型零散、固件无管理、新增设备类型成本高。引入 产品 → 设备 两级模型(对标涂鸦/阿里云 IoT 的 Product 概念)是平台标准化的必经之路,并能直接支撑中控屏标准控制 UI、场景、AI 控制、固件升级。


2. 现状与痛点

2.1 现状(代码事实)

  • Device 实体(device 表)字段:deviceId, deviceName, platform, deviceType, manufacturer, model, firmwareVersion, status, capabilities(JSON), ..., homeId, roomId —— 无 productId。
  • Device.capabilities:设备级 JSON,存"设备能力描述",每个设备重复存静态能力,无产品级统一定义。
  • AiDeviceProfile(ai_device_profile 表,iot-device 与 iot-rule 两侧都有):设备级"指令码档案"(powerCode/brightnessCode/colorTempCode/temperatureCode/modeCode…),本质是物模型 DP 雏形,但按 deviceId 维度重复存储。
  • Device.firmwareVersion:仅版本字符串,无固件库、无升级包、无 OTA 任务、无灰度/回滚。
  • 涂鸦侧 TuyaDeviceDTO 有 productId/productName/category,但平台未把它沉淀为自有 Product 实体,仅在对接时透传。

2.2 痛点

  1. 重复定义、难维护:同类设备(同型号)每个都重复存 capabilities / AiDeviceProfile 指令码,产品能力变更需逐设备改。
  2. 无标准物模型:控制逻辑(DP 点、属性/事件/服务)散落在设备 JSON 与 AiDeviceProfile,AI 控制、场景、中控屏各自解析,易错且无法复用。
  3. 固件无管理:只有版本号,无法上传/发布/下发/灰度/回滚固件,中控屏等设备的固件升级无法支撑。
  4. 产品参数无沉淀:厂商/型号/品类/联网方式/配网/图标等散落,无法以"产品"维度统一管理和展示标准控制 UI。
  5. 接入新设备类型成本高:每接一类设备都要改代码/前端,无法配置化。

3. 产品管理模块范围

能力 说明
产品基础信息 名称、品类(category)、厂商(manufacturer)、型号(model)、联网方式(wifi/ble/zigbee/matter)、配网方式、图标、说明、发布状态
物模型(TSL) 属性(Property)、事件(Event)、服务(Action) 三类功能点,含 DP 点定义与涂鸦/平台映射
固件管理(OTA) 固件版本库、升级包存储(md5)、发布、升级任务、灰度、回滚、设备当前版本追踪
平台映射 本平台 Product ↔ 涂鸦 productId 等(platform + platformProductId)
设备归属 Device 增加 productId,继承产品物模型与固件基线
接入/配网模板(二期) 标准化配网流程、设备自动归属产品

4. 与现有概念的关系(迁移策略)

现有 去向
Device.manufacturer / model 提升到 Product;Device 改为引用 productId(建议移除冗余,或保留只读快照防不一致)
Device.capabilities(JSON) 由 Product 物模型(TSL)生成,设备运行时状态另存(device_data/status),不再每设备存静态能力
AiDeviceProfile(设备级指令码) 下沉为 Product 物模型的 DP 定义(powerCode 等即产品的"开关属性");AI 控制/场景直接读产品物模型,设备不再单独存
涂鸦 productId Product.platform + platformProductId 字段建立映射(一个平台产品 → 本平台一个 Product)
Device.firmwareVersion 保留为设备"当前版本"(运行时上报);新增 firmware 表管理"可用版本库",ota_task 记录目标版本

5. 数据模型设计

5.1 product(产品表)

字段 说明
id PK
product_key 业务编码(如 P_LIGHT_001)
name 产品名称
category 品类(light/switch/ac/security…)
manufacturer 厂商
model 型号
platform 接入平台(tuya/local/matter…)
platform_product_id 涂鸦 productId 等映射
connect_type wifi/ble/zigbee/matter
net_config_type 配网方式
icon 图标
description 说明
status 草稿/已发布
spec_version 当前物模型版本号
create_time / update_time —

5.2 物模型(TSL)

推荐拆表(便于校验、UI 渲染、DP 映射),顶层用 spec_version 关联快照:

  • product_property(属性):id, product_id, code(如 switch_1), name, access(读/写/上报), type(bool/int/enum/float/string/json), min, max, step, unit, enum_list, dp_id(涂鸦DP映射), default_value, sort
  • product_event(事件):id, product_id, code, name, type(info/alert/fault), params(JSON)
  • product_action(服务):id, product_id, code, name, input(JSON), output(JSON)

可选:同时存一份 product.spec_json(完整 TSL 快照)便于缓存下发。

5.3 firmware(固件表)

字段 说明
id PK
product_id 所属产品
version 固件版本
file_url 升级包地址
file_md5 校验
size 大小
release_note 更新说明
is_latest 是否最新
status 草稿/已发布
create_time —

5.4 ota_task(升级任务)

字段 说明
id PK
product_id 产品
firmware_id 目标固件
target_version 目标版本
scope 全部 / 指定设备 / 灰度%
device_ids 指定设备
status 进行中/完成/暂停/失败
success_count / fail_count 统计
create_time —

5.5 Device 改造

  • 新增 product_id(FK,关联 product.id)。
  • 视情况移除 model/manufacturer 冗余(或保留只读快照)。
  • firmwareVersion 保留为设备当前运行版本(上报)。

6. 接口设计(建议)

6.1 管理端(后台/管理员)

  • POST/GET/PUT/DELETE /api/v1/products —— 产品 CRUD
  • GET /api/v1/products/{id}/spec —— 物模型查询
  • POST /api/v1/products/{id}/spec/properties 等 —— DP/事件/服务增删改
  • POST /api/v1/products/{id}/firmware —— 上传固件
  • GET /api/v1/products/{id}/firmwares —— 固件列表
  • POST /api/v1/products/{id}/ota —— 创建升级任务
  • GET /api/v1/ota-tasks/{id} —— 任务进度

6.2 设备/中控屏侧(复用)

  • 设备详情返回 productId + 物模型(用于渲染标准控制 UI,不再依赖零散 capabilities)。
  • 控制接口基于物模型 DP(统一语义)。
  • 固件查询:设备上报/拉取最新固件版本,触发 OTA。

7. 固件 OTA 流程

  1. 管理员上传固件到 Product → 生成 firmware 记录(version, url, md5)。
  2. 创建 ota_task(目标版本 + 设备范围 / 灰度比例)。
  3. 设备定期上报/查询最新固件(或平台主动推送升级指令)→ 下载升级 → 上报新 firmwareVersion → 任务统计。
  4. 支持回滚(将上一版本 is_latest=false,重新下发任务)。
  • 中控屏本身也是一类 Product,可纳入同一套 OTA 管理。

8. 分阶段实施

  • P0 产品基础:product 表 + Device.productId 改造 + 产品 CRUD;按 model+manufacturer 自动归并或手动建产品,给存量设备回填 productId。
  • P1 物模型:TSL(property/event/action)建模 + 管理接口;将 AiDeviceProfile / capabilities 迁移沉淀为产品物模型,AI 控制/场景改读产品物模型。
  • P2 固件 OTA:✅ 已实现(2026-09-19)。后端 FirmwareService/Controller:固件注册(草稿)/发布(置最新)/最新版查询、升级任务创建(all/designated/gray 物化目标设备)/任务分页/详情/设备上报回调(回写 device.firmware_version、统计完成)/暂停。管理后台「设备管理→产品管理」含固件OTA面板(注册/发布/建任务/进度/暂停)。V13/V14 迁移已在开发库(iot-mysql 3386)执行,8 台涂鸦设备已 reconcile 归类为 8 个产品。
  • P3 标准化控制:✅ 已实现(2026-09-20)。核心是「标准控制模型」ControlSchemaService:GET /api/v1/products/{id}/control-schema(产品级)与 GET /api/v1/devices/{deviceId}/control-schema(设备级,含 DP 当前值填充)。物模型→控件映射:bool→switch、int/float 有范围→slider、enum→segmented、其余→number/text;主开关自动识别(开关/电源/switch/power 优先,否则唯一可写 bool)。设备无产品时 available=false,客户端回退原有渲染。消费端:管理后台「物模型→控制预览」按模型渲染只读控件;Android DeviceControlActivity 优先拉后端模型渲染(ApiService.getDeviceControlSchema),失败/无模型回退涂鸦 schema(需 Android Studio 编译确认)。
  • P4 高级:✅ 大部分已实现(2026-09-20)。版本回滚 POST /products/{id}/ota/rollback(不指定版本则回退上一个已发布版本);灰度改为设备ID稳定哈希分组(同一设备恒在同一组,可配合不同版本做 A/B 对比);统计看板 GET /ota-tasks/stats?productId=(任务数/进行中/完成/暂停、成功失败数、成功率、设备固件版本分布),管理后台 OTA 面板顶部为统计卡片 + 版本分布。未做:配网模板。

9. 风险与注意

  • 存量迁移:设备需回填 productId(按 model+manufacturer 归并或人工关联)。
  • 兼容性:保留 capabilities 读兼容,逐步切到产品物模型,避免一次性大改。
  • 物模型版本:用 spec_version 管理,产品变更不影响已部署设备(设备绑定创建时的 spec 快照)。
  • 涂鸦映射一致性:platformProductId 与涂鸦 productId 对齐,DP 映射字段 dp_id 准确。

10. 价值总结

引入产品层可一次性解决当前三大痛点:① 物模型统一(消除 capabilities/AiDeviceProfile 设备级重复)② 固件可管理(OTA)③ 设备类型配置化接入。同时为已规划的中控屏标准控制 UI、场景、AI 语音控制提供统一数据底座,是平台从"能连设备"走向"可运营 IoT 平台"的关键一步。


11. 已确认决策(2026-09-19 评审)

项 决策
存量设备回填 两者结合:系统按 model+platform 自动预归类生成建议产品与归属,管理员在后台确认/调整
Device 冗余字段 移除 Device.model / manufacturer,统一从 product 取(需同步改所有读写该字段的逻辑:DeviceController.createDevice、DeviceInfo DTO、AiDeviceProfile、前端设备卡片等)
物模型存储 拆表:product_property / product_event / product_action,每行一个 DP 点,含 dp_id 涂鸦映射与 spec_version
首期范围 P0 + P1 全做:产品基础 + Device.product_id + 存量回填 + 物模型(属性/事件/服务)建模与接口,并将 AiDeviceProfile / capabilities 下沉为产品物模型

11.1 开发前影响面排查(移除冗余字段必做)

  • Device.model / manufacturer 读写点:DeviceController(create/update/query)、DeviceInfo/DeviceData 等 DTO、SQL 映射、前端设备详情/卡片展示。
  • AiDeviceProfile 下沉:iot-device 写入、iot-rule 读取(AI 控制翻译)需改为读产品物模型;迁移脚本把存量 deviceId 级指令码归并到所属产品的 property。
  • capabilities 兼容:保留读兼容,新设备改由产品物模型生成;提供回填/转换脚本。

12. 实现进度(2026-09-19,P0+P1 基础)

12.1 已完成(可编译,已通过 LSP)

  • SQL backend/sql/V13__add_product_module.sql:新建 product / product_property / product_event / product_action / firmware / ota_task 六表;device 表新增 product_id 列(保留原 model/manufacturer 兼容快照,未物理删除)。
  • 实体 + Mapper:6 个实体与 6 个 BaseMapper(纯新增)。
  • ProductService / Impl:产品 CRUD、物模型查询与增删改、resolveProductId(按平台信息解析/自动建产品)、reconcileDevices(存量设备按 model+platform 自动归类回填 product_id)。
  • ProductController POST/GET/PUT/DELETE /api/v1/products、/products/{id}/spec、/properties|events|actions、/reconcile、/resolve。
  • Device / DeviceInfo 增加 productId;TuyaDeviceAdapter.getDeviceInfo 回填 productId(设备详情可返回所属产品)。

12.2 未做(高风险,单列计划,未破坏现有功能)

  1. ✅ 移除 Device.model/manufacturer 冗余(D):V14 给 device 加 platform_product_id(承接塞进 model 列的涂鸦 productId)、迁移存量、再 DROP COLUMN model/manufacturer。Device 实体删两字段加 platformProductId;TuyaController 改设 platformProductId;reconcileDevices 改按 platform+platformProductId 归类;DeviceInfo 的 model/manufacturer 改为从 product 取(TuyaDeviceAdapter 注入 ProductMapper)→ 前端零改动。
  2. ✅ AiDeviceProfile 下沉产品级(C,向后兼容):ai_device_profile 加 product_id。iot-device 探测与 iot-rule 解析/保存全部改为优先读产品级、推断落产品级;旧设备级作 fallback。AiDeviceView 加 productId。
  3. ✅ 设备同步自动关联(B):TuyaController 创建/更新涂鸦设备时自动 resolveProductId 设 device.product_id。
  4. ✅ capabilities 由物模型生成:DeviceServiceImpl.getDeviceInfo 改为依据设备所属 product + product_property 动态推导能力描述(product 元数据 + 每个功能点 code/name/type/access/writable/min/max/step/unit/enum/default),取代各 adapter 硬编码能力(如 LocalDeviceAdapter 的 switch/brightness/color);device.capabilities 列仅保留 dps 运行时态;无产品时回退 adapter 自带能力。前端无引用,零改动。

验证:后端 mvn -pl iot-device,iot-rule -am compile 通过(exitCode 0)。存量设备 productId 回填与产品创建由部署后执行 POST /api/v1/products/reconcile 完成(已基于 platformProductId)。