读写器装好了,标签读取率 98%,可上线三个月后,财务仍在追问那些没人能解释的库存调整。除物理问题之外,几乎所有的 RFID 失败都是集成问题:事件顺序错乱、同一托盘被数了两次,或者中间件直接往 ERP 里写了一个永远无法审计的数量。
本文讨论读写器与业务系统之间的那一层——怎样设计它,才能让 Odoo、SAP 或用友里的数字在月末经得起追问。
集成层该负责什么,什么必须留在 ERP 里?
把职责边界写清楚,并且写进合同的实施范围。边界模糊的结果,就是两个系统都以为对方才是权威。
- 边缘层负责:读写器连接、天线配置、读取过滤、重复抑制、标签到 SKU 的解析、事件时间戳与事件 ID。
- 中间件负责:顺序保证、重试、死信处理、上下文补全(月台门、操作员、工单),以及映射成业务单据。
- ERP 负责:计价、分配、可用量计算、财务过账与审计轨迹。
最能救项目的一条规则是:中间件永远不要直接写 stock.quant。它应当提交一张单据——收货、调拨或盘点调整——让 ERP 自己的业务逻辑决定库存变成什么。直接写库会绕过审计轨迹、绕过计价层,并且在升级那天立刻失效。
按数据量选集成方式:文件、API 还是事件流?
依据实测数字选,而不是依据厂商偏好选。三种方式完全可以共存。
- 每班 5,000 条事件以内:按小时或按天的文件交换就够,而且最容易核对。每站点一个文件,命名确定,清单文件里带校验和。
- 每小时 5,000 至 50,000 条:同步 REST 调用,每批 100–500 条,每条都带幂等键。
- 更高,或者时延决定业务结果(月台门必须在数秒内确认):上事件流——读写器到边缘用 MQTT,边缘到 ERP 用 Kafka 或 RabbitMQ。
时延目标比吞吐量更重要。晚到 20 分钟的收货确认是业务问题,不是 IT 问题。要在月台门测 p95,而不是在实验室测平均值。
Odoo:如何接收 RFID 事件而不破坏 stock.quant
Odoo 几乎允许你写任何东西,正因如此集成需要纪律。
- 每条流程配一个专用作业类型:RFID 收货、RFID 内部调拨、RFID 盘点。报表与权限都跟着作业类型走。
- 盘点用库存调整向导:先在该 quant 行写入 inventory_quantity,再调用 action_apply_inventory。不要直接写 quantity 字段;调整向导才会生成可审计的移动。
- 每个事件分配稳定的外部 ID,放在带唯一索引的自定义字段上,这样重试不会生成第二条移动明细。
- 每个事务批处理 200–500 行移动明细。批次太大会长时间锁住产品行,阻塞其他用户,而且没有任何收益。
- RFID 专用字段(rfid_epc、rfid_event_id、rfid_reader)放在独立模型或非存储计算字段上。stock.quant 被读取的频率极高,把它撑大等于全局拖慢。
SAP:IDoc、OData 与中间件的取舍
SAP 要的是物料凭证,不是标签读取。三条现实路径各有适用场景。
- IDoc(WMMBID02、MBGMCR、DESADV):成熟、面向批量,已有 PI/PO 时对现有架构冲击最小。
- S/4HANA 上的 OData 与 REST API:适合准实时过账,版本管理也比自定义 IDoc 扩展简单得多。
- 专用 MII 或 EWM 层:只有日均数百万条标签事件,或仓储主数据本来就在 EWM 时,才值得投入。
最常见的错误是按方便程度而不是按会计含义选移动类型。261 与 262 用于消耗,101 与 102 用于收货,311 与 312 用于转移——每一种都会影响成本核算与期间结账。在写第一行集成代码之前,让成本会计签掉映射表。
用友、金蝶与国产 ERP:优先走 OpenAPI
国产 ERP——用友 U8+、用友 BIP 与 NC Cloud、金蝶 K/3 与 Cloud——都提供 REST OpenAPI 和消息总线。优先用它们,并且异步用。
- 每日拉取库存快照,与你自己的盘点对账;事务以已完成的业务单据形式推送。
- 直接写 U8 数据库在国内市场很常见,也是代价最高的一条捷径。它绕过审计轨迹、在补丁升级时失效,还会把月末对账变成一场政治谈判。
- 在承诺实时能力之前,先确认 API 限流以及仓库、批次、序列号的字段映射。很多国产部署实际是准实时;承诺实时,就是项目第二周失去信任的方式。
生产环境里会坏在哪,怎么设计
六类故障模式覆盖了大多数生产事故,每一类都有对应的设计答案。
- 读写器时钟漂移:同时记录 occurred_at(读写器侧)与 received_at(服务器侧),排序时不要只依赖前者。
- EPC 重复:两个标签被写成同一个 ID,会产生互相矛盾的移动。在边缘检测并拒绝,别让它进 ERP。
- 读写器离线积压:断线两小时后重连的读写器,不能把 4 万条陈旧读取当成当前事件重放。限制积压窗口,并把迟到事件显式标记。
- 乱序到达:物品不可能在到达之前离开。要么拒绝,要么隔离,绝不静默接受。
- 时区:存 UTC,显示本地时间,上线前测一次夏令时切换边界。
- 静默的部分失败:一批 500 条中有 3 条失败,必须报告成功 497、待处理 3,而不是抛一条笼统错误。
签集成 SOW 前的检查清单
- 事件 ID 由谁生成,是否在跨站点、跨年度范围内全局唯一?
- 哪个系统有权判定一次读取成为一次移动?
- 每一次写入是否幂等,是否用故意重复的消息测过?
- p95 时延是多少,且在月台门实测?
- 异常如何浮出,谁在多长时间内关闭?
- 能不能重放一整天的事件而不把库存翻倍?
- 移动类型与作业类型的映射,财务或成本会计签字了吗?
如果任何一个答案是某个人名而不是某份文档,说明集成还没有被定义——而这份模糊的代价,最终会以库存调整的形式支付。






