首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >AOI/FCT测试结果以SN为主键写入MES的接口字段与幂等设计

AOI/FCT测试结果以SN为主键写入MES的接口字段与幂等设计

原创
作者头像
智能制造MES笔记
发布于 2026-11-04 10:14:43
发布于 2026-11-04 10:14:43
990
举报

SMT产线完成PCBA后,AOI(自动光学检测)与FCT(功能检测)设备会产出每块板的检测结果。MES需要把这些结果写回工单与批次,形成可追溯的测试档案。本文从接口与数据模型角度,讨论以SN为主键的写入接口应携带哪些字段,以及如何在网络抖动、设备重试、MES双写等场景下做到幂等。


1. 为什么选SN作主键

  • SN(序列号/板号)由SIP/线体赋码系统生成,在同一工厂内全局唯一,且在AOI、FCT、烧录、包装各工位之间传递,天然可作为跨站测试结果的主键。
  • 部分老旧设备会额外生成"设备自增ID"或"测试流水号",但这些ID仅在单台设备内唯一,不能跨站关联,也不利于反向追溯。因此以SN作为MES主键,设备流水号降为辅助字段用于排查。
  • 当产线存在"一SN多版本(多镜像/多固件)"时,SN+测试类型+镜像版本共同构成业务唯一键,主键仍取SN,版本通过唯一约束保障不覆盖。

2. 写入MES的POST接口设计

接口示例:POST /api/v1/mes/test-result/ingest

请求头约定:

字段 Content-Type:application/json

字段 X-Trace-Id:调用方生成的全局追踪ID,供全链路排查

字段 X-Sign:可选,HMAC-SHA256签名,防止中间人篡改测试结果

字段 X-Request-Id:可选,调用方唯一请求编号,与接口层幂等配合使用

请求体字段:

字段 sn:必填,被测板的SN,字符串,作为本条记录的主键(与test_type共同构成唯一键)

字段 test_type:必填,测试类型枚举,值域如 AOI / FCT / BURN-IN / ICT / X-RAY,区分不同工位的检测结果

字段 result:必填,检测结果枚举,值域 PASS / FAIL / NG / RETEST,其中RETEST表示需要返修重测

字段 line_code:必填,线体/工位编号,用于区分同SN在不同线体上的多次测试

字段 equipment_id:必填,设备编号或资产编号,用于问题设备过滤与OEE统计

字段 product_code:必填,物料编码,与BOM/MES工单关联

字段 version:选填,固件/镜像/软件版本号,存在多版本同SN时使用

字段 tester_name:选填,操作员或测试工号

字段 test_time:必填,设备端测试完成的UTC时间,ISO 8601格式,精度到秒

字段 receive_time:选填,MES侧接收时间,通常由服务端填充,与test_time比对可发现时钟偏差

字段 duration_ms:选填,单次测试耗时(毫秒),用于CPK/CT分布统计

字段 error_codes:选填,失败原因码数组,如 "ERR_E101", "ERR_OPEN_4-7",与设备错误码手册对应

字段 error_messages:选填,失败描述文本数组,与error_codes一一对应

字段 golden_value:选填,参考/标准值(字符串或数字),用于FCT电压、电流等定量比对

字段 measured_value:选填,实测值,与golden_value配对计算偏差

字段 units:选填,测量单位,如 V / mA / %

字段 threshold_pass:选填,是否超过阈值(布尔或枚举),与golden/measured配合

字段 image_urls:选填,AOI缺陷图片URL数组,通常上传到对象存储后回传URL

字段 test_program_id:选填,测试程序/固件的版本标识,用于排查程序版本导致的误判

字段 station_id:选填,工位编号,与line_code可重合,视MES建模取舍

字段 operator_id:选填,操作员ID,与tester_name互补

字段 batch_no:选填,批次号,用于批次级统计与质量门控

字段 work_order_no:选填,工单号,写回MES工单使用

字段 retest_count:选填,重测次数,用于统计一次不良的返修成本

字段 extend:选填,JSON对象,设备私有扩展字段,MES侧按协议约定透传或忽略

字段 idempotent_key:选填,幂等键,调用方保证同一条测试结果全局唯一(建议格式 {sn}:{test_type}:{equipment_id}:{test_time} 的哈希)

响应字段:

字段 code:状态码,0 表示成功,非0 表示各类业务或系统错误

字段 message:错误描述

字段 data.record_id:MES侧为这条SN结果生成的记录ID,供后续查询与反查

字段 data.status:当前处理状态,如 ACCEPTED / DUPLICATE / QUEUED

字段 data.trace_id:透传请求头中的追踪ID


3. MES侧数据模型

以SN为核心的一张"测试结果事实表",配合少量维度表即可满足日常追溯与统计。

test_result 事实表字段:

字段 record_id:自增主键,供内部查询与审计

字段 sn:被测板SN,外键/业务主键

字段 test_type:测试类型,与接口层同名

字段 result:PASS / FAIL / NG / RETEST

字段 line_code:线体编号

字段 equipment_id:设备编号

字段 product_code:物料编码

字段 version:固件/镜像版本

字段 test_time:设备端测试时间

字段 receive_time:MES接收时间

字段 duration_ms:测试耗时

字段 error_codes:错误码数组

字段 error_messages:错误描述

字段 golden_value:标准值

字段 measured_value:实测值

字段 test_program_id:测试程序版本

字段 batch_no:批次号

字段 work_order_no:工单号

字段 retest_count:重测次数

字段 idempotent_key:幂等键,用于去重

字段 created_at:记录创建时间

字段 updated_at:记录更新时间

字段 extend:设备扩展字段(JSON)

关联维度与索引:

  • 唯一约束 (sn, test_type, equipment_id, test_time) 防止同设备同时间对同SN的重复写入;若产线存在分批次重测,可将 test_time 放宽为 (sn, test_type, equipment_id, test_time_range)。
  • 索引 (sn) 加速"查某块板的全部测试历史";索引 (test_time, test_type) 加速时段统计;索引 (product_code, line_code, test_time) 加速线体/物料级统计。

4. 幂等设计:从调用方到存储

接口层幂等的核心目标:网络超时导致设备重试、消息队列重复投递、MES双活写入时,同一条SN测试结果不会变成多条记录。

4.1 幂等键的构成

最实用的幂等键是 {sn}:{test_type}:{equipment_id}:{test_time} 的确定性哈希(如 SHA-256 前16位)。这四个字段的组合在正常产线中不会重复:同一台设备在同一秒对同一块板只做一次判定。

当设备时钟不准或存在重测时,可在幂等键中追加 test_program_id 或使用设备端生成的单调递增流水号(要求设备侧去重)。纯靠 idempotent_key 字段也可,但需调用方保证不重复。

4.2 接口层去重(Idempotency-Key)

  • 请求头携带 X-Idempotency-Key(与请求体 idempotent_key 同源),网关/MES接口层在Redis或本地LRU中维持"key → record_id + status"映射。
  • 收到幂等键时,先查缓存:命中且为 ACCEPTED,则直接返回缓存中的 record_id 与 status=DUPLICATE,不写入DB。
  • 缓存TTL建议 7~30 天,覆盖设备重试窗口与工单生命周期;超出TTL的重复请求会落入DB唯一约束兜底。

4.3 存储层兜底:唯一约束

DB层在 (sn, test_type, equipment_id, test_time) 上建唯一索引,INSERT 时配合 INSERT ... ON CONFLICT DO NOTHING(PG)或 IGNORE(MySQL 5.7+)/ ON DUPLICATE KEY UPDATE 的语义。

  • DO NOTHING 用于"不允许覆盖"的场景:MES认为首次写入即最终结论。
  • ON DUPLICATE KEY UPDATE 用于"允许最新结果覆盖"的场景,但需配合 business_rule 校验:例如仅当 result 从 FAIL 变为 PASS 时才更新,或仅当 test_program_id 更新时才刷新,避免掩码不良。

4.4 消息层重投的协调

如果测试结果先入 Kafka / RabbitMQ 再由消费者写MES,消费者应基于幂等键做"先查后插"(Check-then-Insert):

  • 查幂等缓存 → 命中则丢弃。
  • 未命中则尝试写入DB,DB报唯一冲突则视为已成功(可能为本实例或兄弟实例已写入),记录日志并丢弃。
  • 消费者提交 offset 前,确保幂等缓存或DB已落盘,避免消费者崩溃重平衡后重复消费。

4.5 时钟偏差的处理

AOI/FCT设备与MES服务器时钟不一致是常见问题。接口层不应以 receive_time 参与幂等,仅用 test_time。建议:

  • 设备侧通过 NTP / 产线时钟服务器统一时钟。
  • MES在 receive_time 与 test_time 偏差超过阈值(如 60 秒)时打一条警告日志,并可选将此类记录标记为 CLOCK_SUSPECT,由质量工程师人工复核,但不直接拒绝写入。

4.6 并发与双活写入

MES双活或多写入口场景下,幂等缓存建议放在跨实例共享的 Redis Cluster 或使用 DB 唯一约束作为唯一真相源。此时接口层"先查缓存"退化为性能优化,DB 约束才是最终决定者。


5. 查询与反查接口

写入之后,MES通常需要提供三类查询。

5.1 按SN查测试历史

GET /api/v1/mes/test-result/sn/{sn}?test_type=&from=&to=

字段 sn:路径参数,必选

字段 test_type:查询过滤,可选

字段 from / to:时间范围,可选,含头不含尾

响应为结果数组,按 test_time 正序。

5.2 按工单/批次查测试通过率

GET /api/v1/mes/test-result/stats?work_order_no=&batch_no=&test_type=&from=&to=

返回:

字段 total:总测试数

字段 pass_count:PASS 数

字段 fail_count:FAIL/NG 数

字段 pass_rate:通过率

字段 top_error_codes:Top N 错误码及频次

5.3 按设备/线体查OEE与误判

GET /api/v1/mes/test-result/stats/equipment?equipment_id=&line_code=&from=&to=

返回设备维度统计,并可基于 "FAIL 后同一 SN 在复检站 PASS" 的比例,估算误判率。


6. 失败结果的处置与返修流程

当 result = FAIL / NG 时,MES通常需要做两件事:工单/批次拦截与返修流转。

字段 quarantine:可选布尔,MES在写入失败结果后自动将SN放入待确认队列

字段 rma_no:选填,返修/重测生成的RMA单号,回写到本条记录

字段 retest_station:选填,返修工位,如 AOI-RETEST / FCT-RETEST

字段 disposition:选填,处置结论枚举,如 SCRAP / REWORK / USE_AS_IS / RETURN_TO_SUPPLIER

失败结果写入成功后,MES可触发下游动作:

  • 更新工单的"不良数"与"直通率",达到阈值时触发线体停线/质量门控。
  • 将失败SN推送到返修工单系统,返修完成后以新 test_time 再次上报(幂等键不同,允许追加一条记录)。
  • AOI的失败图片自动归档到缺陷库,供SPC与不良模式分析。

7. 上下游对接要点

  • SIP/赋码系统: 在AOI/FCT测试前,MES应能从SIP查询到该SN已赋码、已领料、已绑工单,避免"幽灵SN"写入。对接时建议增加预校验接口 GET /api/v1/mes/sn/{sn}/status,返回 SN 当前所处工序与绑定的工单。
  • 设备侧采集: 不建议MES直连每台AOI/FCT。更稳健的架构是设备 → 采集网关(协议转换,如SECS/GEM、Modbus、设备私有TCP) → 消息队列 → MES消费者。网关层负责断线缓存与重发,MES只看到标准化JSON。
  • 对象存储: AOI缺陷图、FCT波形图建议由采集网关上传对象存储后返回URL,接口层只传 image_urls / waveform_url,避免大附件拖慢MES写入。

8. 安全与权限

字段 api_key / tenant_id:多租户SaaS化部署时,请求应携带租户标识与签名,MES按租户隔离存储与查询。

权限模型建议:

  • 设备/网关:只拥有 POST 写入权限与自身 equipment_id 的查询权限。
  • 质量工程师:拥有SN、工单、批次的读权限与 disposition 的写权限。
  • 系统管理员:拥有设备级统计与配置权限。

接口层应做速率限制(如每设备 100 条/秒)与 payload 大小限制,防止异常设备刷屏。


9. SLA 与容量估算

一条FCT结果通常在几十到几百字节,AOI带图片URL也会在一KB以内。按 60 秒节拍的线体,每小时数千条,日级十万~数十万条是常见量级。

  • 写入P99应控制在 200ms 以内(含幂等缓存查询与DB写入),设备侧超时通常设 3~5 秒。
  • 查询接口P99 500ms 以内,复杂聚合(多线体+多工单)可下沉到列式表/OLAP库,接口层只读快照。
  • 幂等缓存建议按日/线体分片,避免单key热点;DB表按 test_time 分区可显著提升历史查询性能。

10. 常见陷阱与FAQ

Q:SN 在厂内真的唯一吗?

取决于赋码规则。推荐 SN 包含"工厂代码 + 年月 + 流水",并由赋码系统集中分配。如果存在多工厂共用SN规则,需在幂等键与唯一约束中加入 factory_code。

Q:AOI 一台设备对同一 SN 测了两次,怎么写?

两次测试的 test_time 不同,幂等键自然不同,允许写入两条。可通过 retest_count 与 line_code 体现"首次不良+复检"的关系。

Q:设备时钟跳变怎么办?

接口层用 test_time 参与幂等,不依赖 receive_time。MES在偏差超阈值时打警告并标记 CLOCK_SUSPECT,由人工复核;严重跳变的设备应列入维护工单。

Q:允许"最新结果覆盖"吗?

一般不建议无差别覆盖。推荐仅当 test_program_id 升级或明确的重测/返修场景下才覆盖,其他情况追加新记录。这样能保留误判排查的完整证据链。

Q:FCT 的 measured_value 精度怎么处理?

接口层统一用字符串传输,保留设备原始精度与单位;MES内部可按需转 Decimal,避免浮点精度损失。units 字段用于解释 measured_value 的量纲。

Q:扩展字段 extend 谁来管?

按"约定优于配置":MES与设备供应商签一份扩展字段清单,MES对清单内字段做索引与查询,清单外字段只透传存储。定期评审清单,避免无限膨胀。


11. 小结

以SN为主键写入MES的测试结果接口,核心设计点有三条:一是字段集要覆盖"测了什么、在哪测的、结果如何、怎么重测"四个维度;二是幂等键要基于设备可确定的字段组合(sn + test_type + equipment_id + test_time),并在缓存与DB两层兜底;三是反查接口要按 SN/工单/设备三种维度提供查询与统计,支撑质量追溯与产线运维。掌握这些接口与数据模型层面的约定,AOI/FCT结果就能稳定、可复现地流入MES,而不是在重试与重复中膨胀成垃圾数据。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 1. 为什么选SN作主键
  • 2. 写入MES的POST接口设计
  • 3. MES侧数据模型
  • 4. 幂等设计:从调用方到存储
  • 5. 查询与反查接口
  • 6. 失败结果的处置与返修流程
  • 7. 上下游对接要点
  • 8. 安全与权限
  • 9. SLA 与容量估算
  • 10. 常见陷阱与FAQ
  • 11. 小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档