# 事件条目

> 对被测对象所监视的条件，写成一个建立在模型通道之上的 JavaScript 表达式，在一次运行期间判，或者始终判。

一个**事件条目**记下被测对象做了一件值得记的事。报警监视的是厂区和设备，而事件条目属于流程：它的跳变随观测到它的那次运行一起保存，同时也进入事件页面上那条持久的事件条目时间线。它的条件是一个建立在模型通道之上的 JavaScript 表达式，两个跳变方向都去抖动，并由它所读之物的质量把关。事件条目住在 Process > 模型 > 某个模型 > 设定 > **事件条目**下面，需要**编辑配方与判定**权限。

## 事件条目文件夹 {#the-occurrences-folder}

选中**事件条目**那一行会打开文件夹页面（“对被测对象所监视的条件。凡是适用的，每一次跳变都随它的运行记录保存，同时进入持久的事件条目历史。”），一个事件条目一张卡片，按名称排；点一张卡片就打开它，那个叉则把它删掉。一个都没有时，页面写着“还没有事件条目。添加一个。”

| 命令 | 做什么 | 什么时候变灰（情形） | 什么时候不画出来（角色） |
| --- | --- | --- | --- |
| **新建事件条目**（选中文件夹时在详情栏上；右键**添加事件条目**） | 添一个 `事件条目 <n>`：严重程度为警告，仅在流程期间投入，已启用，没有消息，条件为空。它被加进所属的分组，在那里突出显示并滚动到可见处；用它的卡片打开它。 | 任何一个单元上有运行，或者运行时已停止。 | 没有编辑配方与判定时。 |

## 事件条目的页面 {#the-occurrences-page}

标题栏带着名称、一枚写着严重程度的小药丸（用该严重程度自己的颜色），事件条目关着时还带一枚**已禁用**小药丸。它下面可能立着两种提示：

- 保存下来的条件通不过校验时的一条警示附注（草稿照样保存；附注说明哪里不对，见下）。
- 每一个实时条件求不出值的单元一条**求值不可用**提示条，写作“`<unit>`：`<error>`”。同一个错误不变时，一个单元的诊断只写一次，等求值又成功了就清掉。

### 标识与行为 {#identity--behavior}

| 字段 | 是什么 | 取值 / 默认 | 效果 |
| --- | --- | --- | --- |
| **名称** | 这个事件条目的名称：树里那一行、运行记录文件里的事件标签、事件时间线和那些报告里用的都是它。 | 自由文本；创建时是 `事件条目 <n>`。 | 给树里那一行重命名，也改流程的清单里对它的称呼。 |
| **严重程度** | 一次成立的分量。选择框把每一个选项按它的小药丸将来的墨色显示出来。 | **提示**、**警告**（默认）、**严重**。 | 决定小药丸和那段发生记录在任何地方被列出时的颜色。运行期间，一个警告或严重事件条目的成立，还会在应用被遮住或最小化时请求一条操作系统通知；提示则留在窗口里。 |
| **投入时机** | 什么时候判这个条件。 | **仅在流程期间**（默认）：只在一次投入它的流程的运行进行期间，在记录下来的那些行上判。**始终**：运行之外也判，由一个后台监视程序实时读取这个单元的绑定。 | 一个始终的事件条目不需要任何流程来投入它；一个仅在流程期间的事件条目，只由勾选了它的那些流程来判。 |
| **成立延时（ms）** | 条件必须持续成立多久，**已成立**才被确认，分辨率取决于采样。 | 一个毫秒数；默认 0。这个字段不接受负数：输入会被拒绝，字段下面的附注会写出来，之前的值回来。 | 给上升沿去抖动。 |
| **复归延时（ms）** | 条件必须持续不成立多久，**已复归**才被确认。 | 同上；默认 0。 | 给下降沿去抖动。 |
| **已启用** | 这个事件条目到底投不投入。 | 默认开。 | 被禁用的事件条目永远不投入，运行里运行外都不投入，也从不挡住启动。 |
| **消息** | 随一次成立一起记录并播报的那段文字。 | 自由文本；默认为空。 | 随每一次跳变一起进入运行记录文件和日志。 |

### 条件 {#condition}

“一个返回布尔值的 JavaScript 表达式。”这张卡片装着一个代码编辑器、你可以使用的那些引用的清单（“可用的通道引用：Channels.Ch_1、Channels.Outlet_temperature、…”），以及那句提醒“运行期间，条件读取记录下来的数据记录列；‘始终’监视器则实时读取单元的绑定。写法错误、引用缺失和求值失败都会显示在这里，而不会被当成假或者信号丢失。”

一条通道写作 `Channels.<identifier>`，其中的标识符是通道名称规范化之后的样子：字母和数字原样保留，其他每一个字符变成 `_`，以数字开头的名称前面补一个 `_`。`Channels` 里只有这个模型的通道，别无他物，因此一条名叫 `Math`、`isNaN` 或 `true` 的通道仍然是合法的通道名，也不会遮住任何 JavaScript 全局对象。一个存在且质量良好的 `NaN` 是数据，你可以用 `isNaN(Channels.Pv)` 去判它。例子：`Channels.Outlet_temperature > 80`、`Channels.Door_open && Channels.Heater_on`。

草稿在你输入时就按每条通道类型的示例值校验，标题下面那条警示附注说出哪里通不过：

| 附注 | 含义 |
| --- | --- |
| “写法错误：…” | 这个表达式解析不了。 |
| “通道引用‘Channels.X’在这个模型里不存在。” | 一个引用没有指到任何通道。 |
| “不止一条通道映射到‘Channels.X’。” | 两个通道名称规范化成同一个标识符；请到通道表里给其中一个重命名。 |
| “条件必须返回布尔值，但返回了 `<type>`。” | 表达式得出的不是真也不是假。 |
| “求值错误：…” | 表达式抛了异常。 |

无效的条件仍然作为草稿保存下来。它在别处有后果：一个已启用、通不过校验、而且被某个流程投入（在它上面勾选了，或者投入时机是始终）的事件条目，会挡住那个流程的启动，流程的页面上写着“事件条目‘`<name>`’不成立：…”；一个无效的始终事件条目不会启动它运行之外的监视程序，只在这里留下一条看得见的诊断，而不是每轮轮询都重复一遍。

每一次求值都跑在一个受约束的引擎里（500 ms 的上限、有界的语句条数和有界的内存），因此一个失控的表达式失败的是它这次求值，而不是工作站。

## 一个事件条目是怎么被判的 {#how-an-occurrence-is-judged}

运行期间，条件是在数据记录记下来的那些行上判的，因此这个流程的数据记录没有记录的通道，对它来说就是不可用的。一个流程在这样一条通道上投入了事件条目，或者投入了事件条目却什么都不记录，会在它自己那一页上和启动时被拒绝：那个事件条目永远判不了，警示附注会写出它的名字。运行之外，一个始终事件条目由一个实时读取该单元绑定的监视程序来判。两种判定程序在任何一条被引用的通道不可用期间，都保持最后确认过的状态：只有值缺失或者质量不良才会把判定挂起，而一个存在、质量良好的值（包括 `NaN`）是可以求值的数据。判定程序记录四种状态变化：**已成立**（成立延时之后）、**已复归**（复归延时之后）、**不可用**（一条被引用的通道丢了信号）和**已恢复**（每一条被引用的通道都回来了；条件重新被判，相应的延时也重新开始）。

运行期间，每一次状态变化先写进运行记录文件，然后连同它的运行上下文复制进[事件](events-occurrences)页面上那份持久日志；运行之外，监视程序只写日志。启动一次运行会丢弃这个单元运行之外的那个判定程序，离开运行时再造一个新的，因此没有哪一次成立会跨过一段没有被观测的边界带过来。重命名称、消息或严重程度只影响之后的跳变；改条件、延时、投入时机或启用状态，会开始一次全新的监视。

发生记录（从成立到解除，其间任何信号丢失的区间单独计）是从这些跳变里推导出来的，应用在哪里显示它们就在哪里推导：操作面板的事件条目卡片、事件页面、历史和那些报告。一段发生记录的持续时间正好是两次持久化跳变之间的间隔，因此它不含成立延时而含复归延时：计时是在条件已经持续满足了成立延时之后开始的，而它要等复归延时走完、解除被写下来时才停。那就是一份报告交给第三方的那个数字。

## 一个事件条目在哪里被用到 {#where-an-occurrence-is-used}

一个流程的页面上带着**这个流程期间投入的事件条目**卡片，配一枚“已投入 `<n>` 个”的小药丸，以及这个模型每一个事件条目一个复选框，按名称排。勾上一个，就在那个流程的运行期间投入它；一个投入时机为**始终**的事件条目不管怎样都在监视，不需要勾。这个模型里一个事件条目都没有时，卡片写着“这个模型里还没有事件条目。请在模型的‘事件条目’下添加。”见[流程](process-procedures)。

给一条通道重命名，会改写这个模型每一条条件里那条通道的 `Channels.<identifier>` 引用；它不动字符串、不动注释，也不动另一个对象上同名的属性。

## 删除事件条目 {#remove-occurrence}

**删除事件条目**在选中这个事件条目时立在详情栏的危险组里，也在它的右键菜单里，还是文件夹页面卡片上那个叉。它先问一次（“删除事件条目”，“这会把这个事件条目从模型里删掉。”），并把它从每一个勾选了它的流程上撤下来。它需要编辑配方与判定，在工程锁定和运行时停止之下变灰。

## 一个事件条目不做的事 {#what-an-occurrence-does-not-do}

- 它不是报警：它不被确认，它没有优先级，它也不监视点位。厂区的报警在 [Logic](logic-alarms) 页面上。
- 它不触发任何东西。一次成立被记录下来并播报出去；没有任何动作、标签或报告挂在它上面。
- 除了这个模型的通道，它什么都读不了：没有点位，没有变量，也没有别的模型。
- 它不会按单元判得不一样：一个条件服务于每一个单元，在那个单元自己的绑定或记录下来的行上判。
