物模型怎么定义:属性、事件与服务的边界
物模型是设备与平台之间的契约。本文说明属性、事件、服务三类元素各自表达什么、单位和取值范围为什么必须写进模型,以及版本变更要怎么处理。
- 物模型让上层面向模型而非具体型号的报文格式,是设备与平台之间的契约。
- 把故障做成属性是常见错误:短暂故障会被下次上报覆盖,而运维关心它发生过。
- 单位与取值范围必须写进模型,否则换人之后必然出现单位误读。
- 标识符用英文小写下划线,中文只作展示名,避免数据库与日志中的编码问题。
- 修改单位或删除字段属于不兼容变更,应新增标识符而不是改动原有的。
物模型是设备能力的结构化描述:这台设备有哪些可读写的状态、会主动报告什么、能被调用执行什么。它的作用是让平台不必为每款设备写专门的解析代码 —— 上层的规则引擎、展示和存储都面向模型,而不是面向某个型号的报文格式。
三类元素的边界
- 属性:设备的状态,有当前值,可读,部分可写。温度、开关状态、运行模式都属于这一类;
- 事件:某一时刻发生的事,没有当前值的概念。故障发生、按键被按下、阈值被突破属于这一类;
- 服务:可以被调用的动作,通常有入参和返回。重启、校准、设置定时任务属于这一类。
最常见的混淆是把事件做成属性。例如用一个「故障码」属性表示当前故障,看起来可行,但当同一时刻有两个故障、或者故障发生后迅速恢复时,这个属性无法表达 —— 短暂的故障在下一次上报前就被覆盖了,而运维恰恰关心它发生过。故障应当是事件,每次发生都是独立的一条记录。
单位和取值范围必须写进模型
一个只写了「温度,数值型」的属性,无法回答它是摄氏度还是华氏度、是整数还是带小数、合理范围是多少。这些信息如果只存在于某个人的记忆里,换人之后就会出现把华氏度当摄氏度画进曲线这类问题。
写进模型之后还有一个附带好处:平台可以据此做入库前校验。超出物理合理范围的数值通常意味着传感器故障或解析错误,拦在入库前比事后清洗容易得多。W3C 的物联网事物描述规范就把数据类型、单位与取值范围作为属性描述的组成部分,思路是一致的。
命名的约定
标识符用英文、全小写、下划线分隔,并在整个项目内保持一致;中文名称作为展示用的另一个字段。不要用中文做标识符 —— 它会出现在数据库列名、接口字段、日志和规则表达式里,每一处都可能遇到编码问题。
版本演进
物模型一定会变:加传感器、改量程、拆分属性。能兼容的变更和不能兼容的变更要区分对待。
- 新增属性、事件或服务:兼容,老设备不上报新字段,平台按缺失处理即可;
- 修改单位或取值范围:不兼容,同一个标识符在不同时间段含义不同,历史数据会被错误解读;
- 删除或重命名:不兼容,依赖该字段的规则和报表会直接失效。
后两类变更的稳妥做法是新增一个标识符,而不是修改原有的。原有字段保留并标记为废弃,等到确认所有设备和下游都已迁移再移除。模型版本号要随数据一起记录,否则无法判断某条历史数据该按哪个版本解读。这些约定在平台与系统开发类项目里同样适用。物模型一旦对外发布就成为契约,变更流程建议写进合作流程的交付文档。
常见问题
物模型里属性和事件怎么区分?
看它有没有「当前值」这个概念。温度任何时刻都有一个当前值,属于属性;故障发生是某一时刻的事,两次发生之间不存在当前值,属于事件。把事件做成属性会导致短暂发生的情况被下一次上报覆盖。
物模型改了,老设备怎么办?
新增字段是兼容的,老设备不上报即可。修改单位、取值范围或删除字段不兼容,应当新增标识符并保留原字段为废弃状态,等所有设备和下游迁移完成后再移除。数据入库时要记录所用的模型版本。
每个型号都要单独建物模型吗?
同一品类下能力相近的型号可以共用一个模型,用属性表达差异。只有当能力集合明显不同时才分开建,否则模型数量膨胀会让规则和报表重复建设。