4. ThingTemplate与ThingShape的复用机制
在ThingWorx中,ThingTemplate(事物模板)与ThingShape(事物形状)是两种最核心的模型复用单元。它们解决的是同一个问题的两个侧面:ThingTemplate定义“一类设备是什么”,ThingShape定义“一类能力做什么”。理解二者的分工与组合方式,是避免重复建模、实现资产类型标准化的关键。
一、ThingTemplate:资产类型的“出厂规格”
ThingTemplate描述某一类资产的完整规格。以工业场景中常见的“离心泵”为例,一个名为PumpTemplate的模板通常包含以下内容:
- 属性(Properties):如
ratedFlow(额定流量,单位m³/h)、ratedHead(额定扬程,单位m)、ratedPower(额定功率,单位kW)、manufacturer(制造商)。这些属性在模板层定义名称、数据类型和默认值,实例化时只需覆盖差异值。 - 服务(Services):如
Start()、Stop()、GetRuntimeHours(),定义该类设备对外暴露的行为契约。 - 事件(Events):如
OverheatAlarm、VibrationHigh,定义该类设备可能产生的告警事件。 - 订阅(Subscriptions):如属性
temperature超过阈值时触发OverheatAlarm,将属性变化与事件绑定。
当现场有20台同型号离心泵时,只需创建20个Thing实例并分别绑定到PumpTemplate,每台泵只需填写serialNumber、installDate、location等实例级差异属性。模板层的任何修改——例如新增一个energyConsumption属性或调整OverheatAlarm的触发阈值——会自动传播到所有实例,无需逐台修改。
RotatingEquipmentTemplate作为基模板,包含vibration、bearingTemperature等旋转设备通用属性,再让PumpTemplate和FanTemplate继承它。子模板自动获得基模板的全部属性、服务和事件,并可追加或覆盖。二、ThingShape:可组合的能力单元
ThingShape与ThingTemplate的本质区别在于:ThingTemplate是“是什么”,ThingShape是“能做什么”。一个ThingShape封装一组相关的属性、服务、事件和订阅,但它不限定具体设备类型。例如:
MaintainableShape:包含lastMaintenanceDate、maintenanceIntervalDays属性,以及ScheduleMaintenance()服务。EnergyMonitorShape:包含powerConsumption、energyCost属性,以及ResetEnergyCounter()服务。RemoteControlShape:包含Start()、Stop()、SetSpeed()服务,以及controlMode属性。
一个Thing可以同时实现多个ThingShape。例如一台离心泵可以同时实现MaintainableShape、EnergyMonitorShape和RemoteControlShape,从而获得可维护、可能耗监测、可远程控制三种能力。这种组合方式比继承更灵活:继承是“纵向”的类型层次,组合是“横向”的能力拼装。
三、继承与组合的协作规则
在实际建模中,ThingTemplate和ThingShape并非二选一,而是协同工作。一个Thing实例的最终能力由三部分叠加而成:
- 模板继承链:从最顶层的基模板到最底层的具体模板,逐层累积属性、服务、事件和订阅。子模板可以覆盖父模板的默认值,但不能删除父模板已定义的内容。
- ThingShape组合:Thing实例可以额外实现多个ThingShape,每个Shape贡献一组独立的能力。Shape之间不应有属性名冲突;若冲突,ThingWorx会以最后添加的Shape为准,因此命名时建议加前缀(如
maint_、energy_)。 - 实例级覆盖:在Thing实例上可以直接修改属性值、添加订阅或覆盖服务实现。这是优先级最高的层,但应尽量少用,否则会削弱模板的标准化价值。
四、标准化建模的实操建议
以下是一套可直接参考的建模决策流程,用于判断一个新需求应该放在哪一层:
| 判断条件 | 归属层 | 示例 |
|---|---|---|
| 所有旋转设备共有的属性/服务 | 基模板(ThingTemplate) | vibration、bearingTemperature |
| 某类设备特有的属性/服务 | 具体模板(ThingTemplate) | 泵的ratedFlow、阀的cvValue |
| 跨设备类型的通用能力 | ThingShape | 可维护、可能耗监测、可远程控制 |
| 仅单台设备特有的配置 | Thing实例 | serialNumber、installDate、location |
以一个具体配置为例。假设需要为某化工厂的32台离心泵建立模型,其中8台位于A线、12台位于B线、12台位于C线。建模过程如下:
1. 创建基模板 RotatingEquipmentTemplate
- 属性:vibration (NUMBER, 默认0)、bearingTemperature (NUMBER, 默认25)
- 服务:GetHealthIndex() → 返回 100 - vibration*2 - (bearingTemperature-25)*0.5
- 事件:HealthDegraded(当 GetHealthIndex() < 60 时触发)
2. 创建子模板 CentrifugalPumpTemplate extends RotatingEquipmentTemplate
- 新增属性:ratedFlow (NUMBER)、ratedHead (NUMBER)、npshRequired (NUMBER)
- 新增服务:Priming()、Start()、Stop()
- 新增事件:CavitationAlarm
3. 创建ThingShape MaintainableShape
- 属性:lastMaintenanceDate (DATETIME)、maintenanceIntervalDays (INTEGER, 默认90)
- 服务:ScheduleMaintenance(date)、GetNextMaintenanceDate()
4. 创建ThingShape EnergyMonitorShape
- 属性:powerConsumption (NUMBER)、energyCost (NUMBER)
- 服务:ResetEnergyCounter()
5. 为每台泵创建Thing实例,绑定 CentrifugalPumpTemplate
并实现 MaintainableShape + EnergyMonitorShape
实例级填写:serialNumber、location、ratedFlow、ratedHead
6. 验证:修改基模板中 vibration 的默认值,
检查32台泵实例是否全部同步更新。
完成上述配置后,可以通过以下方式验证复用机制是否生效:在ThingWorx Composer中打开任意一台泵实例,查看其“Properties”面板是否同时包含模板继承的属性(vibration、ratedFlow)和Shape贡献的属性(lastMaintenanceDate、powerConsumption);在“Services”面板中确认GetHealthIndex()、ScheduleMaintenance()、ResetEnergyCounter()均可调用。若修改基模板的某个默认值后,所有实例的对应属性值自动变化,则说明继承链工作正常。
最后需要强调的是,ThingTemplate和ThingShape的复用机制之所以能避免重复建模,根本原因在于它们把“变化”和“不变”分离到了不同层级。设备类型之间的共性沉淀到模板继承链,跨类型的能力沉淀到ThingShape,只有真正因设备而异的参数才留在实例层。这种分层策略使得新增一台设备时,大部分建模工作已经在模板和Shape中完成,现场只需填写少量实例级参数即可投入使用。