SMT产线完成PCBA后,AOI(自动光学检测)与FCT(功能检测)设备会产出每块板的检测结果。MES需要把这些结果写回工单与批次,形成可追溯的测试档案。本文从接口与数据模型角度,讨论以SN为主键的写入接口应携带哪些字段,以及如何在网络抖动、设备重试、MES双写等场景下做到幂等。
接口示例: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
以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)
关联维度与索引:
接口层幂等的核心目标:网络超时导致设备重试、消息队列重复投递、MES双活写入时,同一条SN测试结果不会变成多条记录。
4.1 幂等键的构成
最实用的幂等键是 {sn}:{test_type}:{equipment_id}:{test_time} 的确定性哈希(如 SHA-256 前16位)。这四个字段的组合在正常产线中不会重复:同一台设备在同一秒对同一块板只做一次判定。
当设备时钟不准或存在重测时,可在幂等键中追加 test_program_id 或使用设备端生成的单调递增流水号(要求设备侧去重)。纯靠 idempotent_key 字段也可,但需调用方保证不重复。
4.2 接口层去重(Idempotency-Key)
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 的语义。
4.4 消息层重投的协调
如果测试结果先入 Kafka / RabbitMQ 再由消费者写MES,消费者应基于幂等键做"先查后插"(Check-then-Insert):
4.5 时钟偏差的处理
AOI/FCT设备与MES服务器时钟不一致是常见问题。接口层不应以 receive_time 参与幂等,仅用 test_time。建议:
4.6 并发与双活写入
MES双活或多写入口场景下,幂等缓存建议放在跨实例共享的 Redis Cluster 或使用 DB 唯一约束作为唯一真相源。此时接口层"先查缓存"退化为性能优化,DB 约束才是最终决定者。
写入之后,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" 的比例,估算误判率。
当 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可触发下游动作:
GET /api/v1/mes/sn/{sn}/status,返回 SN 当前所处工序与绑定的工单。字段 api_key / tenant_id:多租户SaaS化部署时,请求应携带租户标识与签名,MES按租户隔离存储与查询。
权限模型建议:
接口层应做速率限制(如每设备 100 条/秒)与 payload 大小限制,防止异常设备刷屏。
一条FCT结果通常在几十到几百字节,AOI带图片URL也会在一KB以内。按 60 秒节拍的线体,每小时数千条,日级十万~数十万条是常见量级。
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对清单内字段做索引与查询,清单外字段只透传存储。定期评审清单,避免无限膨胀。
以SN为主键写入MES的测试结果接口,核心设计点有三条:一是字段集要覆盖"测了什么、在哪测的、结果如何、怎么重测"四个维度;二是幂等键要基于设备可确定的字段组合(sn + test_type + equipment_id + test_time),并在缓存与DB两层兜底;三是反查接口要按 SN/工单/设备三种维度提供查询与统计,支撑质量追溯与产线运维。掌握这些接口与数据模型层面的约定,AOI/FCT结果就能稳定、可复现地流入MES,而不是在重试与重复中膨胀成垃圾数据。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。