# 运行记录与备注

> 一个单元的操作面板：预选流程和它的元数据、启动以及它校验什么、暂停、继续、停止和中止、那些实时卡片、备注、单条命令、运行记录文件，还有自动化路径和代理路径。

一个单元的**操作面板**（Process > 模型 > 某个模型 > 操作 > 那个单元 > 某张面板，以及它标着“在 View 上显示”时 View 页面上同一张面板），就是预选、启动、操控和观看一次运行记录的地方。它画哪些卡片、按什么顺序画，是在模型上的可视化 > [操作面板](process-panels)里排一次的；这个模型的每个单元随后都通过同一个界面来操作。看只需要那棵树。这张面板上的每一条命令都需要**运行流程**；没有它，面板打开时带着这条提示“你可以在这里观看这个单元的运行状态，但启动或操控它需要‘运行流程’权限。”，一个生命周期按钮都不画。

工作站没有东西可给的卡片会被略去，而不是画成空白：单条命令卡片需要模型上有一份数据记录或者一个即时配方，通道卡片需要一条可读通道，元数据卡片需要一个会提示填写字段的预选流程（或者干脆什么都还没预选），嵌进来的仪表画面则需要上面放了东西。一张一张卡片都没排的操作面板读作“这个操作面板不画任何卡片。请在模型‘可视化’下的‘操作面板’一行里选择它的卡片。”。

## 联锁提示条 {#the-interlock-banner}

模型观测一个外部停止信号时（见[自动化](process-automation)），这个单元的联锁立在每一张卡片之上，而在它正常期间什么也不画。否则它是一条提示条，标题写着**联锁已触发**（醒目）、**联锁等待复位**或者**联锁不可用**，带着理由、信号源的名称、它的值和它的质量。只要它不是正常，这个单元上就不再受理新的启动、继续、快照、判定或者套用配方。一次触发会通过普通的结束路径把正在进行的运行记录结束掉，以**已中止**、结论**不合格**、结束原因**联锁**收场，而且不点任何人的名说是谁结束了它。这个锁定挺得过一次重启。**复位**只在等待复位时出现，它需要运行流程权限、一个读数良好且已安全的信号源，以及一个没有运行记录占着的单元；它清掉这个锁定，按操作员的名字记进日志，而且绝不会把已中止的那次运行记录重新启动。

## 运行记录卡片 {#the-run-card}

卡片的头上带一盏灯，说出这个单元此刻在做什么，用的字眼和颜色与单元页面上那枚胶囊相同。等待设定值压过其他任何读数。

| 灯 | 颜色 | 什么时候 |
| --- | --- | --- |
| **未在记录** | 灰色 | 没有运行记录占着这个单元。 |
| **准备中** | 灰色 | 启动已经预留了这个单元，而运行记录还不存在。 |
| **记录中** | 绿色 | 运行记录正在采样。 |
| **正在等待设定值抵达设备** | 警示色 | 配方已经把某一段的设定值交了出去，正等着现场设备收下；这一段自己的时间还没开始计，数据记录照旧在记。只有设为等待的段才会显示它（见[配方](process-recipes#what-a-run-does-with-it)）。 |
| **已暂停** | 警示色 | 暂停把时序窗口冻结在最后一个设定值上；数据记录继续记录。 |
| **保存中** | 灰色 | 采样已经停下，正在写这次运行记录的快照。 |
| **收尾中** | 灰色 | 运行记录已经到达最终状态，正在关掉它的文件；这个单元还没有空出来。 |

| 字段 | 是什么 | 取值 / 默认 | 效果 |
| --- | --- | --- | --- |
| 流程 | 为下一次启动预选好的那个流程。 | “（无）”加上这个模型的每一个流程，按字母顺序；默认什么都不预选，而且应用启动时预选归零。 | 预选是全工作站范围的：这个单元的每一个屏幕、`Next.Procedure` 这个点位和操作卡片显示的是同一个选择。预选一个锁定了别名集的流程，会在预选的那一刻就把那一套应用到这个单元上，而不是等到启动；应用不了的锁定会让原来的预选留在原处，并在卡片上说明为什么。没有运行流程权限时以及运行时已停止时，这个选择器变灰。 |

生命周期按钮，按画出来的顺序排列。预选的流程是受控流程或者即时流程时，暂停和继续被略去，因为只有时序运行记录才有窗口可冻结；什么都没预选时五个都画出来。

| 命令 | 做什么 | 什么时候变灰（情形） | 什么时候不画出来（角色） |
| --- | --- | --- | --- |
| 启动 | 在这个单元上启动预选的流程。 | 单元忙、没有预选流程、运行时已停止、联锁不是正常，或者工作站正在拒绝写入。 | 没有运行流程时。 |
| 暂停 | 把时序窗口冻结在最后一个设定值上；数据记录继续记录。 | 没有运行记录处于运行中，或者正在跑的流程不是时序的。 | 没有运行流程时；预选的流程是受控流程或即时流程时。 |
| 继续 | 解除暂停，让窗口继续走。 | 没有运行记录处于已暂停，或者联锁不是正常。 | 没有运行流程时；预选的流程是受控流程或即时流程时。 |
| 停止 | 从运行中或者从已暂停干净地结束这次运行记录，并把它冻结成历史。 | 没有运行记录占着这个单元。 | 没有运行流程时。 |
| 中止 | 以中止方式结束这次运行记录；收尾块仍然执行。 | 没有运行记录处于运行中或已暂停。 | 没有运行流程时。 |

被拒绝的命令把理由写在卡片上（“没有预选任何流程。请先选一个。”），而按钮下面那两行常设文字说明工作站或者这个单元为什么不接受命令：“运行时已停止”，以及联锁的理由。

## 启动，以及它校验什么 {#start-and-what-it-validates}

启动消耗这个单元的预选，并在动用任何资源之前就把该拒绝的都拒绝掉。顺序是：单元被预留（同一个单元上的第二次启动被拒绝）；预选的流程必须仍然存在（“预选的流程已经不存在。请重新选一个。”），而且预选不能在启动等待一次工程编辑完成的时候被挪动过（“等待启动期间，预选的流程或元数据发生了变化。请检查准备好的运行记录后重试。”）；流程必须通过它自己那一页显示的那道关（“没有可执行的内容：这个流程既没有引用数据记录，也没有引用配方。”“时序方式需要一个时长。请设定一个。”“即时方式需要一个即时配方，或者不用配方。时序曲线没有单一的时刻。”“配方曲线（*N* ms）比时间窗口（*M* ms）长。”，以及那些计入产出的检查）；每一个投入的事件条目都必须有一个有效的条件；至少有一条数据记录通道要在这个单元上解析到一个已绑定的信号源（“在单元‘X’上，没有任何数据记录通道解析到已绑定的信号源。”）；被提示填写的元数据必须完整且类型正确（“元数据字段‘X’是必填的。”“元数据字段‘X’必须是数字。”），而每一个流水号字段都必须拼得出来（缺少单元代号或流程代号会让这次启动被拒绝）；联锁必须是正常；配方要写的每一个信号源都必须是空闲的（被另一个单元的运行记录占着的信号源会让这次启动被拒绝，并点名是哪条通道、被哪个单元占着）。到这时才预留那些流水号计数器、创建运行记录文件并把元数据已经写进去、把各个引擎启动起来；流程在开始时产出的那些标签和报告，随着这次运行记录成形而发出去（见[产出标签与报告][emission]）。

[emission]: process-emission

## 元数据卡片 {#the-metadata-card}

这张卡片的标题写着“‘流程’的下一次运行记录以什么身份记录下来。带 * 的字段每个流程都会提示填写。”，并按流程的顺序，为预选流程提示填写的每一个元数据字段画一项；什么都没预选时它读作“预选一个流程，它提示填写的字段就会出现在这里。”。

| 字段类型 | 卡片画出什么 | 效果 |
| --- | --- | --- |
| 文本 | 一个输入框。 | 边打边写进全工作站范围的预选区；启动时把它记进运行记录文件。必填字段（带 *）会拒绝一次留空的启动。 |
| 数字 | 一个输入框。 | 同上，而且启动会拒绝一个不是数字的值。 |
| 流水号 | 对计数器此刻会拼出的那个标识的只读预览，或者在还没有计数器状态时写“开始时已预留”。 | 看一眼不会占下任何东西：最终值是在启动时才预留的，因此几个单元共用的计数器在那之前可能还会往前走。 |

预选是被启动消耗掉的，不是被清空的：那些填好的内容作为默认值留给同一个流程的下一次运行。为另一个流程打进去的内容留在预选区里，但是不起作用，因为启动只读预选流程的那些字段。没有运行流程权限时以及运行时已停止时，这些输入框变灰。

## 运行状态卡片 {#the-run-state-card}

三个读数：**状态**（运行中、已暂停、保存中、已完成、已中止、失败，或者单元被预留期间写“准备中”，没有东西占着它时写“空闲”）、**循环**（循环运行记录写“2 / 10”，否则写“不循环”；预选的流程是受控流程或即时流程时整个被略去）和**结论**（判定给出的实时结论，运行记录结束之后仍然读得到，直到下一次运行记录开始；什么都还没判过时写“无”）。没有运行记录占着单元时，仍然显示的结论属于上一次运行记录，这时读数的名字是**上次运行记录的结论**，免得被当成即将开始的运行记录的结论。

## 每一种结束各做什么 {#what-each-end-does}

| 结束方式 | 记录 | 配方 | 结论与状态 |
| --- | --- | --- | --- |
| 停止 | 收尾块执行完之后采样才停止，因此那次到安全状态的过渡在数据记录里。 | 收尾的那些设定值被写下去。 | 判定关掉它开着的那些窗口并合成结论：合格、不合格、无法判定，或者没有判定时是“无”。已完成。 |
| 中止 | 同上。 | 收尾的那些设定值被写下去。 | 无论判出过什么，都是不合格。已中止。 |
| 窗口走完（时序）或者那一行记完（即时） | 同上。 | 收尾的那些设定值被写下去。 | 和停止一样。已完成；不点任何人的名说是谁结束了它。 |
| 一次配方写入失败，而失败处置设为中止 | 同上。 | 收尾仍然执行。 | 不合格。已中止。 |
| 联锁动作 | 同上。 | 收尾仍然执行。 | 不合格。已中止，结束原因为联锁。 |
| 运行时停止 | 每一条还没封存的运行记录都被中止。 | 收尾仍然执行。 | 不合格。已中止。 |
| 一个无法恢复的错误 | 采样停止；不做收尾。 | 不再写任何东西。 | 无。失败。 |

关闭应用不会结束任何东西：处于运行中或已暂停的运行记录会在下一次启动时继续下去，时序曲线停在它保存下来的那个曲线段和那个循环上，而数据记录在同一个文件里接着记。

## 通道卡片 {#the-channels-card}

这个单元的可读通道画在一张实时图上，每条系列用这个单元上生效的那个名称作标签（别名是实时显示的），并用模型在这条通道上声明的颜色和分组画出来，带着每张图都有的那条图表工具栏（见[图表](view-charts)）。无论有没有运行记录在记录，它显示的都是实时值。只有当某个保留上限削减了这张图保留的历史（一个通道能保留的量、一张图在它所有通道上合计能保留的量，或者工作站在所有实时图表上合计保留的量）时，画面下面才会出现一行，说出这个上限留下了什么；拿到了所要求的全部历史的图表不带这一行。这些上限见[折线图](component-line-chart#history)。

## 备注卡片 {#the-comments-card}

有运行记录活着时，这张卡片的标题写着“备注 · 流程 · 单元”，否则写“备注 · 没有正在进行的运行记录”；空闲的单元不显示时间线，而已结束的运行记录，它的备注要到[备注与标注](histories-notes)里去写。每一条已记录的行都显示它的时刻、它的阶段（运行中或运行之后）和它的文字，带两个动作：**编辑**就地改写它（回车保存，Esc 取消；留空或者没改动就不动这条记录，而一次改写会盖上编辑时刻），**删除**需要按两下，第一下把这一行武装起来（“要删除这条备注吗？此操作无法撤销。”），第二下才把它移走。底下那个输入框（“添加一条备注……”）和**添加**记下新的一行，盖上时刻和在这个屏幕上登录的操作员（没有人时就是工作站）。这三个动作都需要运行流程权限和一次活着的运行记录。同样这次追加，仪表画面和代理也可以通过这个单元的 `Commands.Comment` 点位做到（见[单元地址空间](process-addresses)）。

## 事件条目卡片 {#the-occurrences-card}

这个单元的那些事件条目发生记录，活动的排在前面，每一条带着它的状态、它的两个时钟（持续时间和信号丢失时间）和随它冻结下来的那条消息；卡片头上数出有多少条活动的。一段发生记录是什么、它的那些时钟怎么算出来，写在[事件条目](process-occurrences)里。

## 产量卡片 {#the-productivity-card}

这个单元在**今天**或者滚动窗口上的生产活动（头上有一个分段控件）：产量、合格率和典型历时、产出台账、完成结论，以及一张按流程分的表。什么算数、怎么算出来的，写在[产量](process-productivity)里。

## 单条命令卡片 {#the-single-commands-card}

在任何流程之外，对这个单元发出一条孤立的命令。只有模型声明了它所依据的东西时，那一行才出现。

| 行 | 控件 | 做什么 | 什么时候变灰 |
| --- | --- | --- | --- |
| 快照 | 一个数据记录选择器和**采集** | 立即记录一行数据记录，作为历史里一次已完成的即时运行记录，名叫 `Snapshot · 数据记录名`。 | 单元忙、联锁不是正常、运行时已停止、还有一条单条命令在执行，或者没有运行流程权限。 |
| 立即判定 | 一个数据记录选择器、一个判定选择器和**判定** | 记录一行并立即按判定来判它；这次运行记录名叫 `Evaluate · 判定名`，并带着此刻的结论。只有模型既有数据记录又有判定时才画出来。 | 同上。 |
| 套用配方 | 一个覆盖这个模型即时配方的选择器和**套用** | 在一把短命的锁下，把配方的设定值经写入出口写一次；不记录任何运行记录，日志就是记录。被一次活着的运行记录占着的信号源会拒绝它。 | 联锁不是正常、运行时已停止、还有一次套用在执行，或者没有运行流程权限。单元正在记录期间它仍然可用。 |

快照和判定不提示任何元数据，不预留任何计数器，也绝不计入产出。结果落在操作记录条上（“快照已记录。请看‘历史’。”“已判定。结论记在‘历史’里。”“配方已套用。”）。

## 仪表画面作为卡片 {#dashboards-as-cards}

一张操作面板可以把这个模型的任意一张仪表画面当作一张卡片嵌进来，高度按面板上选定的值。这张卡片跑的是为这个单元解析出来的那份模型定义，和这个单元自己那个仪表画面节点一模一样，而它的命令类组件只需要运行流程权限。

## 数据记录 {#the-datalog}

一次运行记录在记录期间，它的流程所指名的那份[数据记录](process-datalogs)每隔一个间隔写一次应用层快照：每一条被记录的通道，按声明的列顺序排列，每个值都配一个良好或者不可用的标志。这一行承诺的是应用层面的一致观测，不是物理上同时的采集：各个信号源设备按各自的速率刷新。不可用的信号源或者转换不了的值存成一个空档；正确收到的 `NaN` 或者工程哨兵值仍然是良好。更短的间隔从界面进不来：数据记录的“快照间隔（ms）”字段会拒绝低于 50 ms 的值（“请输入不小于 50 的数字。”），输入框退回当前的间隔。从别的途径到达一次运行记录的间隔一直照原样使用，最低到 50 ms；比这更低的都按 50 ms 处理。

## 运行记录文件 {#the-run-file}

运行记录文件就是那份完整的记录：稳定的模型、单元和流程标识与名称、模型修订号、冻结下来的通道版面（每一列都带着解析出来的图表用色）、那些元数据值、实际执行的配方写入、判据结果、事件条目事件、备注、图表标注、生产记录、标签存档件和报告登记。冻结下来的那份上下文是在启动时采集的，此后绝不改动；收尾程序只添上结果：结论、最终状态、结束时间、是谁结束了这次运行记录，以及在联锁结束它时的结束原因。删掉模型、单元或者流程，绝不会触动一条已记录的运行记录。从运行记录文件浏览、导出和重新生成文档，写在[历史](histories)里。

## 自动化路径 {#the-automation-path}

启用了[自动化](process-automation)的单元，从现场接过同一套生命周期：绑定到启动、暂停、继续、停止或中止的那个布尔信号源上升沿到来，就触发那条命令。同一次轮询里中止压过停止，而任何别的一对同时到来的沿都被当作冲突拒绝。自动化的启动从固定选择或者数字选择器解析出它的流程，从配置好的那些信号源解析出它的元数据，完全不碰操作员的预选，而且只有单元已经为启动做好准备时才受理。结果被写回映射为命令结果的那个返回点位：0 等待 / 已复位、1 已受理、2 单元未就绪、3 选择无效、4 元数据无效、5 命令不相容、6 命令冲突、7 内部故障。自动化受理的运行记录，在历史里带着**自动化**徽记列出来，把自动化记为责任人，而在一次自动的停止或中止之后，也把它记为结束者。

## 代理与仪表画面 {#agents-and-dashboards}

内置的代理服务器通过它的 Process 操作类工具（启动、停止、暂停、继续、中止、备注、快照、判定、套用配方）驱动同一套生命周期，在日志里记为 Agent，在运行记录里也记为 Agent（见[代理访问（MCP）](agent)）。一张仪表画面通过这个单元的那些命令点位够到它：绑在 `Commands.Start` 上的按钮在就绪状态读作假时自己禁用，绑在 `Next.<Field>` 上的输入框预选一个值（见[单元地址空间](process-addresses)）；流程本身在[运行记录卡片](#the-run-card)上预选。

## 这个界面不做的事 {#what-this-surface-does-not-do}

它什么也不配置：通道、绑定、元数据、联锁和自动化都在[定义](process-definition)下面编辑；一次运行记录套用什么、记录什么、判什么，在[设定](process-setup)下面拼装。它不编辑一条已结束的运行记录：一条已记录的运行记录的事后补记、标注、导出、报告和标签都属于[历史](histories)。而且它绝不画一张工作站填不满的卡片。
