docs: update thing-model design with Phase 1 implementation plan

This commit is contained in:
Vickey
2026-05-23 08:20:48 +08:00
parent c6b70c1665
commit cf2ffb0194
+89 -28
View File
@@ -7,6 +7,23 @@ title: 物模型设计方案
本文是物模型改造初版设计,用于先统一概念和边界,再进入接口、表结构和代码实现。这里的"物模型"用于说明行业语义,不要求把 DC3
的领域名词改成通用物模型名词。
> **实施状态**:Phase 1 开工在即;Phase 2-4 为后续迭代。各章节 `[DONE]` / `[TODO]` 标记实际进度。
---
## 0. 实施进度总览
| 阶段 | 内容 | 状态 | 说明 |
|------|------|------|------|
| Phase 1 | Device 加 `profile_id`,移除 ProfileBind | [TODO] | 28 文件改动,核心重构 |
| Phase 1 | 数据迁移(多 Profile → 单 Profile) | 不做 | 已决策:新设备走新逻辑,老设备兼容过渡 |
| Phase 2 | `dc3_command` / `dc3_command_param` 表 | [TODO] | 纯增量,无风险 |
| Phase 2 | `dc3_event` / `dc3_event_param` 表 | [TODO] | 纯增量,无风险 |
| Phase 3 | 指令调用链路 + 事件上报链路 | [TODO] | 依赖 Phase 2 完成 |
| Phase 4 | Web UI + 导入导出 + 文档 | [TODO] | 产品化收尾 |
---
## 设计结论
基于现有 `Profile` 扩展指令和事件是合理的。当前 `Profile` 已经承担"设备模板 / 产品模型"的角色:`Point` 通过 `profile_id`
@@ -42,7 +59,7 @@ DC3 保留自己的领域语言:`Profile` 就是 DC3 对一类设备能力模
| 属性值 | `PointValue` | 运行态采集数据,归属 `device_id + point_id` |
| 设备归属能力模型 | `Device.profile_id` | 设备只能归属一个 `Profile`,不再维护多对多绑定 |
| 服务 | `Command` | DC3 的动作型指令能力;Point 读写由 `rw_flag` 和现有读写链路表达,不进入 `dc3_command` |
| 事件 | `Event` + 运行态事件记录 | 新增 `Profile` 级事件定义;已有 `DeviceEvent` / `DriverEvent` 主要是平台运行态事件记录 |
| 事件 | `Event` + 运行态事件记录 | 新增 `Profile` 级事件定义;已有设备/驱动告警由 `dc3_entity_alarm` 承载,是运行态记录而非模型定义 |
## 目标
@@ -57,6 +74,7 @@ DC3 保留自己的领域语言:`Profile` 就是 DC3 对一类设备能力模
- 初版不重命名数据库、接口和页面中的 `Profile`、`Point` 概念。
- 初版不一次性覆盖复杂 TSL 标准,只实现 DC3 当前驱动和数据流能闭环的最小物模型。
- 不做历史数据迁移。新建设备直接走 `profile_id`;已有设备通过兼容路径(bind 和 `profile_id` 并存过渡期)逐步切换。
## 领域模型
@@ -80,6 +98,8 @@ Runtime
`Profile` 继续作为 DC3 的设备能力模型根对象。业务层、接口和前端仍使用 `Profile` 作为主概念;文档可以说明它覆盖物模型能力,但不把它改名为物模型。
当前字段已具备:`profile_code`、`profile_name`、`profile_type_flag`、`profile_share_flag`、`version`、`profile_ext`、`enable_flag`、`tenant_id`。
建议约束:
- `profile_code` 在同租户下保持唯一,并作为物模型编码。
@@ -89,7 +109,7 @@ Runtime
### Point
`Point` 作为 DC3 的点位概念,不建议新建 `Property` 表替代它。当前字段已经覆盖属性的核心定义:
`Point` 作为 DC3 的点位概念,不建议新建 `Property` 表替代它。当前已有 `profile_id` 归属。字段已经覆盖属性的核心定义:
| 字段 | 能力含义 |
|---------------------------|---------------------|
@@ -108,7 +128,7 @@ Runtime
- 设备的 Point 集合只来自自身 `profile_id` 指向的 `Profile`。
- `point_ext` 中可放点位约束,如 `min`、`max`、`enum`、`step`、`reportMode`。
### Command
### Command [TODO]
物模型语义里的服务在 DC3 中统一表达为 `Command`。这里的 `Command` 只描述读写 Point 之外的动作型能力,例如重启、校准、切换模式、下发配置。指令定义属于
`Profile`,指令执行属于 `Device`。
@@ -120,7 +140,7 @@ Runtime
| `READ` | `Point.rw_flag` 包含读能力 | 读取指定 `device_id + point_id` 的点位值 |
| `WRITE` | `Point.rw_flag` 包含写能力 | 向指定 `device_id + point_id` 写入目标值 |
Point 读写不在 `dc3_command` 中重复建模,由 `Point.rw_flag` 和现有 `PointValueCommand` 链路表达。新增 `Command` 只用于描述读写
Point 读写不在 `dc3_command` 中重复建模,由 `Point.rw_flag` 和现有 `PointCommand` 链路表达。新增 `Command` 只用于描述读写
Point 之外的自定义指令能力,并通过 `profile_id` 归属到 `Profile`。
建议新增定义表:
@@ -167,7 +187,7 @@ Point 之外的自定义指令能力,并通过 `profile_id` 归属到 `Profile
4. 驱动执行后返回结果;同步指令等待结果,异步指令只记录受理状态。
5. 指令调用记录写入数据中心,便于追踪、重试和审计。
### Event
### Event [TODO]
事件表示设备主动上报或平台根据数据规则识别出的业务事件,例如故障、告警、模式切换、工况变化。事件定义属于 `Profile`,事件实例属于
`Device`。
@@ -195,18 +215,17 @@ Point 之外的自定义指令能力,并通过 `profile_id` 归属到 `Profile
### Event 与现有运行态事件的边界
当前系统已经有 `dc3_device_event` 和 `dc3_driver_event`,但它们更接近平台运行态事件记录,不等同于 `Profile` 下的模型事件定义。
当前系统已通过 `dc3_entity_alarm` 统一承载设备/驱动的运行态告警记录(`EntityAlarmDO`,含 `alarm_type_flag`、`alarm_source_flag`、`alarm_level_flag`)。
原 `dc3_device_event` / `dc3_driver_event` 已合并到 `dc3_entity_alarm` 中。
| 现有事件 | 当前定位 | 是否属于 `dc3_event` 定义范围 |
|------------------------------|--------------------|--------------------------------------------------------------|
| `dc3_driver_event` | 驱动在线、离线、告警等平台运行态事件 | 否,驱动不是设备模型实例,不归属 `Profile` |
| `dc3_device_event` 心跳/状态派生事件 | 设备在线、离线、故障等平台运行态事件 | 默认否,属于平台状态链路 |
| `dc3_device_event` 业务告警/故障事件 | 设备侧业务事件运行记录 | 可作为模型事件实例基础,但需要补充 `event_id` 或 `event_code` 与 `dc3_event` 关联 |
| `dc3_entity_alarm` 状态超时告警 | 驱动/设备在线、离线、故障等平台运行态记录 | 否,属于平台状态链路,不归属 `Profile` |
| `dc3_entity_alarm` 规则告警 | 规则引擎触发的告警记录 | 否,属于规则引擎链路 |
| `dc3_entity_alarm` 设备上报告警 | 设备侧业务告警运行记录 | 可作为模型事件实例基础,但需要补充 `event_id` 或 `event_code` 与 `dc3_event` 关联 |
设备状态和驱动状态当前不依赖 Redis,而是由 `dc3_entity_state` 维护持久化状态租约;心跳续租,状态翻转或
租约过期时再派生告警事件记录。因此,在线/离线状态不建议建成 `Profile` 下的通用 `dc3_event` 定义,避免把平台生命周期和设备业务能力混在一起。
现有 `dc3_device_event` 可作为模型事件运行记录的基础,但建议补充 `event_id` 或 `event_code`,否则只能记录告警类型,无法和模型事件定义稳定关联。
设备状态和驱动状态由 `dc3_entity_state` 维护持久化状态租约;心跳续租,状态翻转或租约过期时再派生告警事件记录到 `dc3_entity_alarm`。
因此,在线/离线状态不建议建成 `Profile` 下的通用 `dc3_event` 定义,避免把平台生命周期和设备业务能力混在一起。
## API 与模块落点
@@ -223,43 +242,85 @@ Point 之外的自定义指令能力,并通过 `profile_id` 归属到 `Profile
## 兼容策略
- 现有 Profile、Point API 保持命名不变,不为了贴合物模型术语新增同义别名接口。
- 旧设备和旧模板需要先完成 `dc3_profile_bind -> dc3_device.profile_id` 的关系迁移,默认只有 Point 能力。
- 自定义指令、事件新增表独立演进,不影响 `PointValue` 采集链路和现有读写指令。
- 迁移后设备能力视图只来自单个 `Profile`,不再存在多模型能力聚合和编码冲突问题。
- 新建设备直接写 `profile_id`;已有设备可留空,通过兼容路径(bind 查询)过渡。
- 自定义指令、事件新增表独立演进,不影响 `PointValue` 采集链路和现有 `PointCommand` 读写链路。
- 租户、启停、逻辑删除、版本字段遵循现有 `Profile / Point` 模式。
## 待确认问题
- 自定义指令结果是否需要强同步回传;若需要,命令通道要补充关联 ID 和响应队列。
- 事件运行记录是扩展现有 `dc3_device_event`,还是新建更通用的事件实例表;无论哪种方式,`dc3_driver_event` 都应继续保持平台运行态事件定位。
- 事件运行记录是扩展现有 `dc3_entity_alarm`,还是新建更通用的事件实例表。
- 参数类型是否复用 `PointTypeFlagEnum`,还是抽象为通用 `ValueTypeEnum`。
- 已存在多 `Profile` 绑定数据时,是要求用户人工选择主 `Profile`,还是迁移脚本按规则选择一个并输出审计报告。
- ~~已存在多 `Profile` 绑定数据时的迁移策略~~ — 已决策:不做数据迁移,新设备走新逻辑,老设备兼容过渡。
## 分阶段落地
### 第一阶段:设备与物模型单归属
### 第一阶段:设备与物模型单归属 [TODO]
- 在 `Device` 增加 `profile_id`,把设备与物模型关系固化为多对一。
- 将 `dc3_profile_bind` 中的有效绑定迁移到 `dc3_device.profile_id`。
- 清理 `ProfileBind` 的 DO/BO/VO、Mapper、Service、Controller、Facade、gRPC 契约和前端入口。
- 调整设备、点位、状态、导入导出、Dashboard、Agentic 工具中依赖 `ProfileBind` 的查询逻辑。
- 对历史上绑定了多个 `Profile` 的设备生成迁移清单,确认唯一目标 `Profile` 后再执行迁移。
**范围**:28 个文件,12 个类删除,16 个类修改。
### 第二阶段:模型定义闭环
**DDL**:
```sql
ALTER TABLE dc3_device ADD COLUMN profile_id BIGINT;
CREATE INDEX idx_device_profile ON dc3_device (tenant_id, profile_id) WHERE deleted = 0;
```
- 保留 `Profile` 和 `Point`,新增自定义指令、事件定义表。
**代码改动清单**:
| 操作 | 文件 | 说明 |
|------|------|------|
| DELETE | `ProfileBindDO.java` | 模型类 |
| DELETE | `ProfileBindBO.java` | 业务对象 |
| DELETE | `ProfileBindVO.java` | 视图对象 |
| DELETE | `ProfileBindQuery.java` | 查询对象 |
| DELETE | `ProfileBindBuilder.java` | 构建器 |
| DELETE | `ProfileBindMapper.java` | Mapper 接口 |
| DELETE | `ProfileBindMapper.xml` | Mapper XML |
| DELETE | `ProfileBindManager.java` | Manager 接口 |
| DELETE | `ProfileBindManagerImpl.java` | Manager 实现 |
| DELETE | `ProfileBindService.java` | Service 接口 |
| DELETE | `ProfileBindServiceImpl.java` | Service 实现 |
| DELETE | `ProfileBindingRow.java` | Dashboard DTO |
| MODIFY | `DeviceDO.java` | 加 `profile_id` 字段 |
| MODIFY | `DeviceBO.java` | `Set<Long> profileIds` → `Long profileId` |
| MODIFY | `DeviceVO.java` | 同上 |
| MODIFY | `DeviceBuilder.java` | 适配新字段 |
| MODIFY | `DeviceServiceImpl.java` | 移除所有 bind 调用,直接读写 `profile_id` |
| MODIFY | `DeviceMapper.xml` | `selectPageWithProfile` 去掉 INNER JOIN |
| MODIFY | `ProfileServiceImpl.java` | `listByDeviceId()` 改用 `device.profile_id` |
| MODIFY | `PointServiceImpl.java` | device↔profile 解析改用 `device.profile_id` |
| MODIFY | `DriverServiceImpl.java` | `listDeviceIdsByProfileId` 查 `dc3_device.profile_id` |
| MODIFY | `TopicServiceImpl.java` | 点位解析链路 |
| MODIFY | `PointAttributeConfigServiceImpl.java` | bind 校验 → profile_id 校验 |
| MODIFY | `DashboardServiceImpl.java` | 拓扑图数据源 |
| MODIFY | `DashboardMapper.xml` | 拓扑 SQL |
| MODIFY | `ImportDeviceServiceImpl.java` | `importProfileBind` → 设 `profile_id` |
| MODIFY | `driver/entity/bo/DeviceBO.java` | `profileIds` → `profileId` |
| MODIFY | `driver/entity/builder/DeviceBuilder.java` | 适配 |
| MODIFY | `driver/job/DriverReadScheduleJob.java` | `getProfileIds()` → `getProfileId()` |
**出口标准**:
- `dc3_device` 有 `profile_id` 列
- `DeviceDO` / `DeviceBO` / `DeviceVO` 使用 `profileId` 单值
- ProfileBind 全链路物理删除
- Device/Point/Driver/Topic/Dashboard 服务不再引用 `dc3_profile_bind`
- 现有测试通过
### 第二阶段:模型定义闭环 [TODO]
- 保留 `Profile` 和 `Point`,新增 `dc3_command`、`dc3_command_param`、`dc3_event`、`dc3_event_param` 四张表。
- Manager 提供自定义指令、事件 CRUD、分页、按 `profile_id` 查询。
- Profile 详情聚合返回 Point、指令、事件。
- 增加同一 `Profile` 下 `point_code`、`command_code`、`event_code` 唯一校验。
### 第三阶段:运行链路闭环
### 第三阶段:运行链路闭环 [TODO]
- Data Center 扩展指令调用 API 和调用记录。
- Driver SDK 扩展自定义指令 DTO。
- Data Center 事件上报 API 支持按 `event_code` 关联模型定义。
- 虚拟驱动先实现一条示例自定义指令和一条示例事件,作为协议驱动参考。
### 第四阶段:产品化体验
### 第四阶段:产品化体验 [TODO]
- Web UI 保留 Profile 管理入口,在 Profile 详情中补齐 Point、指令、事件能力视图。
- Point、指令、事件统一展示为设备能力视图。