# 事件条目

> 每一次事件条目边沿的持久时间线，由某次运行的判定程序或者运行记录之外的“始终”监视程序观测到，并附上每一次背后被冻结下来的条件。

[事件](events)的事件条目标签页（`/events?view=occurrences`）是被测对象做了什么的持久时间线：一次**事件条目边沿**一行，不论是某次运行的判定程序看到的，还是运行记录之外的**始终**监视程序看到的。看到它需要**查看事件**；导出需要**导出/导入历史**。事件条目是按模型在 [Process > 设定 > 事件条目](process-occurrences)里定义的；这个标签页只读它们的历史，什么都不改。

它遵循[事件](events#how-the-three-timelines-behave)那一页所写的三条时间线的共同做法：每页 500 行外加下方的翻页带、一个日期范围、去抖动的搜索、实时刷新、一个详情面板，以及把整个时间范围导出成 CSV 和 JSON。

## 一行是什么 {#what-one-row-is}

一个事件条目是建立在一个模型的通道之上的布尔条件，带一个延时接通和一个延时断开。一行是一个**监视会话**的四种状态变化之一：

| 状态变化 | 含义 |
| --- | --- |
| Activated | 条件成立，并且持续满足了延时接通的时间。 |
| Cleared | 条件不再成立，并且持续了延时断开的时间。 |
| Unavailable | 条件所引用的一个或多个通道不再提供数值。判定程序保持它最后确认过的条件，绝不凭空造出一次解除。 |
| Restored | 每一个被引用的通道又开始提供数值了；条件重新求值，它的延时也重新开始。 |

每一行还写出它是在哪个**范围**里被观测到的，以及它的会话为什么开始：

| 字段 | 取值 | 含义 |
| --- | --- | --- |
| 范围 | **运行记录**、**运行记录之外** | 运行记录：某次运行自己的判定程序，由流程投入；这次边沿同时也写进那次运行的文件里。运行记录之外：在两次运行之间读取该单元绑定的“始终”监视程序。 |
| 原因 | **运行开始**、**运行恢复**、**守望开始**、**运行之外的观察恢复**、**定义有改动** | 一个新的监视会话为什么开始：一次运行开始了；应用重启之后一次运行继续了；这个事件条目和这个单元的“始终”监视程序启动了；一次运行之后单元回到了运行记录之外的监视；或者条件、延时、被引用的通道、启用状态或投入方式被编辑了。 |

新会话从零开始：没有任何条件、可用性或去抖动状态会跨过一段没有被监视的空档带过来，因此一个本来就成立的条件，会在一次运行开始或应用回来时再产生一次 **已成立**，而这条时间线里没有人造的“会话已开始”那种行。运行自己的文件即使后面没有任何状态变化，也会记下会话的分界；历史和报告用它把更早的、还开着的那次成立归类为已中断。那个标记不进这条时间线，也不引发任何通知。只影响显示的编辑（名称、消息、严重程度）保留会话，只改变后续的快照。

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

| 控件 | 取值 | 做什么 |
| --- | --- | --- |
| 搜索 | 占位文字“搜索名称、消息、模型、单元或流程” | 对事件条目的名称、它的消息、模型名称、单元名称和流程名称做“包含”匹配，按当时的快照来匹配。 |
| 严重程度 | **全部严重程度**（默认）、**严重**、**警告**、**提示** | 只保留发生时带该严重程度的事件条目的状态变化。 |
| 刷新 | | 重读日志；悬停提示“刷新事件条目”。 |
| 导出 | **导出为 CSV…**、**导出为 JSON…** | 写出搜索、严重程度和日期范围所及的每一次状态变化，一页接一页，而不只是当前列出来的那些行。只有具备**导出/导入历史**才画出来；列表为空时是灰的。 |

## 那些行 {#the-rows}

| 行的组成 | 内容 |
| --- | --- |
| 时间 | 判定程序观测到这次边沿的日期和时间（运行里则是被判的那个采样点自己的时间戳）。 |
| 圆点 | 严重程度的色调：严重用严重色调，警告用警示色调，提示用中性色。 |
| 名称 | 当时这个事件条目的名称。 |
| 摘要 | “状态变化 · 观测 N（原因） · 模型 / 单元 · 上下文”，其中 N 是这次边沿在它那个会话里的序号，上下文则是“运行记录 · ”再跟上流程的名称（没有记下流程名称时只写“运行记录”），或者“运行记录之外”。例如：“已成立 · 观测 1（运行开始） · Furnace / Line 2 · 运行记录 · Bake 180”。 |
| 级别 | 严重程度那个词。 |

一行所带的消息，在 **已成立** 和 **已复归** 上是事件条目自己的消息（定义里没有时为空，面板里显示为“没有捕获到消息。”），在两种可用性边沿上则是“信号不可用：”或“信号已恢复：”再跟上受影响通道的名称，用逗号分开。

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

选中一行会打开面板，里面是严重程度标记和名称、完整时间戳、摘要行、消息，以及四张卡片：

| 卡片 | 字段 | 内容 |
| --- | --- | --- |
| 事件 | 级别 | 严重程度。 |
| 事件 | 事件 ID | 这次边沿在日志里的标识。运行里的观测，它就是运行记录文件里保存的那一个 id。 |
| 事件条目快照 | 状态变化 | Activated、Cleared、Unavailable 或 Restored。 |
| 事件条目快照 | 模型 | 当时模型的名称。 |
| 事件条目快照 | 单元 | 当时单元的名称。 |
| 事件条目快照 | 范围 | 运行记录或运行记录之外。 |
| 事件条目快照 | 流程 | 只有运行记录范围才有：流程的名称，没有记下时写一个破折线。 |
| 事件条目快照 | 运行记录 ID | 只有运行记录范围才有：这次运行的 id，和历史里显示的是同一个。 |
| 事件条目快照 | 模型 ID、单元 ID、事件条目 ID | 名称背后那些稳定的 id，重命名不会变。 |
| 观测会话 | 日志序号 | 这一行在日志里的写入序号，时间戳相同的行由它决定先后。 |
| 观测会话 | 观测 ID | 观测到这次边沿的那个会话的标识；同一个会话的每一次边沿都带着它。 |
| 观测会话 | 状态变化序号 | 这次边沿在会话里的序号，从 1 开始。中间有缺口，说明有一次边沿日志没能持久保存下来。 |
| 观测会话 | 开始时间 | 这个会话是什么时候开始的，写成完整时间戳。 |
| 观测会话 | 原因 | 运行开始、运行恢复、守望开始、运行之外的观察恢复 或 定义有改动。 |
| 冻结的配置 | 条件 | 这个会话实际判的那个 JavaScript 条件。 |
| 冻结的配置 | 上升 / 下降延时 | “x ms / y ms”，这个会话所用的去抖动时间。 |
| 冻结的配置 | 引用的通道 ID | 把这个条件挡住的那些通道的 id，用分号分开。 |

**复制事件**复制成一行：“时间戳 | Occurrence | 严重程度 | 名称 | 摘要 | 消息 | EventId=… | OccurrenceId=… | ObservationId=… | ObservationSequence=… | ObservationStartedAt=… | ObservationReason=… | Condition=… | OnDelayMs=… | OffDelayMs=… | ReferencedChannelIds=…”。

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

CSV 和 JSON 带着同样的字段，顺序如下：`Timestamp`（CSV 的表头会加上时间基准，“Timestamp (UTC-03:00)”）、`JournalSequence`、`Severity`、`Name`、`Transition`、`Scope`、`Model`、`ModelId`、`Unit`、`UnitId`、`Procedure`、`RunId`、`Message`、`EventId`、`OccurrenceId`、`ObservationId`、`ObservationSequence`、`ObservationStartedAt`、`ObservationReason`、`Condition`、`OnDelayMs`、`OffDelayMs` 和 `ReferencedChannelIds`（CSV 里用分号分开，JSON 里是一个数组）。JSON 是一个带 `TimeZone` 和 `Events` 的信封。文件名是 `occurrence-history-<yyyyMMdd-HHmmss>.csv` 和 `.json`。CSV 和别的导出一样遵循工作站的小数分隔符偏好：小数点用点号时，列表分隔符是 `,`；小数点用逗号时，列表分隔符是 `;`。以 `=`、`+`、`-` 或 `@` 开头的单元格前面会加一个撇号，好让电子表格把它当文本来读。

## 一个事件条目还记在别的什么地方 {#where-else-an-occurrence-is-recorded}

运行里的观测先写进那次运行自己的文件，再用同一个事件 id 连同运行上下文复制到这里；复制失败时，运行记录文件里仍然保有这次边沿，控制台会有一行错误说明这件事。运行记录之外的观测只存在于这里。每一次边沿还会在 Process 这一区留下一行控制台记录：成立按它的严重程度记（严重记为错误，警告记为警告，提示记为信息），信号丢失也按同一个级别记，解除和恢复记为信息。一次成立还会在窗口内引发一条通知，标题是“事件条目 · ”再跟上单元的名称；窗口被遮住或最小化时，运行期间观测到的警告或严重的成立还会引发一条系统通知。

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

- “还没有事件条目”，配上“来自运行记录以及运行记录之外“始终监视”的事件条目状态变化，会出现在这里。”
- “没有事件条目符合这些筛选条件”，配上“调整严重程度或搜索词，可以放宽这段历史。”
- 状态行写“显示 N 条 · 第 1 页”，有搜索、严重程度筛选或日期范围生效时后面跟着“ · 已筛选”；右边写“已选 1 条”和“更新于 hh:mm:ss”。

## 事件条目标签页不做的事 {#what-the-occurrences-tab-does-not-do}

- 它不定义、不投入、也不编辑事件条目（[Process > 设定 > 事件条目](process-occurrences)）。
- 它不把边沿配成带时长的发生记录：那个推导出来的视图，连同它的已中断和不完整分类，在一次运行的[历史](histories)里，以及单元自己的操作面板上。
- 它没有单元、运行记录、范围或日期筛选；按单元、模型或流程的名称搜索，或者到历史里打开那次运行。
- 它不显示实时状态：一个事件条目此刻是否处于活动，要在单元的操作面板上看，不在这里看。
