# 通道

> 定义一个模型所用的那些抽象通道（通道号、名称、别名、别名范围、角色、类型、工程单位、颜色和图表分组），以及每一个单元在它们背后绑定的信号源、别名和实时数值。

一条**通道**是模型的一个抽象点。数据记录、配方、判定、事件条目、操作面板、仪表画面和报告只引用通道，从不引用点位，正是这一点让这个模型的每一个单元在构造上就彼此相容。**通道**屏幕（Process > 模型 > 定义 > 通道）把这件事的两半都摆在这里：上面是定义这个模型所用的那些通道，下面是那些单元，旁边则是被选中那一行的设置，也就是一条通道的声明，或者一个单元的绑定表。标题栏写着“这个模型测量什么、下达什么命令，以及每个单元从哪里读它。”，并数出通道数和单元数。

读取需要查看模型；每一次编辑都需要管理 Process 和一台没有被锁住的工作站。这个屏幕穿着每个定义屏幕共用的那一副样子（见[定义](process-definition#the-one-shape-of-the-five-screens)）。

## 模型定义：通道表 {#model-definition-the-channel-table}

标题栏写着“它对每个单元都有效：在这里加一条或删一条通道，每个单元的表都会跟着变。”，并带着**通道**，按它就追加一行。

| 命令 | 做什么 | 什么时候变灰 | 什么时候不画出来 |
| --- | --- | --- | --- |
| **通道** | 在列表末尾添一条通道，名字取第一个空着的“通道 N”，编号取最小的空号；新的一行被选中，设置就在它旁边，并滚动到可见处。 | 工作站被锁住时。 | 角色没有管理 Process（那时整个屏幕都是只读的）。 |
| **把通道上移** / **把通道下移**（行上） | 把这一行挪一个位置；每条通道的编号都不变。 | 这一行已经在最前或最后。 | |
| **删除**（行上，危险色） | 把这条通道从模型上和每一个单元上删掉（见下）。 | | |

每一行都带着整份声明。这一行被选中时，同样这些字段会在设置栏里完整展开，每一个都写在说明它决定什么的那一行上面；两个地方编辑的是同一条通道，因此在哪一边改动，另一边都会显示出来。

| 字段 | 是什么 | 取值 / 默认 | 效果 |
| --- | --- | --- | --- |
| **通道号** | 固定的、由用户指定的通道编号：那个经得起重命名和重新排序的、稳定的人用参照，凡是列出通道的地方都写成 `Ch<n>`（“Ch1 · 设定值”）。 | 一个不小于 1 的整数，在模型内唯一；创建时取最小的空号。 | 已记录的运行记录会保留它，移动这一行也绝不改变它。别的通道已经占着的号会在字段上被拒绝，并写在表下面：“第 3 通道已经属于‘Flow’。一个号只能命名一条通道，因此‘设定值’仍留在第 1 通道。”；小于 1 的号答的是“通道号从 1 开始，因此‘设定值’仍留在第 1 通道。” |
| **名称** | 这个模型的每一件产物所用的那个固定参照：“数据记录、配方、判定和每一次已记录的运行记录都用这个名称称呼它。”它同时也是每个单元的地址点 `Process.<Model>.<Unit>.Channels.<Name>`，以及事件条目条件所读的 `Channels.<name>` 属性。 | 自由文本；创建时是“通道 N”。 | 一次安全重命名：字段下面那一行预告都有哪些引用，提交时会改写那些指向这条通道的地址、数据记录的列、配方的值、判据和别名条目，以及这个模型的事件条目条件里那条通道的 `Channels.*` 引用。两个规范化后得到同一个标识符的名称（保留字母和数字，其余变成 `_`，开头是数字时补 `_`）会被拒绝：“名称‘X’映射到的事件条目引用‘Channels.Y’已经被‘Z’占用。”没有管理 Process 时以及锁住时它是禁用的。 |
| **别名** | “操作员读到的名称。留空则显示通道名称。没有任何东西引用别名，因此改它不会改写任何东西。”整个模型范围的显示名。 | 自由文本；默认为空（占位显示的是名称）。 | 那一栏会补上“对操作员显示为 X。”每一个实时界面、回放和报告读的都是当时生效的别名；地址永远不读它。 |
| **别名范围** | 一个单元是否可以按它自己的方式称呼这条通道。单元格提供**整个模型**或**每个单元**；那一栏把两个答案都写全：“整个模型一个”和“每个单元可以自己定”。 | 两个答案；默认“整个模型一个”。 | “允许命名它的单元，在自己的绑定旁边或者通过别名集来命名。”选“整个模型”这个答案时，单元的别名单元格会拒绝编辑，别名集既不为这条通道提供条目也不写它，而且即便某个绑定还留着一个按单元的名字，也没有东西按那个名字读它；切回去时原来的东西又回来了。 |
| **角色** | “模型可以拿这条通道做什么：读它、写它，或者两者都行。” | **只读**（“被采样、画在图上、参与判定。没有配方写它。”）、**只写**（“配方的目标。没有东西把它采样回来。”）、**读写**（“由配方写入并采样回来：常见的设定值。”）；默认只读。 | 角色决定一个单元可以绑定哪些信号源（被采样的通道需要可读的信号源，只作命令的通道需要可写的信号源）、配方能不能以这条通道为目标，以及图表画不画它。 |
| **类型** | 粗粒度的值类别：“单元只能绑定值属于这一类的点位。” | **布尔值**、**整数**、**小数**、**文本**、**日期和时间**；默认小数。 | 布尔值收布尔点位，整数收任何整数家族，小数收任何数字，日期和时间收 DateTime，文本收任何信号源。绑上去的信号源不合适时，不管是点位还是变量，都会在这个单元那一行上标出来。 |
| **工程单位** | “这条通道的每一个读数以什么单位书写。留空则不带单位。” | 自由文本；默认为空（占位写“无”）。 | 印在每个读数后面，也印在图表的标尺上和导出里。在这个字段下方，那一栏会按通道的类型、带上这个工程单位显示一个示例读数，写法和单元上这条通道的实时读数一样（“读作 24.53 bar”）。 |
| **颜色** | 这个模型的每一张图画这条通道所用的墨色：一块可选的色块，加上可读、可输入、可粘贴、可清空的十六进制值。 | 一个十六进制颜色，例如 `#D62728`，或者留空（占位写“调色板”）。 | 留空就把这条线交给调色板，由它按这条通道在被画通道中的位置发一个稳定的颜色；色块永远显示当时生效的墨色，由调色板发色时它的边框画得不一样（“没有声明颜色：这一条由调色板分配。选一个就成为通道自己的颜色。”对着“这条通道声明的颜色。清空十六进制值，这条线就交回给调色板。”）。解析出来的墨色会冻结进每一次运行，因此一条已记录的曲线在模型被重新上色或删除之后仍然保留它。你自己拼出来的图表保留它自己的颜色。 |
| **分组** | 这条通道在层叠图表里被读的那一条带；字段提供模型里已有的那些分组，也接受一个新的。 | 自由文本；默认为空（占位写“未分组”）。 | 指定同一个分组的通道共用一条带和一根数值轴，每一条带都沿着同一根时间轴，而这条带的标尺上写着分组名称和它那些通道一致同意的工程单位。留空就加入未分组通道共用的那一条带。 |

行的顺序只是显示顺序：一条通道不管落在哪里都带着它的编号，因此编号那一列老老实实读作 1、5、2 也不奇怪。这个模型里凡是显示通道的列表都跟着这个顺序，并把这个编号写成 Ch1、Ch5、Ch2 放在名称前面。

保存是这两条规则的最后一道防线：从别的路径重复走到这里的号会被拒绝，说“通道号 *N* 被不止一条通道占用。在一个模型里，一个号只属于一条通道。”；两个落到同一个引用上的名称则会得到“不止一条通道映射到事件条目引用‘Channels.*通道*’。”

### 一条通道的设置栏 {#the-settings-column-for-a-channel}

在那些字段下面，这一栏画出这个模型的每一个单元将来会显示在屏幕上的那张图：每一条可读通道都以全强度画在一段示例走线上，用的是画一张操作面板的通道卡片所用的那同一个构造器。下面写着“颜色和分组决定这条通道在这个模型的每一张图上怎么画。”，以及被选中的通道落在哪里：“画在 压力 这一条带上，用自己的一套刻度。”“画在最上面那一条带上，和没有指定分组的通道在一起。”“和其他所有通道画在一起，共用一套刻度。”，或者对只写通道写“配方的目标不被采样，因此没有图会画它。”

### 删除一条通道 {#removing-a-channel}

**删除**先把够得着的范围数出来再动手：“要从这个模型的每一个单元上删除通道‘Flow’（第 3 通道）吗？这同时会删除 2 个数据记录列、1 个配方设定值和 3 个单元绑定。此操作无法撤销。”（或者“没有别的东西引用它。此操作无法撤销。”）。两个按钮写着**删除**和**保留这条通道**。这次删除会一并扫掉数据记录的列、配方的设定值、曲线段的目标、单元的绑定、判定的判据（把这条通道当作参考通道的判据会失去那个参考）和别名条目。保存被拒绝时一切都放回去。

## 按单元：单元列表 {#per-unit-the-units-list}

下面那一块按顺序列出这个模型的单元，标题栏最末端是**管理单元**（点它打开模型的页面，单元在那里添加、命名和移除）。

| 列 | 显示什么 |
| --- | --- |
| **单元** | 单元的名称。 |
| **绑定** | 按模型读出来的覆盖情况：“还没有通道”“已绑定 6 条，没有缺失”，或者用警示色写的“已绑定 4 条，缺失 2 条”。 |

只有被选中的那个单元才构建行、才采样数值；其余的行不花任何代价。

## 被选中单元的绑定表 {#the-binding-table-of-the-picked-unit}

选中一个单元，就在设置栏里打开它的绑定表（“单元 · 单元 1”）：这个模型的每一条通道一行，按通道顺序排。

| 列 | 是什么 | 效果 |
| --- | --- | --- |
| **通道** | `Ch<n> · 名称`。 | 只读。 |
| **角色**、**类型** | 这条通道的角色和类别，用词与上面的通道表相同。 | 只读。 |
| **信号源** | 这条通道在这个单元上读或写的那一个值来源：一个 [Connector](connector) 点位或者一个 [Logic](logic) 变量，绝不会两者都要。 | 下拉框先提供**（无）**，然后是已启用设备上的每一个已启用点位，写作“驱动 · 设备 · 点位”，再然后是每一个变量，写作“变量 · 名称”（放在文件夹里的变量写作“变量 · 文件夹 / 名称”，同名的变量也能分清），并按角色能用的范围收窄：被采样的通道只提供可读的信号源，只写通道只提供可写的；变量和（无）两边都合适。选中就立刻提交。没有绑定的通道采出来是一段空缺，绝不是一个错误。 |
| **别名** | “这个单元用这个名称读这条通道。留空则回到通道自己的名称。” | 只有在通道的范围是“每个单元可以自己定”时才能编辑；否则单元格是禁用的，悬停提示写着“这条通道对所有单元只用一个名称。请到上面的通道表里改。”给一条没有绑定的通道设别名会创建出绑定那一行；当时生效的名称会被快照进每一次运行。 |
| （警告图标） | 绑上去的信号源不合这条通道的类型时显示：点位是节点类型不合，变量是声明的输出类别不合。工作站解析不出来的信号源没有可以冲突的类型，因此不加标记。 | 悬停提示：“点位类型‘String’与通道类型‘小数’不兼容。”或者“变量类型‘文本’与通道类型‘小数’不兼容。” |
| **共享写入** | 对可写的通道，写出另外哪些单元对某条可写通道的绑定解析到了同一个信号源：同一模型上写单元名，跨模型时写“模型 · 单元”。 | 共用一个写入信号源的两个单元不能同时跑：第二次启动会被指名拒绝。读取从不共享。 |
| **数值** | 绑定信号源的实时读数，这张表打开期间每 500 ms 采样一次，用工作站的数字格式写出（[语言与格式](settings-localization)）：整数不带小数，小数按工作站的小数位数，日期和时间按工作站的格式。 | 只读。 |
| **清除绑定**（行上，危险色） | 把这一行的两种信号源都清掉。 | 别名留着。 |

工作站已经不再提供的信号源（被移除的点位或变量，或者键被另一个点位争走了的点位）仍然留在行上，写作“点位不可用 · 键”或者“变量不可用 · 键”，处于禁用状态，理由是“这个信号源已不再可用；请清除或替换它。”被通道的角色不再接受的信号源（比如一条只写通道绑到了一个只读的点上）也照样写出名字，理由则是“这个通道只下达命令，而这个信号源无法写入。请清除或替换它。”或者它可读的那个对应说法。这样的一行只能清除或替换。

每一次绑定编辑都通过模型自动保存。工作站被锁住期间写入会被拒绝（“有单元在运行时配置是锁住的。”），单元格随之回退，因此正在运行的单元的绑定不会在它脚下被改掉；已经在记录的运行保留它在启动时解析出来的那些信号源。模型在底下被重新载入之后才到达工作站的编辑会被拒绝，理由是“单元配置已更改。请检查绑定后重试。”一行如果最后同时指向两个信号源，就永远到不了数据库：“通道‘*名称*’的绑定同时指向点位和变量。请只选一个。”

### 应用一个别名集 {#applying-an-alias-set}

模型里有别名集时（设定 > 别名），表下面立着一个选择框和**应用**：“把一套命名好的通道名称应用到上面的别名上。把这一套应用到某个单元，会覆盖该单元的全部别名，因此这一套没有命名的通道会回到通道自己的名称。在你重新应用之前，手工改动优先。”应用是对这个单元的别名做一次完整的、看得见的覆盖：别名集指名的通道取那个名字（通道没有绑定时会把绑定那一行创建出来），别名集没有列出的通道别名被清空，而范围是“整个模型一个”的通道则完全不去碰。一个流程也可以钉住一个别名集，那样在这个单元上预选该流程时就会应用它；见[别名集](process-aliases)。

## 这个屏幕不做的事 {#what-this-screen-does-not-do}

- 它不声明任何单元：添加、命名和移除一个单元是模型页面上的单元表格的事（[单元](process-units)）。
- 它什么也不记录：一次运行记录哪些通道、多久记一次，是[数据记录](process-datalogs)的事；配方的目标在[配方](process-recipes)上。
- 它只显示被选中单元的实时数值，而且从不写值：一条可写通道是由配方、某个仪表画面组件或者一个命令点位写的。
- 颜色和分组是这个模型每一张图的默认值；你自己拼出来的仪表画面保留你在它上面选的墨色。
- 它不改动正在运行的单元：工作站被锁住期间每一次写入都会被拒绝。
