# 报警

> 正在等着答复的报警，在读到它的地方就地确认，之上是每一次报警状态变化的持久时间线。

报警标签页是报警的操作屏幕：眼下有什么在等着，以及已经发生过什么的记录，叠在同一块屏幕上。它是[事件](events)的第一个标签页（`/events?view=alarms`），也是这一页打开时停住的标签页，还是你点状态栏上的报警指示时落到的地方。看到它需要**查看事件**；在这里答复一条报警需要**操作 Logic**；导出历史需要**导出/导入历史**。报警本身在 [Logic > Alarms](logic-alarms)里定义；这个标签页从不编辑任何一条。

标签页里叠着两张卡片：上面是**当前报警**，从报警登记表实时读出；下面是**历史**，从持久日志里读出。

## 当前报警 {#current-alarms}

这张卡片列出每一条处于活动、或者仍在等待确认的报警：正好就是状态栏所计数的那一批，因此两者永远不会说不到一块去。它直接从实时登记表里读出，并由登记表自己的信号触发重画（任意界面上的一次成立、一次复归或一次确认，一条定义被保存、被禁用或被删除），而不是靠时钟。

### 标题栏 {#the-head}

| 元素 | 显示什么 |
| --- | --- |
| 铃铛 | 报警标志。只要有报警活动或未确认，它就切换成响铃的样子，并取列表里最严重那个优先级的颜色。 |
| 摘要 | “N 条活动报警（M 条未确认）”：此刻有多少个条件成立，以及还有多少条报警在等答复。在有人确认之前就复归的报警，仍然算作未确认。这段文字取最严重那个优先级的色调。 |
| 全部确认 | 一条命令答复所有还在等着的报警。只对具备**操作 Logic** 的角色画出来。运行时停止期间（“运行时已停止”）或者没有东西在等着时（“没有报警在等待响应。”）它变灰，理由写在悬停提示里；其余情况下悬停提示写“确认所有还在等待响应的报警”。操作记录条答“全部报警已确认。” |

### 那些行 {#the-rows}

行按优先级排序，最严重的在最前（严重、高、中、低），同一个优先级里则最早成立的在最前，因此最该被答复的那条报警离顶端最近。表格是紧凑的，最高 240 像素，在卡片内部滚动。

| 列 | 是什么 |
| --- | --- |
| 名称 | 一个按优先级取色的圆点，然后是报警的名称。把鼠标停在名称上会显示这条报警的消息。 |
| 地址 | 这条报警带根的 Logic 地址，`Alarms.<folders>.<name>`，也就是表达式和仪表画面引用它时写的样子。 |
| 状态 | 状态加优先级，例如“活动，未确认 · 严重”。状态那几个词就是报警状态机的四个：**正常**、**活动，未确认**、**活动，已确认**和**已复归，未确认**（条件在有人答复之前就回到了正常）。 |
| 起始时间 | 当前这次成立开始的日期和时间；条件已经复归、这一行只等确认时写一个破折线。 |
| 确认 | 只在仍未确认的行上画出来，而且只对具备**操作 Logic** 的角色画出来。它的悬停提示写“确认”再跟上报警的名称；运行时停止期间它变灰，写“运行时已停止”。操作记录条答的是报警的名称再跟上“已确认。” |

一次只派发一条确认；第一条还在逻辑队列上时再按一次会被忽略，而不是去答复一行列表其实已经放开的报警。这张卡片上的每一次确认都走 Logic 页面用的那同一个记入日志的出口，并以那个窗口里登录用户的名字记进下面的历史里；那里没有人登录时，记为工作站。对没有任何待处理内容的报警做确认，什么也不做。定义里不要求确认的报警永远不会以未确认的样子出现：它直接升到“活动，已确认”，也直接落回正常，因此它的行只在活动期间显示，而且不带**确认**。

没有任何报警活动或等待时，卡片写着“没有报警处于活动状态或等待响应。”，配上“报警一旦成立就会出现在这里，以便确认。”

### 拒绝 {#refusals}

| 情形 | 会怎样 |
| --- | --- |
| 角色没有操作 Logic | **确认**和**全部确认**都不画出来；那些行仍然可读。即便有按压绕过界面到了处理程序，也会答“你的角色可以查看 Logic，但不能操作它（写入数值、运行动作、确认报警）。” |
| 运行时已停止 | 两个动作都仍然画出来并变灰，写“运行时已停止”；列表仍然显示登记表所持有的状态。 |
| 没有东西在等着 | **全部确认**变灰，写“没有报警在等待响应。”；没有一行带**确认**。 |

## 历史 {#history}

当前报警下面那张卡片是持久时间线：一次报警状态变化一行，遵循[事件](events#how-the-three-timelines-behave)那一页所写的三条时间线的共同做法。

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

| 控件 | 取值 | 做什么 |
| --- | --- | --- |
| 搜索 | 占位文字“搜索名称、消息或信号源” | 对报警的名称、它的消息和这次状态变化的来源做“包含”匹配，按当时的快照来匹配。 |
| 优先级 | **全部优先级**（默认）、**严重**、**高**、**中**、**低** | 只保留发生时属于该优先级的报警的状态变化。 |
| 从、到 | 两个日期框，起初是空的 | 只保留日期范围之内的状态变化，每个框是范围的一端：空的框不构成任何界限，在**到**里选中的那一天整天都算在内，直到它的最后一刻。只要其中一个框里有日期，旁边就有一个叉（“清除日期范围”），把两个框都清空。规则是所有时间线共用的那一套，写在[事件](events#how-the-three-timelines-behave)那一页。 |
| 刷新 | | 重读日志；悬停提示“刷新报警事件”。 |
| 导出 | **导出为 CSV…**、**导出为 JSON…** | 写出搜索、优先级和日期范围所及的每一次状态变化，一页接一页，而不只是当前列出来的那些行。只有具备**导出/导入历史**才画出来；列表为空时是灰的。 |

### 那些行 {#the-rows-1}

| 行的组成 | 内容 |
| --- | --- |
| 时间 | 这次状态变化的日期和时间。 |
| 圆点 | 优先级的色调：严重用严重色调，高用警示色调，中用提醒色调，低用中性色。 |
| 名称 | 这次状态变化发生时报警的名称。 |
| 摘要 | “从 → 到 · 来源”，例如“正常 → 活动，未确认 · Logic”。 |
| 级别 | 优先级那个词。 |

状态机的每一次状态变化都被记录下来，不论是什么引起的。**信号源**写出它的出处：

| 信号源 | 含义 |
| --- | --- |
| Logic | 逻辑扫描周期求出了这个条件：延时接通之后的一次成立，或者延时断开之后的一次复归。 |
| *用户的名字* | 在这个标签页上、在 Logic 页面上或者在[报警提示条](component-alarm-banner)上，由在那里登录的用户做出的一次确认。 |
| 工作站 | 那里没有人登录时的同一种确认，以及报警弹出消息卡片上的**确认**，后者总是记为工作站。 |
| 代理 | 代理通过 MCP 做出的一次确认，日志记录为 MCP。 |
| 配置 | 这条报警被重置为正常，因为它的定义在条件、延时、是否要求确认或启用状态被改动之后保存了，或者因为它被删除了。 |

行和详情面板用工作站的语言写出信号源，搜索既能按这个词、也能按日志记录的原值找到它；复制的那一行和导出的文件写出的，则是日志记录的原样：Logic、Station、MCP、Configuration 或用户的名字。

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

选中一行会打开面板，里面是优先级标记和名称、完整时间戳、状态变化摘要、报警当时播报的那条消息（或者“没有捕获到消息。”），以及两张卡片：

| 卡片 | 字段 | 内容 |
| --- | --- | --- |
| 事件 | 级别 | 优先级。 |
| 事件 | 事件 ID | 这次状态变化在日志里的标识。 |
| 报警快照 | 状态变化 | 用状态那几个词写出的“从 → 到”。 |
| 报警快照 | 信号源 | Logic、用户的名字、工作站、代理或配置。 |
| 报警快照 | 报警 ID | 报警定义的稳定 id，重命名之后仍是同一个。 |

**复制事件**把“时间戳 | 报警 | 优先级 | 名称 | 从 → 到 · 来源 | 消息”复制成一行，并答“该事件已复制到剪贴板。”

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

| 列 | CSV | JSON |
| --- | --- | --- |
| 时间戳 | 第一列，表头是“Timestamp (UTC-03:00)”（工作站自己的时差） | `Timestamp` |
| 优先级 | `Priority` | `Priority` |
| 名称 | `Name` | `Name` |
| 状态变化 | `Transition`，写成“从 → 到” | `From` 和 `To`，两个字段 |
| 信号源 | `Source` | `Source` |
| 消息 | `Message` | `Message` |
| 事件 id | `EventId` | `EventId` |
| 报警 id | `AlarmId` | `AlarmId` |

JSON 文件是一个信封，`{ "TimeZone": "...", "Events": [ ... ] }`。文件名是 `alarm-history-<yyyyMMdd-HHmmss>.csv` 和 `.json`。CSV 和别的导出一样遵循工作站的小数分隔符偏好：小数点用点号时，列表分隔符是 `,`；小数点用逗号时，列表分隔符是 `;`。以 `=`、`+`、`-` 或 `@` 开头的单元格前面会加一个撇号，好让电子表格把它当文本来读。

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

- “还没有报警事件”，配上“运行时观察到报警状态变化后，它们会出现在这里。”
- “没有报警事件符合这些筛选条件”，配上“调整优先级或搜索词，可以放宽这段历史。”
- 状态行写“显示 N 条 · 第 1 页”，有搜索、优先级筛选或日期范围生效时后面跟着“ · 已筛选”；右边写“已选 1 条”和“更新于 hh:mm:ss”。

## 报警标签页不做的事 {#what-the-alarms-tab-does-not-do}

- 它不创建、编辑、启用、禁用或删除报警；那是 [Logic > Alarms](logic-alarms)的事。
- 它不搁置也不静音报警，而且它不出声。
- 它不在重启之后恢复已确认状态：登记表会从第一个逻辑扫描周期起重新推导出每一个状态，原本还挂着的确认必须重新给一次。历史保留着前后的状态变化。
- 它不记录是谁通过弹出消息卡片上的**确认**答复的：那次确认不管谁登录着，都记为工作站。
- 它不按报警或状态来筛选历史；按名称搜索，用**从**和**到**缩小日期范围，或者把结果导出来。
- 历史没有自己的动作：这里没有任何东西会删除一次状态变化。
