3. 设备建模与Thing模板设计
在ThingWorx中,设备数字化建模的核心不是“把设备接进来”,而是把物理设备抽象成平台可识别、可复用、可扩展的软件对象。Thing、ThingShape、ThingTemplate、属性、服务、事件与订阅,正是这套抽象机制的七个基本构件。理解它们之间的层次与引用关系,是后续做设备接入、状态监控和预测维护建模的前提。
七个概念的分工
Thing是平台中最基本的实体实例,代表一个具体的被管理对象,例如“1号空压机”“3号注塑机”“A区配电柜”。每个Thing有唯一名称,并拥有自己的属性值、服务实现和事件定义。
ThingShape是可复用的能力集合,用来描述“一类对象具备哪些属性、服务和事件”。它只定义接口与结构,不绑定具体设备。例如可以定义“旋转设备”ThingShape,包含属性vibrationRMS、bearingTemp,服务readVibration(),事件VibrationAlarm。
ThingTemplate是Thing的创建模板,它由一个或多个ThingShape组合而成,并可预设默认属性值、默认服务实现和默认事件。创建Thing时选择某个ThingTemplate,就自动继承了模板中所有ThingShape定义的能力。
三者的关系可以概括为:ThingShape定义能力,ThingTemplate组合能力并给出默认实现,Thing是模板的实例化结果。属性、服务、事件是能力的具体形式,订阅则是事件驱动逻辑的绑定方式。
属性:设备状态的数字化表达
属性是Thing上可读写的数据字段,分为基础属性和自定义属性。基础属性由平台自动维护,如name、description、enabled;自定义属性则由建模者按设备特征定义。以空压机为例,可定义:
vibrationRMS(Number,单位mm/s):振动有效值,用于判断轴承磨损趋势;bearingTemp(Number,单位℃):轴承温度,用于过热预警;runHours(Number,单位h):累计运行小时数,用于保养周期计算;deviceState(String):运行状态,取值RUN、IDLE、FAULT。
属性定义时需要明确数据类型、默认值、是否持久化以及是否可远程写入。对于预测维护场景,vibrationRMS和bearingTemp通常设为持久化,以便历史趋势分析;deviceState可设为非持久化,仅反映当前状态。
服务:对设备执行的操作
服务是Thing上可被调用的方法,用于读取数据、下发指令或执行计算。服务分为内置服务(如GetPropertyValues、SetPropertyValues)和自定义服务。自定义服务可以用JavaScript编写,也可以由ThingWorx的“服务编排”图形化定义。
一个典型的自定义服务readVibration(),其逻辑是:从设备连接器读取原始振动信号 → 计算RMS值 → 写入vibrationRMS属性 → 若超过阈值则触发VibrationAlarm事件。服务的关键在于输入参数、输出结果和异常处理都要明确。例如输入参数sampleWindow(采样窗口,单位ms),输出为vibrationRMS的当前值。
事件与订阅:从状态变化到响应动作
事件是Thing在特定条件下发出的通知,例如属性越限、服务执行完成或定时器到期。事件本身只负责“发出”,不负责“处理”。订阅则是把事件与处理逻辑绑定起来:当事件发生时,自动调用指定的服务或触发工作流。
以空压机振动监测为例:当vibrationRMS超过4.5 mm/s时,触发VibrationAlarm事件;订阅该事件后,自动执行createMaintenanceTicket()服务,生成维护工单,并同时向bearingTemp属性写入当前温度快照。这样,事件源与处理逻辑解耦,后续增加新的响应动作(如发送邮件、推送看板)只需新增订阅,不必修改事件本身。
设备数字化建模的实际方法
建模不是一次性动作,而是一个从设备清单到可运行Thing的逐步细化过程。以下以“空压机群”为例,给出可操作的建模路径。
第一步:梳理设备类型与共性能力。将空压机、冷干机、储气罐等按功能归类,提取共性属性(振动、温度、压力、运行状态)和共性服务(读取数据、启停控制、报警确认)。这一步的产出是ThingShape清单。
第二步:定义ThingShape。为每类能力建立独立ThingShape,避免把所有属性塞进一个Shape。例如“旋转设备”Shape包含振动和温度,“压力容器”Shape包含压力和液位,“电气设备”Shape包含电流和电压。ThingShape之间可以继承,子Shape自动获得父Shape的全部定义。
第三步:组合ThingTemplate。根据设备实际构成,把多个ThingShape组合成一个ThingTemplate。例如“螺杆空压机模板”= 旋转设备Shape + 压力容器Shape + 电气设备Shape + 控制接口Shape。在模板中设置默认采样周期、默认报警阈值和默认服务实现。
第四步:实例化Thing并绑定数据源。为每台实际设备创建Thing,选择对应ThingTemplate,然后绑定设备连接器(如Modbus、OPC UA、MQTT)的地址映射。例如1号空压机的vibrationRMS绑定到Modbus寄存器40001,bearingTemp绑定到40002。
第五步:配置事件与订阅。在Thing上定义事件触发条件,并创建订阅关系。建议把“阈值判断”放在事件定义中,把“响应动作”放在订阅中,这样阈值调整不影响响应逻辑,响应逻辑变更也不影响阈值判断。
一个可参考的建模配置片段
以下示例展示“螺杆空压机模板”中振动监测相关的属性、事件和订阅配置结构,参数为教学示例值,实际项目中需根据设备手册和工况调整。
ThingTemplate: ScrewAirCompressor_Template
ThingShapes:
- RotatingEquipment_Shape
- PressureVessel_Shape
- ElectricalEquipment_Shape
Properties:
vibrationRMS: { type: Number, unit: "mm/s", persistent: true, default: 0 }
bearingTemp: { type: Number, unit: "℃", persistent: true, default: 25 }
runHours: { type: Number, unit: "h", persistent: true, default: 0 }
deviceState: { type: String, persistent: false, default: "IDLE" }
Events:
VibrationAlarm:
trigger: vibrationRMS > 4.5
severity: WARNING
OverheatAlarm:
trigger: bearingTemp > 85
severity: CRITICAL
Subscriptions:
OnVibrationAlarm:
source: VibrationAlarm
action: createMaintenanceTicket(deviceName, "振动超标", vibrationRMS)
OnOverheatAlarm:
source: OverheatAlarm
action: setDeviceState("FAULT") + notifyOperator(bearingTemp)
这段配置体现了建模的核心思想:属性承载数据,事件定义“什么算异常”,订阅定义“异常后做什么”。三者分离后,同一套模板可以复用到多台空压机,只需在Thing实例上绑定不同的数据源地址和调整阈值即可。
常见建模误区
第一,把设备型号直接当作ThingTemplate。型号是采购属性,不是能力抽象;同一型号可能因配置不同而具备不同能力,应按能力组合模板。第二,把所有属性都设为持久化,导致存储膨胀;只对需要趋势分析的属性开启持久化。第三,事件触发条件写在订阅里,导致阈值分散、难以统一管理;阈值应集中在事件定义中。第四,ThingShape粒度过粗,一个Shape包含几十个属性,失去复用价值;应按功能域拆分,保持每个Shape职责单一。
掌握Thing、ThingShape、ThingTemplate、属性、服务、事件与订阅的层次关系后,设备建模就从“逐台配置”转变为“先抽象、再复用、后实例化”的工程方法。这套方法直接决定了后续设备接入、状态监控和预测维护逻辑的可维护性与扩展性。