# 联锁

> 每个单元停止联锁锁定的持久历史：触发、信号源恢复安全，以及手动复位和执行复位的人。

[事件](events)的联锁标签页（`/events?view=interlocks`）是**停止联锁**的持久时间线：模型为每个单元监视的那个布尔信号，机器从外部被停下来时用它结束一次运行。看到它需要**查看事件**；导出需要**导出/导入历史**。联锁在 [Process > 定义 > 自动化](process-automation)里配置，并从仪表画面上的联锁组件或单元自己的界面复位；这个标签页只记录，不改变任何东西。

它遵循[事件](events#how-the-three-timelines-behave)那一页所写的三条时间线的共同做法。

## 三种状态变化 {#the-three-transitions}

联锁监视器每 100 ms 轮询一次配置的信号源，只读取 Connector 或 Logic 已经发布出来的值和质量，不带表达式，也不去抖动。一个单元的锁定在不可用（还没有有效读数）、正常、已触发和等待复位之间走动；其中三种走动会记进日志：

| 状态变化 | 什么时候记录 | 消息 |
| --- | --- | --- |
| 已触发 | 信号源被第一个良好读数投入之后，报出了配置的触发极性，或者失去了质量。锁定被持久保存下来，这个单元上每一次新的执行都会被拒绝，它可写的信号源被阻断，正在进行的运行以已中止 / 不合格结束，原因为 StopInterlock。一个本来在等待复位的单元再次触发，会记下一次新的已触发。 | “信号源报出了配置的触发值（真）。”（或者“（假）”），或者“联锁投入之后，信号源不可用或质量不良。” |
| 信号源已安全 | 处于锁定期间，信号源回到安全值的良好读数。在有人复位它之前，这个单元一直被阻断。 | “信号源已恢复安全；需要手动复位。” |
| 已复位 | 有人在信号源良好且安全、而且这个单元不忙于收尾时清掉了锁定。记录时带上这个人的名字。 | “联锁闭锁已手动复位。” |

监视器在启动或恢复期间（那时它只轮询而不发布）观测到的状态变化会被保留下来，写在下一次发布式轮询上，或者写在紧随其后的那次复位的时刻，因此一次复位绝不会记在它所答复的那次安全边沿之前。在同一个单元里，每一个记下来的时刻都严格晚于前一个，至少差一毫秒，因此行的顺序永远不含糊。

## 搜索与筛选 {#search-and-filter}

| 控件 | 取值 | 做什么 |
| --- | --- | --- |
| 搜索 | 占位文字“搜索模型、单元、信号源、执行者或消息” | 对模型名称、单元名称、信号源的键和名称、一次复位的作者以及消息做“包含”匹配。 |
| 状态变化 | **全部状态变化**（默认）、**已触发**、**信号源已安全**、**已复位** | 只保留一种状态变化。 |
| 刷新 | | 重读日志；悬停提示“刷新联锁事件”。 |
| 导出 | **导出为 CSV…**、**导出为 JSON…** | 写出搜索、状态变化筛选和日期范围所及的每一条事件，一页接一页，而不只是当前列出来的那些行。只有具备**导出/导入历史**才画出来；列表为空时是灰的。 |

## 那些行 {#the-rows}

| 行的组成 | 内容 |
| --- | --- |
| 时间 | 这次状态变化的日期和时间。 |
| 圆点 | 已触发用严重色调，信号源已安全用警示色调，已复位用中性色。 |
| 名称 | 当时单元的名称。 |
| 摘要 | “状态变化 · 模型 / 单元 · 信号源 = 值 · 质量 良好”，例如“已触发 · 40 吨压机 / A 单元 · EmergencyStop = 真 · 质量 良好”。值写作真、假或不可用；质量写作良好或不可用。 |
| 级别 | 状态变化那个词：已触发、信号源已安全或已复位。 |

## 详情面板 {#the-detail-panel}

选中一行会打开面板，里面是状态变化标记和单元的名称、完整时间戳、摘要行、消息，以及三张卡片：

| 卡片 | 字段 | 内容 |
| --- | --- | --- |
| 事件 | 级别 | 状态变化。 |
| 事件 | 事件 ID | 这次状态变化在日志里的标识。 |
| 联锁快照 | 状态变化 | 已触发、信号源已安全或已复位。 |
| 联锁快照 | 日志序号 | 这一行在日志里的写入序号。 |
| 联锁快照 | 模型、模型 ID | 当时模型的名称和它稳定的 id。 |
| 联锁快照 | 单元、单元 ID | 当时单元的名称和它稳定的 id。 |
| 冻结的信号源 | 信号源 | 当时被监视的那个点位或变量的名称（读不出来时写“信号源不可用”；变量已经不存在时写“已移除的变量”）。 |
| 冻结的信号源 | 信号源标识 | 与名称无关的信号源标识，`tag:<id>` 或 `var:<id>`，因此改过名的信号源仍然对得上它的历史；单元没有配置信号源时写 `unit:<id>`。 |
| 冻结的信号源 | 触发极性 | “为真时触发”或“为假时触发”：这个布尔量取哪个读数时结束运行。 |
| 冻结的信号源 | 观测到的值 | 真、假或不可用（信号源读不出来，或者转换不成布尔量）。 |
| 冻结的信号源 | 质量 | 良好，或者不可用。 |
| 冻结的信号源 | 作者 | 已复位时写在执行复位那块屏幕上登录的用户的显示名（没有人登录时写“未登录”；没有名字传过来时写“未知操作员”）。已触发和信号源已安全写“自动”。 |

**复制事件**复制成一行：“时间戳 | Interlock | 状态变化 | 单元 | 摘要 | 消息 | EventId=… | ModelId=… | UnitId=… | SourceKey=… | SourceName=… | TripWhenTrue=… | QualityGood=… | ObservedValue=… | Author=…”。

## 导出的列 {#export-columns}

CSV 和 JSON 带着同样的字段，顺序如下：`Timestamp`（CSV 的表头会加上时间基准，“Timestamp (UTC-03:00)”）、`JournalSequence`、`Transition`（写的是原始名称，例如 `SourceSafe`）、`Model`、`ModelId`、`Unit`、`UnitId`、`SourceKey`、`SourceName`、`TripWhenTrue`、`QualityGood`、`ObservedValue`（不可用时为空）、`Author`（自动发生的状态变化为空）、`Message` 和 `EventId`。JSON 是一个带 `TimeZone` 和 `Events` 的信封。文件名是 `interlock-history-<yyyyMMdd-HHmmss>.csv` 和 `.json`。CSV 和别的导出一样遵循工作站的小数分隔符偏好：小数点用点号时，列表分隔符是 `,`；小数点用逗号时，列表分隔符是 `;`。以 `=`、`+`、`-` 或 `@` 开头的单元格前面会加一个撇号，好让电子表格把它当文本来读。

## 一次状态变化还记在别的什么地方 {#where-else-a-transition-is-recorded}

每一次状态变化还会在 Process 这一区留下一行控制台记录：“联锁已触发：…”记为警告，“联锁信号源已恢复安全：…”和“联锁已复位：…”记为信息，每一条都带着模型、单元、信号源、极性、质量和值。被一次触发结束的那次运行，在[历史](histories)里保留着它自己的记录，原因为 StopInterlock。持久保存下来的那条锁定本身是监视器一直留到复位为止的另一条记录，它不在这个标签页上显示。

## 空状态和状态行 {#empty-states-and-the-status-line}

- “还没有联锁事件”，配上“联锁触发、信号源恢复安全和手动复位，都会出现在这里。”
- “没有联锁事件符合这些筛选条件”，配上“调整状态变化或搜索词，可以放宽这段历史。”
- 状态行写“显示 N 条 · 第 1 页”，有搜索、状态变化筛选或日期范围生效时后面跟着“ · 已筛选”；右边写“已选 1 条”和“更新于 hh:mm:ss”。

## 联锁标签页不做的事 {#what-the-interlocks-tab-does-not-do}

- 它不启用联锁，不选择它的信号源或极性，也不把某个单元从模型的默认设置上摘下来（[Process > 定义 > 自动化](process-automation)）。
- 它不复位：复位命令在联锁组件和单元自己的界面上，而且需要信号源良好且安全，还需要这个单元不再忙于收尾。
- 它不显示某条锁定的实时状态（不可用、正常、已触发、等待复位）；那是单元的操作面板和联锁组件的事。仍在等待复位的单元，在这里只能靠一条后面没有跟着已复位的信号源已安全行认出来。
- 第一个良好读数之前那个不可用状态不算一次状态变化，因此不留下任何行。
- 它没有单元或日期筛选；按单元或模型的名称搜索。
