Stunner API 19 个命令:分类、流程、细节
30 秒看懂
19 个命令只有 Measure 是异步,其余 18 个等动作做完才返回 托盘等同步命令的 timeout 至少留 10 秒,别按毫秒配 返回 −200 至 −202 时调 GetLastInternalError
系列指南 · 第 4 篇
Stunner API 19 个命令:分类、流程、细节
Stunner Client 一侧配置完成之后,仪器就准备好被外部脚本调用了。这里说的"脚本",是工作站或调度系统上的一段小程序(常用 C#、Python 或 LabVIEW 写)。它通过加载 Stunner.dll 这个文件,把 19 个 API 命令一条一条发给 Stunner。整套 API 按职责分成四组。写脚本时,先掌握一次完整测量的常规顺序,再留意几处容易写错的细节。
先认识几个名词
同步 / 异步 — 同步命令要等仪器把动作做完才返回;异步命令启动动作后立即返回,脚本再自己查进度。19 个命令里只有 Measure 一个是异步。
独占访问权 — 同一时刻只能有一个脚本控制 Stunner。脚本先用 Request_Access 取得访问权,用完再用 Release_Access 释放,别的脚本才能接手。
轮询(polling) — 脚本周期性地问仪器"测完了吗?",直到拿到肯定答复才往下走。Measure 异步启动测量后,就靠轮询 Get_Status 判断何时完成。
状态码(return code) — 每个命令调用之后,返回一个整数告诉脚本结果。Stunner 的约定:0 是成功,正数是状态/补充信息(不是错),负数是错误,不同负数对应不同原因,见 Manual Appendix 2。
Stunner.dll — Stunner API 的 Windows 动态链接库(DLL 是一种文件,里面装着可以被外部程序调用的函数)。客户脚本加载这个 DLL,就能调用 19 个 API 命令。
try / finally — 一种编程结构。把可能出错的代码放 try 里,把"无论成败都要做"的清理动作放 finally 里。Stunner 脚本里典型用法是把 Release_Access 放在 finally,确保哪怕中途出错也能释放访问权。
timeout(超时) — 脚本等命令返回的最长时间。超过这个时间还没返回就放弃等、报错,避免脚本永远挂在那。Stunner 的开/关托盘要等几秒机械动作,超时配毫秒级会误报。
plate_ID — 每块 Stunner Plate 的标识字符串。Define_Experiment 时一次传入完整的样品定义,返回一份 plate_ID 数组(多板时就有多个);后面 Measure(plate_id) 按这个 ID 挨块测。
19 个命令分四类
写脚本时,会话控制的命令只在开头和结尾调用,Get_Status 贯穿全程,按板循环的是测量动作这组。
会话控制 — 3 条 — Stunner() · Request_Access · Release_Access — 每个脚本开头都要走前两条建立连接、申请访问权;结尾走第三条释放访问权。
仪器信息 — 3 条 — Get_Instrument_Serial_Number · Get_Software_Version · Get_Status — 前两条用来开机自检,确认连的是预期那台仪器;Get_Status 全程都在用,是脚本和仪器之间唯一的状态同步手段。
测量动作 — 7 条 — Open_Tray · Close_Tray · Read_Bar_Code · Define_Experiment · Measure · Abort_Measurement · Get_Results — 这一组是核心,一次测量的主干流程基本就是按这几条命令的顺序往下走。
辅助命令 — 6 条 — Pause · Do_Continue · Reset · Store_Blanks · Get_Stored_Blanks · GetLastInternalError — 日常测量用不到,只在调试、应急和复用空白时调用。
同步与异步:两种返回行为
19 个命令里,18 个是同步的,只有 Measure 一个是异步的。两者返回的时机不同,分清这一点是写 Stunner 脚本的第一件事。
18 条
同步命令
命令发出去后,函数会一直等,直到仪器真的把动作做完才返回。比如 Open_Tray() 返回的那一刻,托盘已经物理上打开了。脚本下一行可以放心继续往后走。
· 返回即代表动作完成,可按顺序写
· 托盘动作等几秒,字符串解析瞬间返回
· timeout 至少留 10 秒,别按毫秒级配
仅 1 条
异步命令:Measure
函数返回只表示"测量已经成功启动"。实际测量在仪器那边继续跑,可能持续几分钟到两小时多。只测浓度一板约 12 分钟,加 DLS 一板约 1 小时,加 RADLS 一板约 2 小时多。
· 函数返回 ≠ 测量完成
· 后面必须接 Get_Status 反复问,直到仪器说"测完了"
· 不轮询直接去取结果,这时数据还没出来,会拿到空
为什么 Measure 要做成异步:测一板 RADLS 要两个多小时。如果 Measure 跟其他命令一样同步等待,脚本会被这一条命令卡住,中间什么都做不了。改成异步之后,脚本可以在仪器测量期间做别的事。比如让机械臂搬下一块板、清洗液体工作站、把上一板的结果传给 LIMS。轮询频率一般定在 1–2 秒一次:更快只是多占网络;更慢则机械臂要在仪器旁边空等,整批样品的处理时间会被拉长。
一次完整测量的命令顺序
把命令拼起来,一块板从开始到结束的最小可用脚本是下面这 13 步。左边是脚本侧发出的 API 命令,右边是同一时刻仪器或工作站在做的物理动作。
步 / 脚本侧(API 命令) / 仪器 / 工作台
这是单板的最小可用顺序。多板实验里,第 8 步测量完成后,用第 9–11 步开托盘、换板、关托盘,再回到第 7 步 Measure 下一块。Define_Experiment 只在第 3 步发一次。一次定义里可以包含多块板,返回的 plate_IDs 数组按顺序列出每块板的 ID,后续 Measure 挨个传入即可。Get_Results 留到所有板都测完再调一次,一次取走所有结果。
命令一览
19 个命令按分组列在下面,便于写脚本时对照。每个命令完整的入参定义、返回字段说明,在 Stunner API Manual §4.2 里都有;这里只列签名和一句话职责。
### 如何看签名
- string = 字符串、int = 整数、bool = 真/假、string[] = 一组字符串(数组)
- out 标记的参数是"输出参数"。命令执行完之后,Stunner 把这个值塞回脚本里。它是返回的状态码之外的额外数据
- 例:Read_Bar_Code(out string bar_code) 意思是"调用这条命令,Stunner 会把条码字符串塞进 bar_code 变量"
命令:职责
会话控制(3 条)
Stunner(string address, int port):建立 TCP 连接对象。地址用仪器 IP,端口固定 6300。
Request_Access():申请独占访问权。别的脚本已占用或 License 没激活时会被拒。
Release_Access():释放访问权,让出仪器。脚本结束或出错前都应该走一次。
仪器信息(3 条)
Get_Instrument_Serial_Number():读仪器序列号。开机自检时用,确认连的是预期那台。
Get_Software_Version():读仪器软件版本,确认和 PC 上的应用版本对得上。
Get_Status(out string measurement_info) 或 Get_Status():查当前状态,任何时候都可以发。测量进行中,有 measurement_info 输出参数的重载会带回额外信息。
测量动作(7 条)
Open_Tray():打开托盘。返回时托盘已物理打开。
Close_Tray():关闭托盘。返回时托盘已物理关闭。
Read_Bar_Code(out string bar_code) 或 Read_Bar_Code(out string bar_code, out bool valid, out string plate_type):读已经放进托盘的 Stunner Plate 上的条码。重载版本可同时返回是否有效和板型。
Define_Experiment(string experimentDefinition, string sampleDefinition, out string[] plate_IDs):把实验定义、样品定义两段字符串发给仪器;返回一份 plate_ID 数组,后面 Measure 要用。
Measure(string Plate_ID):异步:命令立刻返回,实际测量要靠 Get_Status 轮询确认。Plate_ID 传 "autodetect" 可让仪器先扫条码,再决定测哪块板。
Abort_Measurement():强行中断正在进行的测量。一般只在出错或上层调度取消时用。
Get_Results(string results_parameters, string plate_ID, out string results, out string experiment_path, out string AniML_types):取结果文本字符串,同时把 .bin 原始数据写到共享目录。要等所有板测完才能调用,提前调用会返回错误;plate_ID 留空返回所有板,填某块板的 ID 只返回该板。
辅助命令(6 条)
Pause():暂停当前所有动作,直到收到 Do_Continue。
Do_Continue():从暂停状态恢复测量。
Reset():把仪器从 error 状态拉回正常。一般作为出错处理的最后一招。
Store_Blanks() 或 Store_Blanks(string file_name):把刚跑完的或共享目录里某一板的空白存到仪器本地。整文件覆盖,旧空白会被删掉。
Get_Stored_Blanks():列出当前仪器上存了哪些空白:Plate type、sample group 名、剩余有效天数。
GetLastInternalError():取 DLL 内部最近一次错误的详细文字描述。仅在前一次返回 −200/−201/−202 这三个 DLL 内部错误码后才有内容。
几处容易写错的细节
写 Stunner 脚本时,下面 6 处最容易出错。
出错了怎么定位
API 报错的时候,Stunner 不会自己跳出错误提示,因为仪器没法在脚本 PC 上显示任何东西。所有出错信息都打包成一个整数(就是前面说的状态码),随命令的返回值传回脚本。脚本拿到这个数字之后,自己判断怎么处理。定位故障主要靠下面两种手段。
1
查每条命令的整数状态码
每个命令调用之后都返回一个状态码。约定如下:
0 = 成功,继续执行
正数 = 补充信息,不是错误。例如 50 表示"已连接、托盘开着"、3 表示"托盘本来就开着"
负数 = 错误。例如 -1 无访问权、-2 仪器状态不对、-9 实验定义解析失败、-200 TCP 连不上
完整状态码表在 Stunner API Manual Appendix 2。
2
−200 / −201 / −202 时,加一次 GetLastInternalError
当状态码是 −200、−201 或 −202 时,说明问题出在 Stunner.dll 那一层(通常是连接、超时或参数解析的问题)。这时可以立刻调一次 GetLastInternalError(),拿到一段更详细的文字描述。其它状态码下这个函数不会返回内容,所以只在这三个码后面加就行,不必每条命令都调。
### 推荐的统一封装
生产脚本里,建议统一封装一层"返回码 → 动作"的映射函数,把动作收敛成几种:
- · 返回 0 继续
- · 正数继续
- · 特定负数重试
- · 其它负数报警停产线
- · 严重错误走一次 Reset
这样返回码集中映射,日志也集中记录,比每条命令各自写 try/catch 更容易找到根因。
big-picture · 19 个命令分四类
sync-vs-async · 同步与异步:两种返回行为
standard-flow · 一次完整测量的命令顺序
reference-table · 命令一览
同步 / 异步 · 同步命令要等仪器把动作做完才返回;异步命令启动动作后立即返回,脚本再自己查进度。19 个命令里只有 Measure 一个是异步。
独占访问权 · 同一时刻只能有一个脚本控制 Stunner。脚本先用 Request_Access 取得访问权,用完再用 Release_Access 释放,别的脚本才能接手。
轮询(polling) · 脚本周期性地问仪器"测完了吗?",直到拿到肯定答复才往下走。Measure 异步启动测量后,就靠轮询 Get_Status 判断何时完成。
状态码(return code) · 每个命令调用之后,返回一个整数告诉脚本结果。Stunner 的约定:0 是成功,正数是状态/补充信息(不是错),负数是错误,不同负数对应不同原因,见 Manual Appendix 2。
Stunner.dll · Stunner API 的 Windows 动态链接库(DLL 是一种文件,里面装着可以被外部程序调用的函数)。客户脚本加载这个 DLL,就能调用 19 个 API 命令。
try / finally · 一种编程结构。把可能出错的代码放 try 里,把"无论成败都要做"的清理动作放 finally 里。Stunner 脚本里典型用法是把 Release_Access 放在 finally,确保哪怕中途出错也能释放访问权。
timeout(超时) · 脚本等命令返回的最长时间。超过这个时间还没返回就放弃等、报错,避免脚本永远挂在那。Stunner 的开/关托盘要等几秒机械动作,超时配毫秒级会误报。
plate_ID · 每块 Stunner Plate 的标识字符串。Define_Experiment 时一次传入完整的样品定义,返回一份 plate_ID 数组(多板时就有多个);后面 Measure(plate_id) 按这个 ID 挨块测。
会话控制 · 3 条 · Stunner() · Request_Access · Release_Access · 每个脚本开头都要走前两条建立连接、申请访问权;结尾走第三条释放访问权。
仪器信息 · 3 条 · Get_Instrument_Serial_Number · Get_Software_Version · Get_Status · 前两条用来开机自检,确认连的是预期那台仪器;Get_Status 全程都在用,是脚本和仪器之间唯一的状态同步手段。
测量动作 · 7 条 · Open_Tray · Close_Tray · Read_Bar_Code · Define_Experiment · Measure · Abort_Measurement · Get_Results · 这一组是核心,一次测量的主干流程基本就是按这几条命令的顺序往下走。
辅助命令 · 6 条 · Pause · Do_Continue · Reset · Store_Blanks · Get_Stored_Blanks · GetLastInternalError · 日常测量用不到,只在调试、应急和复用空白时调用。
3 · 把实验定义、样品定义两段字符串发过去
5 · — · 机械臂或人把 Stunner Plate 放进托盘
8 · 每 1–2 秒查一次状态,直到测量完成
10 · — · 机械臂取出测完的板;多板实验在这里换上新板
12 · 拿回文本结果;同时 .bin 原始数据写到共享目录
13 · 释放访问权,让出仪器给下一个脚本
机械臂或人把 Stunner Plate 放进托盘
机械臂取出测完的板;多板实验在这里换上新板
拿回文本结果;同时 .bin 原始数据写到共享目录
会话 · 访问权是独占的 · 同一时刻只有一个脚本能控制 Stunner。多个脚本共用一台仪器时,排队由上层调度负责,API 这一层不会自动处理。
会话 · 访问权要主动释放 · 脚本崩溃前如果没走 Release_Access,下一个脚本启动时会被拒。建议把释放语句放在 try/finally 的 finally 块里,出错时也能执行到。
异步 · Measure 不能直接等结果 · 它返回"成功"只代表测量已经启动,真正的结果要靠 Get_Status 反复问,直到拿到状态码 25(测量成功)。如果不轮询就直接去取结果,这时仪器还没测完,会拿到空数据。
条码 · autodetect 依赖板上有可读条码 · Stunner Plate 出厂自带 CODE128 条码,但样品板若被贴纸遮住、条码污损或反向放置,自动识别会失败。这种情况下改用 Define_Experiment 返回的明确 plate_ID 会更稳。
机械 · 同步命令也会等托盘动完 · Open_Tray、Close_Tray 这两条返回之前,函数会阻塞几秒,这是托盘机械动作的时间。脚本里这两条的 timeout 至少留 10 秒,不要设置成毫秒级。
结果 · Get_Results 一次取走更划算 · 多板实验里,所有板测完前调用 Get_Results 会返回错误;测完后 plate_ID 留空,一次返回所有板的结果。通常这一次就够了,不需要每块板分别查一次。频繁调用 Get_Results 反而可能拖慢仪器对其他命令的响应。