> ## Documentation Index
> Fetch the complete documentation index at: https://all.mimedal.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 操作

> 说明厂商设备接口在操作维度必须提供的动作参数、执行结果和完成证据。

操作是厂商设备接口必须包含的一个维度。它承载这次要做的动作、参数、实际结果和完成证据；动作的通用含义由 FSP 服务中的[动作契约](/docs/specification/fsp/action-contract)定义。厂商不必为操作维度单独建立一套接口，但必须在现有调用和结果中提供这些内容。

## 操作说明字段

每项设备操作都应提供以下说明：

| 字段                      | 含义                 | 可以填写的内容与示例                                                                          |
| ----------------------- | ------------------ | ----------------------------------------------------------------------------------- |
| `operation_id`          | 在当前设备定义中稳定标识一项操作   | 可填 `add_liquid`、`set_temperature`、`start_stirring`、`measure_absorbance`；版本升级时不应随意改名 |
| `name`                  | 面向使用者的简短名称         | 可填“加液”“设定温度”“开始搅拌”“测量吸光度”                                                           |
| `description`           | 说明操作对象、动作和预期结果     | 例如“向指定离心管加入给定体积的液体，并返回实际加液结果”                                                       |
| `parameters`            | 操作接受的参数定义集合        | 例如加液量、来源容器、目标温度、转速、持续时间、测量波长；无参数操作可为空集合                                             |
| `preconditions`         | 操作逻辑自身必须满足的执行前条件   | 例如“加液量位于声明范围”“目标温度不得低于环境露点”“转速与容器类型兼容”                                              |
| `effects`               | 操作成功后预期发生的变化       | 例如“目标容器样品体积增加”“设备设定温度更新”“搅拌状态变为运行中”                                                 |
| `completion_conditions` | 判定操作完成的条件          | 例如“实际加液量完成并通过核验”“温度进入允许偏差范围并保持 30 秒”                                                |
| `result_fields`         | 成功、失败或未知结果时需要返回的字段 | 例如实际体积、实际温度、测量值、持续时间、完成时间和结果质量标记                                                    |
| `diagnostic_codes`      | 该操作可能产生的格式固定的错误说明  | 例如参数越界、液量不足、目标未定位、执行超时、结果无法确认                                                       |

## 参数字段

`parameters` 中的每个参数应分别说明：

| 字段                                      | 含义            | 可以填写的内容与示例                                                           |
| --------------------------------------- | ------------- | -------------------------------------------------------------------- |
| `name`                                  | 参数的稳定名称       | `volume_mL`、`temperature_c`、`speed_rpm`、`duration_s`、`wavelength_nm` |
| `type`                                  | 参数的数据类型       | `string`、`number`、`integer`、`boolean`、`array`、`object`               |
| `description`                           | 参数的物理含义与使用方式  | 例如“单次加入目标容器的液体体积”                                                    |
| `unit`                                  | 参数使用的标准单位     | `mL`、`μL`、`°C`、`rpm`、`s`、`nm`；无量纲参数可不填                               |
| `minimum`、`maximum`                     | 单个参数允许的闭区间    | 加液量可填最小 `0.05 mL`、最大 `0.8 mL`；温度可填 `20–120 °C`                       |
| `exclusive_minimum`、`exclusive_maximum` | 不允许等于边界时使用的范围 | 例如压力必须大于 `0 MPa`，但不得等于零                                              |
| `enum`                                  | 参数允许选择的有限值    | 搅拌方向可填 `clockwise`、`counterclockwise`；工作模式可填设备声明的模式集合                |
| `pattern`                               | 字符串格式约束       | 孔位可使用类似 `A1`、`H12` 的格式规则；容器标识可限制字符集合和长度                              |
| `default`                               | 未提供参数时采用的值    | 例如默认持续时间 `60 s`；不宜设置会掩盖错误的默认值                                        |
| `precision`                             | 允许的小数位数或分辨率   | 体积可精确到 `0.001 mL`，温度可精确到 `0.1 °C`                                    |
| `items`                                 | 数组元素的类型和约束    | 批量孔位可规定每项为孔位字符串，且数量不得超过设备批处理上限                                       |

参数约束既用于编译和仿真，也必须在设备动作前再次校验。参数之间存在关系时，还应说明跨字段约束，例如“总加液量不得超过目标容器剩余容量”“转速越高时允许的最大持续时间越短”。

## 调用时的操作字段

| 字段                 | 含义                  | 可以填写的内容与示例                                   |
| ------------------ | ------------------- | -------------------------------------------- |
| `operation_id`     | 本次准备执行的操作           | 例如 `add_liquid`，必须与设备声明的操作标识一致               |
| `contract_version` | 本次依据的操作契约版本         | 必须与绑定一致；省略时只能采用承载明确固定的版本，不得自动选择最新版本          |
| `parameters`       | 本次操作的实际参数值          | 例如来源容器为 `source-01`、加液量为 `0.5 mL`；字段必须符合参数定义 |
| `preconditions`    | 调用方已知且要求设备再次确认的操作条件 | 例如“加液量符合范围”“目标容器必须处于无盖状态”                    |
| `requested_result` | 调用方希望返回的附加结果        | 例如要求返回实际体积、温度曲线或测量质量标记；不得据此省略基础结果字段          |

## 返回时的操作字段

| 字段                          | 含义           | 可以填写的内容与示例                                                                                                    |
| --------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- |
| `operation_id`              | 返回结果对应的操作    | 应与调用中的操作标识一致                                                                                                  |
| `status`                    | 操作执行状态       | `rejected`、`accepted`、`running`、`waiting_confirmation`、`succeeded`、`failed`、`cancelled`、`unknown`；转换规则见任务生命周期 |
| `actual_parameters`         | 有证据的参数回读与测量  | 应区分 `adopted_settings` 与 `measured`，并关联证据；仅收到受理回执时为空对象                                                        |
| `result`                    | 操作产生的设备返回的数据 | 例如测量值、完成数量、实际持续时间或设备确认的动作结果                                                                                   |
| `progress`                  | 当前完成程度       | 可填百分比、已完成步骤数或阶段名称，例如 `60%`、`3/5`、`stabilizing`                                                                |
| `started_at`、`completed_at` | 实际开始和结束时间    | 使用带时区的时间；未开始或未结束时相应字段可为空                                                                                      |
| `diagnostics`               | 结构化执行诊断集合    | 成功时可为空；失败时填写错误码、说明、相关字段、是否可重试和已确认事实                                                                           |

## 填写示例

以加液操作为例，操作说明可以声明：操作标识为 `add_liquid`；参数包括来源容器标识和加液体积；体积类型为数值、单位为毫升、允许范围为 `0.05–0.8 mL`；完成条件为设备确认液体已经加入且实际体积得到核验。调用时可以填写来源容器 `source-01` 和体积 `0.5 mL`。完成后的操作结果可以填写状态 `succeeded`、实际体积 `0.498 mL`、诊断为空。

以设定温度操作为例，可以声明目标温度、升温速率和稳定时间三个参数。目标温度可限制为 `20–120 °C`，升温速率可限制为 `0.1–10 °C/min`。完成后返回实际稳定温度、达到稳定状态的时间以及超调量；如果温度未在规定时间内进入允许偏差，则状态填写 `failed`，诊断说明超时和实际温度。

## 强制规则

定义和检查一项动作的流程见[动作契约伪代码](/docs/specification/fsp/adapter#1-动作契约把动作的意思写清楚)，可运行实现见 [GitCode 示例源码](https://gitcode.com/mimedal/all/blob/main/examples/fsp_three_parts.py)。

* 操作参数必须声明类型、含义以及适用的范围、枚举或格式约束；
* 调用前必须同时校验对象状态、操作参数和系统条件；
* 返回结果必须反映设备实际执行情况，不得把计划参数直接当作实际结果；
* 失败、取消或结果未知时，不得报告预期成功状态；
* FSP 不规定操作在 HTTP、CLI、MCP、RPC 或 SDK 中的具体名称与路径。

## 怎样判断操作成功

每项操作必须写清“做到什么才算成功”：用 `completion_scope` 指定完成范围，并列出完成条件、可以采用哪些测量或检查、允许多大误差、需要持续多久或何时超时。

返回 `succeeded` 只表示这些条件已满足。例如，“温度设定值已写入”不能说明样品已经达到目标温度。

| `completion_scope`       | 能证明什么          | 不能据此推断什么           |
| ------------------------ | -------------- | ------------------ |
| `protocol_response`      | 指定命令获得符合协议的响应  | 参数实际生效、设备运动结束或样品效果 |
| `configuration_readback` | 参数从设备回读并符合要求   | 样品达到目标温度或完成处理      |
| `physical_process`       | 指定机械或工艺过程按条件结束 | 未测量的体积、成分或反应结果     |
| `sample_effect`          | 按规定的方法检查样品指标   | 未检测的其他样品性质         |

这些范围不构成自动继承关系。每个操作独立规定必需证据；例如离心周期结束可能还要求转子停止，温度设定值回读不能证明样品已经恒温。

用于判断完成的记录放在 `operation.completion_evidence` 中。每条至少写清记录编号、来源、设备、相关任务和容器、测量字段、值、适用单位、观察时间、有效期，以及是不是模拟结果。

对应字段为 `evidence_id`、`source`、`device_id`、适用的 `task_id` / `container_id`、`field`、`value`、单位、`observed_at`、有效期和 `simulated`。来源可以是设备硬件 `hardware`、外部传感器 `external_sensor`、人工检查 `human` 或计算推导 `derived`。人工检查和计算推导只有在操作定义明确允许时，才能用于判断对应条件。

```json theme={null}
{
  "operation_id": "add_liquid",
  "status": "succeeded",
  "completion_scope": "sample_effect",
  "actual_parameters": {
    "measured": {"volume_mL": 0.498}
  },
  "completion_evidence": [{
    "evidence_id": "evidence-01",
    "source": "external_sensor",
    "observer_id": "volume-sensor-01",
    "device_id": "device-01",
    "task_id": "task-001",
    "container_id": "container-01",
    "phase": "completion",
    "basis_revision": "object-21",
    "field": "dispensed_volume",
    "value": 0.498,
    "unit": "mL",
    "observed_at": "2026-09-21T06:00:00Z",
    "expires_at": "2026-09-21T06:01:00Z",
    "simulated": false
  }],
  "diagnostics": []
}
```

这里只展示结果中的操作部分。假设该操作允许用外部传感器检查加液量，允许误差为 `0.005 mL`；这个数字只是示例，不是实际设备精度。

`basis_revision` 记录动作前的目标容器版本，服务端要检查它是否属于原任务，不能把它当成动作后的版本。本例没有读取设备设置值，所以不填 `adopted_settings`。完整响应还要包含对象和系统两部分。

程序没报错、HTTP 返回成功、命令行正常退出、设备回复 ACK、等待时间到了，都不一定表示设备动作已经完成。模型生成的“已完成”也不能作为依据。

缺少所需证据时，按实际情况返回 `running`、`waiting_confirmation` 或 `unknown`。不同证据互相矛盾时，要说明冲突，并暂停依赖该结果的后续动作。

仿真结果必须标记 `simulated: true` 并存入隔离状态，不能更新真实对象。`effects` 表达计划预测；只有已确认事实可以更新物理状态。失败、取消或未知时也必须保存部分实际变化。

## 让程序能够检查这些规则

参数定义必须写清哪些必填、默认值是什么、能否为空、数组长度，以及多个参数之间的关系。

`preconditions`、`effects` 和 `completion_conditions` 应使用固定的规则编号和程序能检查的参数。文字解释可以保留，但安全检查不能只靠一句“条件合适时执行”。`requires`、`provides`、`invalidates` 可以帮助规划程序安排步骤，但必须说明哪些状态还要在执行时实际读取。

契约固有范围与部署限制分别校验。单位换算、坐标系、工具参考点、校准版本和允许误差须在相关操作定义中明确；分辨率或小数位数不能替代准确度与测量不确定度。
