2. 故障报警与事件记录的数据模型设计
报警系统能否长期稳定运行,很大程度上不取决于报警画面做得多漂亮,而取决于底层数据模型是否设计得足够严谨。数据模型是报警与事件记录的“骨架”:它规定了每一条报警由哪些字段构成、字段之间如何约束、状态如何流转、编码如何统一。如果模型设计松散,后续就会出现同一故障重复刷屏、确认状态丢失、历史记录无法追溯、报表口径不一致等典型问题。本节围绕报警等级、事件类型、时间戳与状态机、报警生命周期、数据字典与编码规范五个方面,说明如何把一条报警从“现场发生”到“归档留痕”完整地建模。
一、报警等级与事件类型:两个正交的分类维度
很多初学者会把“等级”和“类型”混为一谈,实际上它们是两个正交维度。等级回答的是“这条信息有多急、需要多快响应”,类型回答的是“这条信息属于哪一类业务对象”。二者组合才能支撑后续的分流处理、统计分析和责任归属。
报警等级建议采用三级模型,并明确每一级的响应要求与典型示例:
- 紧急(Critical):直接威胁人身安全、造成批量报废或设备损坏,要求立即停机或人工干预,典型如安全门被打开、主轴过载、急停触发。
- 警告(Warning):偏离正常工艺窗口但尚未造成损失,允许在限定时间内处理,典型如温度接近上限、气压偏低、节拍连续超时。
- 提示(Info/Notice):状态变化或需要关注但不影响生产,典型如料仓余量低于补料线、刀具寿命剩余 15%、模式切换。
事件类型则按业务域划分,建议至少包含设备故障、工艺异常、安全事件三类,并预留扩展位。设备故障指向硬件与驱动层(如伺服过流、气缸到位信号丢失);工艺异常指向参数与质量层(如焊接电流漂移、涂胶量不足);安全事件指向人员与防护层(如光栅遮挡、门锁异常)。等级与类型交叉后,可以形成一张处置矩阵:安全事件无论等级如何都应优先推送至班组与安全员,而提示级设备故障只需进入当班维护队列。
二、时间戳与状态机:让“什么时候发生”可追溯
时间戳是报警数据中最容易被低估的字段。一条报警至少需要四个时间点:发生时间(现场条件首次满足报警判据的时刻)、检测时间(采集系统实际识别到的时刻)、确认时间(操作员点击确认的时刻)、清除时间(报警条件消失或被复位)。发生时间与检测时间之间的差值反映了采集周期与通信延迟,是排查“报警滞后”问题的重要依据。
工程上建议统一使用带时区的 ISO 8601 格式存储,例如 2025-03-18T09:42:17.350+08:00,并在数据库中以 UTC 存储、在展示层转换。对于需要毫秒级对齐的多设备场景,还应记录设备侧时钟与服务器时钟的偏差,避免跨设备事件排序错乱。
状态机是报警模型的核心。一条报警在其生命周期内只应处于有限个明确状态,状态之间的迁移必须由明确的事件触发,禁止出现“任意状态可跳到任意状态”的松散实现。下图给出了本节建议的报警状态机与生命周期主线:
状态机中需要特别说明两点。第一,“未确认但条件已消失”是现场最常见的路径之一,例如瞬时过载报警在操作员赶到前已自行恢复。此时报警应直接进入“已清除”,但必须保留“未确认”标记,供后续统计“无人确认报警比例”。第二,抑制(Suppressed)与清除不同:抑制是计划内的临时屏蔽(如检修期间屏蔽某工位报警),解除后若条件仍满足应回到触发态,因此抑制必须记录操作人、原因和有效期,不能与清除混用同一状态。
三、报警生命周期与数据字典
生命周期可以概括为“触发—确认—清除—归档”四个阶段,每个阶段对应一组字段写入。触发阶段写入报警标识、等级、类型、设备编码、发生时间与检测时间;确认阶段写入确认人、确认时间、确认备注;清除阶段写入清除时间、清除方式(自动恢复/人工复位/抑制解除);归档阶段将记录转为只读,并写入归档批次号与归档时间。归档不是删除,而是把热数据迁移到历史库,保证在线报警表规模可控、查询响应稳定。
数据字典的作用是把上述字段的“名称、类型、长度、取值范围、是否必填、默认值、编码含义”固定下来,形成团队共同遵守的契约。下表给出一份可直接参考的报警主表字段设计示例(示例参数,实际项目需按现场规模调整):
| 字段名 | 类型 | 必填 | 取值/说明 |
|---|---|---|---|
| alarm_id | VARCHAR(32) | 是 | 全局唯一,建议“设备码+时间序+序号” |
| alarm_level | TINYINT | 是 | 1=紧急,2=警告,3=提示 |
| event_type | VARCHAR(16) | 是 | EQP_FAULT / PROC_ABN / SAFETY |
| alarm_code | VARCHAR(24) | 是 | 遵循编码规范,如 EQP-SRV-0012 |
| device_code | VARCHAR(24) | 是 | 对应设备台账唯一编码 |
| occur_time | DATETIME(3) | 是 | 带时区,毫秒精度 |
| detect_time | DATETIME(3) | 是 | 采集系统识别时刻 |
| ack_time | DATETIME(3) | 否 | 未确认时为空 |
| ack_user | VARCHAR(32) | 否 | 工号,关联人员表 |
| clear_time | DATETIME(3) | 否 | 条件消失或被复位时刻 |
| alarm_state | TINYINT | 是 | 1触发 2确认 3清除 4归档 5抑制 |
| archive_batch | VARCHAR(20) | 否 | 归档批次号,归档后写入 |
四、编码规范:让报警码本身携带信息
报警码不应是随手递增的数字,而应是一套可读、可分类、可扩展的编码。推荐采用“业务域-对象-序号”的分段结构,例如 EQP-SRV-0012 表示设备类、伺服对象、第 12 号故障;PROC-WLD-0007 表示工艺类、焊接对象、第 7 号异常;SAFE-DOOR-0003 表示安全类、安全门对象、第 3 号事件。分段编码的好处是:现场人员看到前缀即可判断大致方向,报表可按前缀直接聚合,新增对象时只需申请新段而不打乱既有编号。
编码规范还应约定几条硬性规则:报警码一经发布不得复用,废弃码保留并标记为停用;同一报警码必须对应唯一的判据与处置建议;等级变更需走版本记录,避免历史数据口径漂移。配合数据字典,这些规则共同保证报警数据在数月甚至数年后仍可被正确解读,为故障统计、MTBF 分析和责任追溯提供可靠基础。