Separate the public docs (how to understand, deploy, and use IoT DC3) from engineering material (design drafts, analyses, roadmaps, legacy operation screenshots): - add an internal archive area with its own nav, grouping design, analysis, strategy, backlog, and legacy-operation sections - migrate design, operation (data/device/driver/template), analyses, and todo notes into the archive, preserving history - refresh public docs: README (en/zh/ja/vi), operation guides (agentic/concepts/data-commands/device-onboarding), architecture, development, guide, quickstart, and modules - promote the project overview to README.ai.md at the repo root
40 KiB
title
| title |
|---|
| 指令与事件属性配置方案 |
指令与事件属性配置方案
本文用于补齐 Command / Event 在设备侧的协议映射配置能力,使 Profile 在已有 Point 能力之外,完整表达属性、指令、事件三类物模型能力。
设计结论:
CommandAttribute/EventAttribute的定义由驱动在application.yml中声明,并在驱动启动时注册到 Manager;具体配置值不放在驱动配置文件中,而是在设备编辑页面按device + command/event + attribute填写,落库到对应 Config 表。
目标
- 新增
dc3_command_attribute/dc3_event_attribute,描述驱动支持的指令、事件协议映射属性。 - 新增
dc3_command_attribute_config/dc3_event_attribute_config,保存设备实例对指令、事件属性的具体配置值。 - 延续现有
DriverAttribute/PointAttribute的注册模式,驱动通过application.yml声明 Attribute 定义。 - 在设备配置侧补齐
PointConfig、CommandConfig、EventConfig三类能力,形成完整设备接入闭环。
非目标
- 不把
CommandParam/EventParam与CommandAttribute/EventAttribute混为一类。 - 不把设备实例的具体配置值写入驱动
application.yml。 - 不在初版引入独立的
ThingModel、Product、Property表替换现有Profile/Point概念。 - 不要求所有驱动一次性支持指令和事件属性;驱动可按协议能力逐步补齐。
概念边界
CommandParam / EventParam 是物模型业务语义,属于 Profile 中的指令和事件定义;CommandAttribute / EventAttribute
是驱动协议映射语义,描述驱动执行指令或识别事件时需要哪些配置项。
| 概念 | 归属视角 | 作用 | 示例 |
|---|---|---|---|
CommandParam |
Command |
指令调用时传入/返回的业务参数 | temperature、mode、resultCode |
CommandAttribute |
Driver 注册,Command 配置时使用 | 指令下发所需的协议映射属性 | functionCode、registerAddress、payloadTemplate |
CommandConfig |
Device |
某个设备的某个指令对属性的实际取值 | setTemperature.registerAddress = 40003 |
EventParam |
Event |
事件上报时携带的业务输出参数 | faultCode、message、occurTime |
EventAttribute |
Driver 注册,Event 配置时使用 | 事件识别或解析所需的协议映射属性 | topic、eventCodePath、payloadPath |
EventConfig |
Device |
某个设备的某个事件对属性的实际取值 | deviceFault.topic = /device/001/event |
Param 逻辑
Param 不属于驱动协议映射配置,而属于 Profile 中的业务能力定义。它描述指令调用需要哪些输入、输出,以及事件上报会携带哪些业务字段。
CommandParam
CommandParam 体现指令的业务入参和出参,定义在 Command 下。
Profile
+-- Command: setTemperature
+-- CommandParam: temperature input, required
+-- CommandParam: resultCode output
+-- CommandParam: message output
它在以下位置发挥作用:
| 环节 | 作用 |
|---|---|
| Profile 编辑页 | 定义指令需要哪些输入参数、输出参数、参数类型、是否必填、默认值、枚举或范围 |
| 指令调用 API | 调用方提交 deviceId + commandId/commandCode + paramValues |
| Data Center 校验 | 校验参数是否属于该 Command、必填参数是否存在、类型是否匹配、默认值是否补齐 |
| Driver 执行 | Driver 接收经过校验的 paramValues,结合 CommandConfig 渲染协议报文 |
| CommandRecord | 保存本次调用的输入参数、输出参数、执行状态和错误信息,便于审计和排障 |
示例:
Command:
commandCode = setTemperature
CommandParam:
temperature, input, required, DOUBLE
CommandAttribute:
functionCode
registerAddress
payloadTemplate
CommandConfig:
functionCode = WRITE_SINGLE_REGISTER
registerAddress = 40003
payloadTemplate = ${temperature}
CommandCall:
paramValues.temperature = 26
最终 Driver 执行时看到的是:
DriverConfig:
host = 192.168.1.10
port = 502
Command:
setTemperature
CommandConfig:
functionCode = WRITE_SINGLE_REGISTER
registerAddress = 40003
payloadTemplate = ${temperature}
ParamValues:
temperature = 26
也就是说,CommandParam 负责定义业务参数,CommandConfig 负责说明这些业务参数如何被映射成驱动协议报文。
EventParam
EventParam 体现事件上报时会携带哪些业务字段,定义在 Event 下。
Profile
+-- Event: deviceFault
+-- EventParam: faultCode
+-- EventParam: message
+-- EventParam: occurTime
它在以下位置发挥作用:
| 环节 | 作用 |
|---|---|
| Profile 编辑页 | 定义事件输出字段、字段类型、默认值、枚举、范围或 JSON Schema 片段 |
| Driver 事件解析 | Driver 根据 EventConfig 从协议报文中识别事件,并解析出参数值 |
| EventReport API | Driver 上报 deviceId + eventId/eventCode + paramValues |
| Data Center 校验 | 校验事件是否属于设备 Profile,参数是否属于该 Event,类型是否匹配 |
| EventRecord | 保存事件参数快照,供查询、告警规则、审计和后续分析使用 |
示例:
Event:
eventCode = deviceFault
EventParam:
faultCode
message
EventAttribute:
sourceTopic
eventCodePath
payloadPath
EventConfig:
sourceTopic = /device/001/event
eventCodePath = $.eventCode
payloadPath = $.payload
EventReport:
paramValues.faultCode = E001
paramValues.message = Motor overload
也就是说,EventAttribute / EventConfig 负责把协议报文解析成某个事件,EventParam 负责约束和说明这个事件最终上报出来的业务字段。
领域模型
业务视角上,Profile 仍然是一类设备的能力模型,Device 绑定一个 Profile 后就拥有该 Profile 定义的 Point、Command、
Event。配置视角上,Device 再结合自己的 driverId,对这些能力做协议映射配置。
Driver
+-- DriverAttribute
+-- DriverConfig
Profile
+-- Point
| +-- PointAttribute
|
+-- Command
| +-- CommandParam
| +-- CommandAttribute
|
+-- Event
+-- EventParam
+-- EventAttribute
Device
+-- profileId
+-- driverId
+-- PointConfig device + point + pointAttribute
+-- CommandConfig device + command + commandAttribute
+-- EventConfig device + event + eventAttribute
需要注意,这里的 PointAttribute / CommandAttribute / EventAttribute 表示用户在配置 Point、Command、Event
时看到的属性集合;从实现来源看,它们由具体 Driver 在启动时注册,因为不同协议需要的映射属性不同。
Attribute 定义来源
驱动 application.yml 只声明 Attribute 定义,不声明具体设备配置值。当前系统已经支持:
dc3:
driver:
driver-attribute:
- attribute-name: Host
attribute-code: host
attribute-type-flag: STRING
default-value: localhost
point-attribute:
- attribute-name: Function Code
attribute-code: functionCode
attribute-type-flag: INT
default-value: 3
本方案在同一层级新增:
dc3:
driver:
command-attribute:
- attribute-name: Function Code
attribute-code: functionCode
attribute-type-flag: STRING
default-value: WRITE_SINGLE_REGISTER
remark: Command write function
- attribute-name: Register Address
attribute-code: registerAddress
attribute-type-flag: STRING
default-value: ''
remark: Target register or command address
- attribute-name: Payload Template
attribute-code: payloadTemplate
attribute-type-flag: STRING
default-value: ''
remark: Payload template rendered with command params
event-attribute:
- attribute-name: Source Topic
attribute-code: sourceTopic
attribute-type-flag: STRING
default-value: ''
remark: Topic or channel used to receive event payload
- attribute-name: Event Code Path
attribute-code: eventCodePath
attribute-type-flag: STRING
default-value: $.eventCode
remark: JSON path used to resolve event code
- attribute-name: Payload Path
attribute-code: payloadPath
attribute-type-flag: STRING
default-value: $.payload
remark: JSON path used to resolve event params
配置文件职责
| 放置位置 | 内容 | 是否需要重启 | 说明 |
|---|---|---|---|
Driver application.yml |
Attribute 定义 | 是 | 驱动开发者声明协议支持哪些配置项 |
| Manager DB | Attribute 定义同步结果 | 否 | 驱动启动注册后持久化,供 Web 和运行时查询 |
| Device Edit 页面 | Config 具体配置值 | 否 | 用户按设备、指令、事件填写实际映射配置 |
| Config 表 | Config 具体配置值持久化结果 | 否 | 运行时 Driver 从 Manager 拉取并组装使用 |
设备实例配置值不放入 application.yml,原因是它们属于租户、设备和业务模型的运行配置,需要在 Web
页面中可编辑、可审计、可热更新。放入驱动配置文件会导致修改设备配置必须重启驱动,也无法支持同一驱动服务管理大量不同设备。
Attribute / Config 能力边界
Attribute + Config 可以解决 Command / Event 的协议映射问题,但不能单独替代 Command / Event / Param /
运行记录 / 驱动执行链路。
可以解决的问题
| 场景 | Attribute 定义什么 | Config 配置什么 |
|---|---|---|
| 指令下发 | 驱动执行指令需要哪些协议字段 | 某个设备的某个指令使用哪些协议字段值 |
| 指令报文模板 | 模板字段、地址字段、方法字段、主题字段等 | 模板内容、寄存器地址、HTTP URL、MQTT Topic 等 |
| 指令参数映射 | 哪些配置项支持引用 CommandParam |
payloadTemplate = ${temperature} 这类映射关系 |
| 事件来源识别 | 驱动监听事件需要哪些来源字段 | Topic、地址、通道、订阅表达式等具体值 |
| 事件报文解析 | 事件编码路径、载荷路径、条件表达式等 | eventCodePath、payloadPath、condition 的值 |
| 不同协议差异 | 不同 Driver 声明各自需要的 Attribute | 同一 Profile 在不同 Driver 下可以配置不同映射值 |
例如 setTemperature 指令:
CommandParam:
temperature
CommandAttribute:
functionCode
registerAddress
payloadTemplate
CommandConfig:
functionCode = WRITE_SINGLE_REGISTER
registerAddress = 40003
payloadTemplate = ${temperature}
这里 Attribute + Config 已经能表达“业务参数 temperature 如何变成驱动协议报文”。
不能单独解决的问题
| 问题 | 需要的模型或链路 |
|---|---|
| 指令本身是什么 | Command |
| 指令需要哪些业务入参/出参 | CommandParam |
| 事件本身是什么 | Event |
| 事件上报哪些业务字段 | EventParam |
| 指令调用校验、投递、回执、超时 | Data Center 指令调用链路 + Driver SDK |
| 事件上报、持久化、告警规则触发 | EventReport 链路 + EventRecord + 告警规则 |
| 复杂组合指令或多步骤流程 | 后续可扩展 command_ext 或流程编排能力 |
| 跨点位、跨设备聚合事件 | 后续由规则引擎或事件规则模型承载 |
因此,初版结论是:Attribute + Config 足以补齐大多数驱动协议映射缺口;Param 负责业务参数,运行链路负责调用、解析、记录和规则触发。
新增表结构
dc3_command_attribute
指令属性定义表,描述某个 Driver 支持哪些指令协议映射属性。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT |
主键 ID |
attribute_name |
TEXT |
属性名称 |
attribute_code |
TEXT |
属性编码 |
attribute_type_flag |
SMALLINT |
属性类型 |
default_value |
TEXT |
默认值 |
driver_id |
BIGINT |
驱动 ID |
attribute_ext |
JSON |
属性扩展信息,例如组件类型、选项、校验规则 |
enable_flag |
SMALLINT |
启停状态 |
tenant_id |
BIGINT |
租户 ID |
remark |
TEXT |
说明 |
signature |
TEXT |
签名 |
version |
INTEGER |
版本 |
creator_id |
BIGINT |
创建人 ID |
creator_name |
TEXT |
创建人名称 |
create_time |
TIMESTAMPTZ |
创建时间 |
operator_id |
BIGINT |
操作人 ID |
operator_name |
TEXT |
操作人名称 |
operate_time |
TIMESTAMPTZ |
操作时间 |
deleted |
SMALLINT |
逻辑删除标识 |
建议索引:
CREATE UNIQUE INDEX idx_command_attribute_active_unique
ON dc3_command_attribute (tenant_id, driver_id, attribute_code) WHERE deleted = 0 AND attribute_code <> ''::TEXT;
CREATE INDEX idx_command_attribute_driver_id
ON dc3_command_attribute (driver_id) WHERE deleted = 0;
dc3_event_attribute
事件属性定义表,描述某个 Driver 支持哪些事件识别、解析、上报映射属性。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT |
主键 ID |
attribute_name |
TEXT |
属性名称 |
attribute_code |
TEXT |
属性编码 |
attribute_type_flag |
SMALLINT |
属性类型 |
default_value |
TEXT |
默认值 |
driver_id |
BIGINT |
驱动 ID |
attribute_ext |
JSON |
属性扩展信息,例如组件类型、选项、校验规则 |
enable_flag |
SMALLINT |
启停状态 |
tenant_id |
BIGINT |
租户 ID |
remark |
TEXT |
说明 |
signature |
TEXT |
签名 |
version |
INTEGER |
版本 |
creator_id |
BIGINT |
创建人 ID |
creator_name |
TEXT |
创建人名称 |
create_time |
TIMESTAMPTZ |
创建时间 |
operator_id |
BIGINT |
操作人 ID |
operator_name |
TEXT |
操作人名称 |
operate_time |
TIMESTAMPTZ |
操作时间 |
deleted |
SMALLINT |
逻辑删除标识 |
建议索引:
CREATE UNIQUE INDEX idx_event_attribute_active_unique
ON dc3_event_attribute (tenant_id, driver_id, attribute_code) WHERE deleted = 0 AND attribute_code <> ''::TEXT;
CREATE INDEX idx_event_attribute_driver_id
ON dc3_event_attribute (driver_id) WHERE deleted = 0;
dc3_command_attribute_config
指令属性配置表,保存某个设备的某个指令对某个指令属性的实际配置值。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT |
主键 ID |
attribute_id |
BIGINT |
指令属性 ID |
config_value |
TEXT |
指令属性配置值 |
device_id |
BIGINT |
设备 ID |
command_id |
BIGINT |
指令 ID |
config_ext |
JSON |
配置扩展信息 |
enable_flag |
SMALLINT |
启停状态 |
tenant_id |
BIGINT |
租户 ID |
remark |
TEXT |
说明 |
signature |
TEXT |
签名 |
version |
INTEGER |
版本 |
creator_id |
BIGINT |
创建人 ID |
creator_name |
TEXT |
创建人名称 |
create_time |
TIMESTAMPTZ |
创建时间 |
operator_id |
BIGINT |
操作人 ID |
operator_name |
TEXT |
操作人名称 |
operate_time |
TIMESTAMPTZ |
操作时间 |
deleted |
SMALLINT |
逻辑删除标识 |
建议索引:
CREATE UNIQUE INDEX idx_command_attribute_config_active_unique
ON dc3_command_attribute_config (tenant_id, device_id, command_id, attribute_id) WHERE deleted = 0;
CREATE INDEX idx_command_attribute_config_attribute_id
ON dc3_command_attribute_config (attribute_id) WHERE deleted = 0;
CREATE INDEX idx_command_attribute_config_device_command
ON dc3_command_attribute_config (device_id, command_id) WHERE deleted = 0;
dc3_event_attribute_config
事件属性配置表,保存某个设备的某个事件对某个事件属性的实际配置值。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT |
主键 ID |
attribute_id |
BIGINT |
事件属性 ID |
config_value |
TEXT |
事件属性配置值 |
device_id |
BIGINT |
设备 ID |
event_id |
BIGINT |
事件 ID |
config_ext |
JSON |
配置扩展信息 |
enable_flag |
SMALLINT |
启停状态 |
tenant_id |
BIGINT |
租户 ID |
remark |
TEXT |
说明 |
signature |
TEXT |
签名 |
version |
INTEGER |
版本 |
creator_id |
BIGINT |
创建人 ID |
creator_name |
TEXT |
创建人名称 |
create_time |
TIMESTAMPTZ |
创建时间 |
operator_id |
BIGINT |
操作人 ID |
operator_name |
TEXT |
操作人名称 |
operate_time |
TIMESTAMPTZ |
操作时间 |
deleted |
SMALLINT |
逻辑删除标识 |
建议索引:
CREATE UNIQUE INDEX idx_event_attribute_config_active_unique
ON dc3_event_attribute_config (tenant_id, device_id, event_id, attribute_id) WHERE deleted = 0;
CREATE INDEX idx_event_attribute_config_attribute_id
ON dc3_event_attribute_config (attribute_id) WHERE deleted = 0;
CREATE INDEX idx_event_attribute_config_device_event
ON dc3_event_attribute_config (device_id, event_id) WHERE deleted = 0;
运行链路
驱动启动注册
- Driver 从
application.yml读取driver-attribute、point-attribute、command-attribute、event-attribute。 - Driver 注册到 Manager 时携带四类 Attribute 定义。
- Manager 以
tenant_id + driver_id + attribute_code为唯一键写入或更新 Attribute 表。 - Manager 返回注册后的 Attribute 列表,Driver SDK 缓存到
DriverMetadata。
设备配置
- 用户在设备编辑页面选择
driverId和profileId。 - 页面加载 Driver 提供的
PointAttribute、CommandAttribute、EventAttribute。 - 页面加载 Profile 下的
Point、Command、Event。 - 用户分别配置:
PointConfig = device + point + pointAttributeCommandConfig = device + command + commandAttributeEventConfig = device + event + eventAttribute
- Manager 保存配置值到对应 Config 表。
指令下发
- Data Center 收到
deviceId + commandId/commandCode + paramValues。 - 校验
device.profileId == command.profileId。 - 查询
CommandConfig(deviceId, commandId),组装为Map<String, AttributeBO>。 - 投递
CommandCallDTO到对应 Driver。 - Driver 执行时同时使用:
DriverConfigDeviceCommandCommandParam入参值CommandConfig
事件上报
事件有两类来源,均使用同一套事件定义和记录表。
| 来源 | 说明 |
|---|---|
| Driver 主动上报 | 驱动解析协议报文后直接识别 eventCode 并上报 |
| Data Center 识别 | 后续可基于点位值或规则识别事件 |
Driver 主动上报场景:
- Driver 根据
EventConfig(deviceId, eventId)订阅、监听或解析事件来源。 - Driver 根据
eventCodePath、payloadPath等属性识别事件。 - Driver 通过
DriverSenderService.eventReportSender()上报EventReportDTO。 - Data Center 校验
device.profileId == event.profileId。 - Data Center 保存
EventRecord,并继续触发告警规则链路。
UI 设计要求
前端交互需要避免“选一个对象、配一堆字段、单独保存一次”的割裂体验。设备配置页应以 driverId + profileId
为上下文,一次性生成可编辑的配置矩阵,让用户能批量查看、批量编辑、批量保存。
Profile 页面
Profile 负责定义能力,不负责填写设备协议配置值。
Related Points展示 Profile 下的 Point。Related Commands展示 Profile 下的 Command。Related Events展示 Profile 下的 Event。- Profile 编辑步骤中包含 Point、Command、Event 的定义维护。
Profile 编辑建议采用以下步骤:
| 步骤 | 内容 | 说明 |
|---|---|---|
| 1 | Profile Info | 维护模板基础信息 |
| 2 | Points | 维护 Point 基础定义 |
| 3 | Commands | 维护 Command 基础定义和 CommandParam |
| 4 | Events | 维护 Event 基础定义和 EventParam |
| 5 | Review | 汇总 Point / Command / Event 数量和关键字段 |
Command 编辑交互:
- 主表维护
commandName、commandCode、commandTypeFlag、callTypeFlag、timeout、enableFlag。 - 行展开或侧边抽屉维护
CommandParam,使用表格编辑paramName、paramCode、direction、type、required、defaultValue。 - Param 表格支持新增、删除、排序和编码唯一性校验。
- 不在 Profile 编辑页填写
CommandConfig具体值,因为此时不一定知道设备使用哪个 Driver。
Event 编辑交互:
- 主表维护
eventName、eventCode、eventTypeFlag、eventLevelFlag、enableFlag。 - 行展开或侧边抽屉维护
EventParam,使用表格编辑paramName、paramCode、type、defaultValue。 - EventParam 表格支持新增、删除、排序和编码唯一性校验。
- 不在 Profile 编辑页填写
EventConfig具体值。
Device 页面
Device 负责把设备实例与驱动、Profile 和协议映射配置串起来。
Device Info显示当前driverId、profileId。Related Points展示设备从 Profile 继承的 Point,并提供 PointConfig 配置入口。Related Commands展示设备从 Profile 继承的 Command,并提供 CommandConfig 配置入口。Related Events展示设备从 Profile 继承的 Event,并提供 EventConfig 配置入口。
Device 编辑建议采用以下步骤:
| 步骤 | 内容 | 说明 |
|---|---|---|
| 1 | Device Info | 选择 Driver、Profile,维护设备基础信息 |
| 2 | Driver Config | 配置 device + driverAttribute |
| 3 | Point Config | 配置 device + point + pointAttribute |
| 4 | Command Config | 配置 device + command + commandAttribute |
| 5 | Event Config | 配置 device + event + eventAttribute |
| 6 | Review | 汇总缺失项、默认值、配置完整度和保存结果 |
配置矩阵交互
Point / Command / Event Config 采用同一种矩阵式交互。
左侧或首列:Profile 下的能力对象
- Point
- Command
- Event
表格列:当前 Driver 声明的 Attribute
- PointAttribute
- CommandAttribute
- EventAttribute
单元格:当前 Device 的 ConfigValue
Command Config 示例:
| Command | functionCode | registerAddress | payloadTemplate | 状态 |
|---|---|---|---|---|
restart |
WRITE_SINGLE_REGISTER |
40001 |
1 |
完整 |
setMode |
WRITE_SINGLE_REGISTER |
40002 |
${mode} |
完整 |
setTemperature |
WRITE_SINGLE_REGISTER |
40003 |
${temperature} |
完整 |
Event Config 示例:
| Event | sourceTopic | eventCodePath | payloadPath | condition | 状态 |
|---|---|---|---|---|---|
deviceFault |
/device/001/event |
$.eventCode |
$.payload |
faultCode != null |
完整 |
doorOpened |
/device/001/event |
$.eventCode |
$.payload |
eventCode == 'DOOR_OPEN' |
完整 |
交互要求:
- 支持表格内直接编辑 ConfigValue。
- 支持一键应用 Attribute 默认值。
- 支持从其他设备复制配置。
- 支持按缺失、已配置、已禁用筛选。
- 支持保存全部变更,减少逐个对象保存的割裂感。
- 支持单行保存或自动保存作为增强能力,但不作为初版必须项。
- Attribute 的
attribute_ext可驱动不同输入控件,例如输入框、数字输入、下拉选择、模板编辑器、JSONPath 输入框。
Command Config 交互细节
Command Config 页面需要把 CommandParam 作为模板变量提示,而不是作为设备配置项。
- 每行展示 Command 的基础信息和 Param 摘要。
- 编辑
payloadTemplate、url、topic等字段时,提供可插入的 Param 变量列表,例如${temperature}、${mode}。 - 支持“预览报文”:用户输入测试参数,前端渲染模板,展示最终 payload。
- 支持“测试调用”:使用测试参数调用当前设备的指令接口,生成一条测试 CommandRecord。
Event Config 交互细节
Event Config 页面需要帮助用户验证事件识别和参数解析是否正确。
- 每行展示 Event 的基础信息和 EventParam 摘要。
- 编辑
eventCodePath、payloadPath、condition等字段时,提供 JSONPath 或表达式输入控件。 - 支持“解析预览”:用户粘贴一段样例报文,前端根据当前 EventConfig 解析出
eventCode和paramValues。 - 支持“模拟上报”:将解析结果按
EventReportDTO格式提交到 Data Center,生成一条测试 EventRecord。
Driver 页面
Driver 页面可提供只读或半只读的 Attribute 查看能力,帮助用户理解当前驱动支持哪些配置项。
DriverAttribute:连接配置项。PointAttribute:点位采集配置项。CommandAttribute:指令下发配置项。EventAttribute:事件识别和解析配置项。
驱动注册产生的 Attribute 默认不建议在 Web 中随意改编码;如需支持编辑,应限制为名称、描述、默认值、attribute_ext 等非破坏性字段。
实施阶段
| 阶段 | 内容 |
|---|---|
| Phase 1 | 新增四张表和种子 SQL,补齐 DO/DTO/BO/Mapper/Service 基础层 |
| Phase 2 | 扩展 DriverProperties、注册 DTO、Manager 注册接口和 DriverMetadata |
| Phase 3 | 补齐 CommandConfig / EventConfig 的 Manager API |
| Phase 4 | 扩展 Data Center 指令调用链路,给 Driver 传入 CommandConfig |
| Phase 5 | 扩展 Driver 事件解析链路,支持基于 EventConfig 识别事件 |
| Phase 6 | 补齐 Web 设备配置页面和 Profile / Device 详情页展示 |
待确认问题
attribute_ext 是否需要统一 UI 组件协议
需要。attribute_type_flag 只能表达值类型,例如字符串、数字、布尔、JSON;但前端配置页还需要知道用什么控件展示、是否必填、下拉选项有哪些、是否允许引用
Param 变量、是否需要脱敏展示。
如果不约定 attribute_ext,前端只能把所有 Attribute 渲染成普通输入框,体验会退化为“能填但不好用”。如果每个驱动都在前端硬编码一套表单,又会导致驱动和
Web 强耦合。
推荐把 attribute_ext 约定为轻量 UI 协议,初版只定义必要字段,复杂能力后续再扩展。
{
"ui": {
"component": "template",
"required": true,
"placeholder": "Use ${paramCode} to reference command params",
"group": "Protocol Mapping",
"order": 30,
"variables": "commandParam"
},
"validation": {
"min": null,
"max": null,
"regex": ""
},
"security": {
"secret": false
}
}
建议初版字段:
| 字段 | 说明 |
|---|---|
ui.component |
控件类型,如 input、number、select、switch、textarea、json、jsonpath、template、expression、password |
ui.required |
是否必填 |
ui.placeholder |
输入提示 |
ui.options |
下拉、单选、多选的选项 |
ui.group |
表单分组或表格列分组 |
ui.order |
展示排序 |
ui.variables |
是否允许引用变量,如 commandParam、eventParam、none |
validation.min |
数值最小值或字符串最短长度 |
validation.max |
数值最大值或字符串最长长度 |
validation.regex |
正则校验 |
security.secret |
是否敏感字段,敏感字段在列表、快照、日志中需要脱敏 |
前端渲染规则:
- 优先读取
attribute_ext.ui.component。 - 如果没有配置
component,按attribute_type_flag兜底渲染。 - 保存时前端做体验校验,后端做最终校验。
secret = true的字段不在日志和历史快照中保存明文。
Command/Event Attribute 是否需要按类型过滤展示
需要支持,但建议作为 Attribute 的展示和校验规则存在,而不是新增硬编码列。原因是过滤维度不只 command_type_flag /
event_type_flag,后续还可能按 call_type_flag、驱动协议能力、事件来源类型、是否支持模板变量等维度过滤。
推荐在 attribute_ext 中增加适用范围:
{
"appliesTo": {
"commandTypeFlags": ["CUSTOM", "ACTION"],
"callTypeFlags": ["SYNC", "ASYNC"],
"eventTypeFlags": ["ALERT", "FAULT"],
"eventSourceTypes": ["DRIVER"]
}
}
展示规则:
| 场景 | 处理方式 |
|---|---|
appliesTo 为空 |
认为该 Attribute 适用于当前 Driver 下所有 Command 或 Event |
| 当前 Command 类型匹配 | 在 Command Config 矩阵中展示该 Attribute 列 |
| 当前 Command 类型不匹配 | 不展示该 Attribute 列,已有配置保存时也应被后端拒绝或标记为无效 |
| 当前 Event 类型匹配 | 在 Event Config 矩阵中展示该 Attribute 列 |
| 当前 Event 类型不匹配 | 不展示该 Attribute 列,已有配置保存时也应被后端拒绝或标记为无效 |
示例:
{
"ui": {
"component": "template",
"variables": "commandParam"
},
"appliesTo": {
"commandTypeFlags": ["CUSTOM", "ACTION"]
}
}
这个配置表示 payloadTemplate 只在 CUSTOM、ACTION 类型指令中展示,配置型指令如果不需要报文模板,就不会在表格中出现这一列。
EventConfig 初版覆盖 Driver 主动上报还是 PointValue 规则识别
初版建议只覆盖 Driver 主动上报。Data Center 基于 PointValue 的规则识别应该复用 Event / EventParam / EventRecord
,但不应该放进 EventConfig 的初版范围。
原因是两者职责不同:
| 来源 | 本质 | 配置模型 |
|---|---|---|
| Driver 主动上报 | 驱动协议层从报文、Topic、通道中识别事件 | EventAttribute + EventConfig |
| PointValue 规则识别 | 平台规则层根据采集值推导业务事件 | 后续独立的 EventRule / Rule Engine 配置 |
Driver 主动上报链路:
Driver 原始报文
-> EventConfig 解析 eventCode / paramValues
-> DriverSenderService.eventReportSender()
-> Data Center 校验
-> EventRecord
-> 告警规则
以 MQTT Driver 为例,事件入站消息先按 sourceTopic 匹配设备事件配置,命中后再用 eventCodePath 和 payloadPath 从 JSON
报文中抽取事件编码和事件参数:
{
"eventCode": "alarm",
"payload": {
"temperature": "92",
"source": "mqtt"
}
}
对应配置:
| Attribute Code | 示例值 | 作用 |
|---|---|---|
sourceTopic |
dc3/event/device-a |
匹配 MQTT 入站 Topic,支持 + / # 通配符 |
eventCodePath |
$.eventCode |
抽取事件编码,并与 Profile Event Code 校验 |
payloadPath |
$.payload |
抽取事件参数,写入 param_values |
如果入站 Topic 未命中任何 EventConfig,MQTT Driver 会保留原有 PointValue 路径,继续尝试将消息解析为点位值。这样事件上报和点位上报共享 MQTT 入站通道,但通过配置边界清晰分流。
PointValue 规则识别链路:
PointValue
-> Rule Engine / EventRule
-> 生成 eventCode / paramValues
-> EventRecord
-> 告警规则
如果初版把 PointValue 规则也塞进 EventConfig,会让 EventConfig 同时承担“驱动协议映射”和“平台规则表达”两种职责,后面会很难维护。例如
sourceTopic、eventCodePath 是驱动协议字段,而 temperature > 80 是平台规则字段,它们不是同一层模型。
建议后续单独设计:
EventRule
+-- profileId
+-- eventId
+-- sourceType = POINT_VALUE
+-- conditionExpression
+-- paramTemplate
+-- enableFlag
这样 EventConfig 保持驱动映射职责,EventRule 负责平台推导事件,二者最终都落到同一个 EventRecord。
指令执行结果是否写入 CommandConfig 快照
需要写入,但要做脱敏和裁剪。业务上通常称为 CommandRecord,当前数据侧落库表是 dc3_command_history。
原因是指令配置会变化。如果历史记录只保存 commandId 和 paramValues,后续用户修改了 CommandConfig
,再回看旧记录时就无法知道当时到底是写了哪个寄存器、发到了哪个 Topic、用了哪个 payload 模板。
建议在指令创建记录时保存配置快照:
{
"driverId": 123,
"profileId": 456,
"commandId": 789,
"commandCode": "setTemperature",
"commandConfig": {
"functionCode": {
"attributeId": 1,
"attributeName": "Function Code",
"configValue": "WRITE_SINGLE_REGISTER"
},
"registerAddress": {
"attributeId": 2,
"attributeName": "Register Address",
"configValue": "40003"
},
"payloadTemplate": {
"attributeId": 3,
"attributeName": "Payload Template",
"configValue": "${temperature}"
}
}
}
快照的作用:
| 作用 | 说明 |
|---|---|
| 审计 | 能确认某次指令执行时实际使用了哪些协议映射配置 |
| 排障 | 设备响应异常时可以回看当时的地址、Topic、模板、超时配置 |
| 防止历史漂移 | 后续修改 Config 不影响历史记录解释 |
| 支持重放分析 | 可以用历史 ParamValues + ConfigSnapshot 复现当时报文 |
需要注意:
secret = true的 Attribute 不保存明文,只保存掩码或摘要。- 快照保存
attributeCode/attributeName/configValue,不能只保存attributeId,因为 Attribute 定义后续也可能改名或删除。 - 大字段要控制大小,例如大型模板、证书、密钥不应完整写入历史。
- 快照用于审计和排障,不应该作为重试时的唯一数据源;重试策略需要明确是使用历史快照还是使用当前配置。
落库方式建议二选一:
| 方案 | 说明 |
|---|---|
新增 config_snapshot JSONB 字段 |
语义最清晰,查询和展示直接围绕快照字段 |
| 放入现有扩展字段 | 改表较少,但语义不如独立字段清楚;如果当前表无扩展字段仍需加字段 |
初版推荐新增 config_snapshot JSONB,并在 Command Detail 页面展示“执行时配置快照”折叠区。