Skip to content

指令 Command

指令是下发给设备的一次动作请求——重启、校准、切换模式、设定温度……定义归属物模型 Profile,调用归属设备,带一组输入/输出参数,由驱动执行后回执结果。

指令回答的是"让设备做一件事",它是事件的对偶:事件上行(设备说"发生了什么"),指令下行(平台说"去做什么")。

它是什么、为什么需要

工业设备除了"上报数值"和"被读写某个量",还需要被触发动作型能力:重启、固件升级、模式切换、按模板下发一段配置。这些动作往往带参数、需要回执、要做超时与审计——把它们建模成 Profile 下的结构化子资源,就是指令 Command。定义沉淀在物模型里(这类设备能做哪些动作、每个动作收哪些参数),调用落到具体设备实例(某台设备某时刻执行了一次)。

最关键的区分:两类下行不要混淆

DC3 有两条独立的下行链路,初学者最容易混淆:

维度写位号 PointCommand自定义指令 Command / CommandCall
改什么某一个量(一个 Point 的值)触发一个带参数的动作
定义来源PointrwFlag 含 WRITEdc3_command 独立定义表
驱动接口DriverCustomService.write()DriverCommand.execute()
参数单值(一个目标值)结构化输入/输出参数 Map
DTOPointCommandDTOCommandCallDTO / CommandCallResultDTO
队列前缀dc3.e.point_commanddc3.e.command

一句话边界(见设计稿 point-command.md §1.2):写位号是属性维度的运行态访问,自定义指令是物模型层的动作能力。

一个例子讲清边界

给空调"把目标温度设为 26℃"——这是写位号targetTemp 是一个可写 Point,写入 26 即可,本质是改一个量。 给空调"执行一次自清洁"——这是自定义指令 selfClean:它不对应某个量,而是一个动作,可能还带参数(如 duration=30),执行完返回 resultCode。 判断口诀:能落到"改某个 Point 的值"就是写位号;是"触发一段动作流程"就是指令。

本页讲的"指令 Command"指自定义指令。写位号请看 位号 Point

关键字段

指令定义 CommandBO(归属 Profile,表 dc3_command):

字段类型含义
commandNameString指令名称(展示用)
commandCodeString指令标识符,同一 profileId 下唯一,调用时按它匹配(如 setTemperature
commandTypeFlagCommandTypeEnum指令类型,见下
callTypeFlagCallTypeEnum调用方式:sync / async
timeoutInteger调用超时时间(秒)
commandExtCommandExt扩展配置(协议映射、驱动指令模板、幂等等)
profileIdLong归属的物模型
enableFlagEnableFlagEnum启停状态
tenantIdLong归属租户

指令参数 CommandParamBO(声明指令的输入/输出参数,归属指令定义):

字段类型含义
paramName / paramCodeString参数名 / 标识符
paramDirectionFlagParamDirectionTypeEnum方向:input(入参)/ output(出参)
paramTypeFlagPointTypeEnum参数数据类型
requiredFlagBoolean是否必填
defaultValueString默认值
commandIdLong归属的指令定义

CommandParam 复用位号的类型系统

paramTypeFlag 用的是和位号一样的 PointTypeEnumSTRING / INT / FLOAT / DOUBLE / BOOLEAN…)。注意区分:入参是调用时由调用方传入(如 temperature),出参是执行后由设备回写(如 resultCode)。

调用入参 CommandCallBO(一次调用的提交体):deviceIdcommandIdcommandCodeparamValuesMap<String,String>,按参数 paramCode 键控)。

指令类型

类型 commandTypeFlag说明
custom自定义指令
config配置型指令
action动作型指令

与其它概念的关系

  • 指令定义挂在物模型下,与位号事件并列,共同描述"这类设备有什么能力"。
  • 指令调用设备发起;驱动执行所需的协议映射由 指令属性配置CommandConfig)提供,与业务参数 CommandParam 分属两层。

调用生命周期与回执

一次调用(CommandCallDTO)携带:recordIdtenantIddeviceIdcommandIdcommandCodeparamValuessourceoccurredAtexpireAt。数据中心持久化为一条 dc3_command_history 记录(PENDING),投递到 RabbitMQ,驱动执行后回执 CommandCallResultDTOstatusresultValueserrorCodeerrorMessagefinishedAt)。

调用状态机(PointCommandStatusEnum,与写位号共用):

PENDING → SENT → SUCCESS / FAILED / TIMEOUT / EXPIRED / DUPLICATE / DEAD
状态含义
PENDING已创建记录,等待投递
SENT已投递到 RabbitMQ,等待驱动执行
SUCCESS / FAILED驱动执行成功 / 失败,结果已回写
TIMEOUT / EXPIRED应用层超时 / expireAt 已过期未执行
DUPLICATE / DEAD重复命令被去重拦截 / 拒入死信队列

同步指令不等于"调用即完成"

callTypeFlag = sync 只表示调用方愿意等回执,不代表 HTTP 立即返回执行结果。当前 /call 返回 recordId,调用方据此轮询 get_by_record_id 拿终态。是否真正"做完"以回执里的 status 为准,别凭 HTTP 200 就认为设备已执行。

示例

空调的物模型里定义一个指令:commandCode = setTemperaturecommandTypeFlag = actioncallTypeFlag = synctimeout = 10,带一个输入参数 temperatureparamDirectionFlag = inputparamTypeFlag = DOUBLErequiredFlag = true)和一个输出参数 resultCodeoutputSTRING)。

调用时提交 CommandCallBO{ deviceId: 1001, commandCode: "setTemperature", paramValues: { temperature: "26" } }。数据中心校验设备 profileId 是否包含该指令,落一条 dc3_command_history(PENDING→SENT),投递给驱动;驱动 execute() 渲染协议报文下发到空调,回执 CommandCallResultDTO{ status: SUCCESS, resultValues: { resultCode: "OK" } },记录推进到 SUCCESS。

API

数据中心服务挂载于 /data

方法路径说明
POST/data/command_history/call下发自定义指令,返回 recordId
GET/data/command_history/get_by_record_idrecordId 查询调用记录详情与终态
POST/data/command_history/list分页查询调用记录

延伸阅读

Released under the AGPL-3.0 License · 基于 AGPL-3.0 协议发布