1. 什么时候需要自己写一个采集中间件
1.1 被集成方案逼到墙角的典型场景
先说个我实际经历过的场面。客户工厂里有一条完整的机加工产线,设备层面有西门子S7-1500的PLC控制两台加工中心,有发那科和广数的CNC,还有几套带RS485输出的小型仪表,喷码机、称重模块也混在里面。上层定了要上MES系统,但MES厂商只负责接收数据,不负责到底怎么把设备那边五花八门的协议统一成标准格式发给MES。
采购那边先去找了一下市面上现成的工业网关,报价单拉出来一看,一台像样点的边缘网关两三万起步,而且只支持某几个品牌的PLC协议。客户现场还有几台“老古董”设备,供应商早就倒闭了,连协议手册都是当年工程部自己翻出来的手抄本,网关厂商根本不可能为这几个点去定制驱动。
这种时候就明白一个道理:数据采集从来都不是“买盒子”的问题,而是“把现场设备当成一群说不同方言的人,找一个人能同时听懂他们的话再统一转述”的问题。市面上的通用网关适合协议种类少、点位规整、环境标准化的工厂。一旦现场出现杂牌仪表、非标CNC、老旧PLC,就只能自己写采集中间件。
1.2 “采集精灵”要解决的不是采集本身,而是接口混乱
我在接手这个项目时先做了一个统计:现场需要采集的设备一共37台,通讯协议却多达6种。其中包括西门子S7协议、Modbus TCP、Modbus RTU、OPC UA、发那科FOCAS、以及一个需要解析字节流的串口自定义协议。
如果每台设备都写一个独立的小程序去采集,然后再单独对接MES,那维护成本会让人崩溃。任何一台设备点位变更、任何一组IP地址调整,都得翻山越岭去找对应的那个采集程序。
所以“采集精灵”这个名字听着像个轻量级工具,实际上它的核心设计目标很明确:做成一个以点位为中心的协议接入平台。设备驱动以插件形式挂载,点位配置走统一的模板,上行输出用统一的数据模型,这样无论下面接的是什么协议、多少种设备,MES平台看到的始终是一个标准的JSON或MQTT报文。
大概的架构关系是这样的:最下层是驱动层,各自负责各自的协议;中间是调度内核,负责点位解析、轮询调度、数据缓存;上层是接口层,对外提供MQTT、HTTP推送或Modbus Server三种方式把数据交出去。这个分层也是在现场被反复教训之后才定型的。
最初我图省事,让每台设备驱动自己直接往MQTT里塞数据。结果现场网络一抖动,MQTT连接断开之后驱动内的消息队列越积越多,内存直接飙上去,把采集工控机整死机了。后来改成“驱动只负责拿到原始值,调度内核统一处理后进持久化缓存,再由独立的上行线程推送”,才彻底解决了这个问题。
1.3 这套系统适合谁、不适合谁
从定位上说,采集精灵这类自研采集中间件并不是要替代商业SCADA和工业网关,它更合适的是这几种情况:
- 工厂里设备品牌杂、协议类型多,通用网关覆盖不全;
- 项目预算有限,买一堆网关的成本超过了自己开发维护的成本;
- 对数据有定制化需求,比如需要在采集端做连续性判断、在边缘做数据清洗;
- 后期点位变化频繁,希望在旁边放一个自己完全可控的工具,随时调整。
反过来,如果现场只有单一品牌的PLC,数量也不多,老老实实用商用网关加官方驱动会轻松得多。自己搞采集中间件的成本其实很大一部分不在代码,而在后面长期的协议适配和现场支持。所以“适合谁”这个问题,接项目之前一定先想清楚。
2. 从设备到平台的数据链路设计
2.1 我采用的五层采集模型
做工业数据采集,最忌讳一上来就奔着写代码去。先把数据从物理世界到最终报表之间要经过的完整链路梳理清楚,后面才能少返工。我在采集精灵里把数据链路拆成了五层:
- 物理链路层:处理网线、串口线、交换机、USB转串口这类基础通信链路,包括串口参数波特率、数据位、校验位的物理连接;
- 协议解析层:对Modbus、S7、OPC UA、FOCAS等协议进行报文封装和解析,拿到原始值;
- 点位映射层:把协议地址和点位编码对应起来,解决“PLC地址DB1.DBD4”和MES里“CNC_Temp_01”这种名字之间的映射关系;
- 边缘处理层:对数据做量程换算、越限判断、变化检测、断线重连处理,产生标准格式数据;
- 上行交互层:把处理好的数据推给MES/SCADA/云平台,同时具备本地存储和历史补传能力。
这五层不是拍脑袋定的,而是被现场一个实际问题逼出来的。早期版本我把协议解析完的数据直接推送,结果MES反馈说一些温度值和现场仪表显示值对不上。查了半天,发现PLC里存储的是原始整形值,仪表显示的是经过量程换算后的工程值,中间差了一个线性变换公式。后来我强制在点位配置里加了“缩放系数”“偏移量”两个字段,所有协议解析出来的值统一换算成工程值之后才允许进入上行队列。
2.2 统一数据模型长什么样
跨协议采集最大的问题就是数据格式不统一。西门子PLC里同一个DB块里可能有Bool、Int、Real、String,Modbus则要区分线圈、离散输入、保持寄存器、输入寄存器,OPC UA节点又有一套自己的数据类型体系。如果这些差异不统一处理,协议层每多一种,MES对接那边就要跟着改一次代码。
采集精灵在中间定义了一套标准点位结构,长这样:
{ "device_id": "device_001", "point_id": "point_temp_oil", "point_name": "主轴油温", "value": 45.6, "quality": 0, "timestamp": 1719907200123, "unit": "degC" }quality字段我专门留了出来,0表示正常、1表示超时、2表示通讯失败。一开始觉得这个字段是多余的,反正超时就直接不推送行了。后来真正跑起来才发现,MES在做设备状态宕机分析时需要区分“这个设备是坏了一直没报数”还是“这个点位采集超时了”,没有质量戳,光靠时间去猜很容易误判。
点位映射层的核心工作是做“协议地址+数据类型”到标准点位结构的转换。现场工程师不需要关心Modbus的寄存器和S7的DB地址在字节序上有什么区别,只需要在配置界面里填好协议类型、起始地址、数据类型、缩放系数,剩下的交给驱动去处理。
2.3 为什么MES那边只愿意收MQTT
上行的数据接口我试过好几个方案,最后全部统一到了一个:MQTT。
刚开始做的时候,MES厂商说你们直接往数据库表里写就行,我们公司有一套通用的数据表接口。我听着觉得省事,结果对接的时候发现他们的数据表在SQL Server里,采集工控机要装一个SQL Server客户端的ODBC驱动,配置好账号权限,而且现场他们的数据库经常在晚上做备份,写入就会卡顿甚至失败。
后来又试过用HTTP接口直接POST JSON,简单是简单,但HTTP在弱网环境下体验很差,一个请求超时就得重发,进程阻塞住了还会连累采集线程。
MQTT的优势在于它天生就是为这种“采集端主动上报、订阅端被动接收”的场景设计的。设备侧采集完数据,发布到一个主题上;MES作为订阅者去接收。网络断了连接自动重连,QoS级别还能保证消息不丢。我在采集精灵里把MQTT的参数统一做成可配置的:Broker地址、端口、ClientID、Topic前缀、QoS、用户名密码,这样部署到不同工厂,只需要改一个配置文件。
唯一的教训是ClientID千万别用网卡MAC地址或者设备名做拼接,因为现场多个采集节点分组部署时,如果两台工控机凑巧在同名Topic下用了相同的ClientID,MQTT Broker会把其中一个踢下线。我在两个工厂都踩过这个坑,后面统一改成“UUID的前八位_部署位置”这种格式才稳定下来。
3. 协议接入的实施细节与驱动开发心得
3.1 Modbus TCP和RTU:看似简单却最容易栽跟头
Modbus是工业现场最常见的协议,但“常见”不代表“简单”。它在数据模型上区分四张表:线圈(Coil)、离散输入(Discrete Input)、保持寄存器(Holding Register)、输入寄存器(Input Register)。很多第一次接触Modbus的人会把这四类混淆,导致点位地址填错。
现场最常见的采集对象是保持寄存器,因为它既可读也可写。每个寄存器是16位,两个寄存器可以拼成一个32位浮点数或32位整数。这里就有一个经典坑:字节序和字序问题。
不同品牌的设备在存放32位数据时,可能会有不同的“大小端”和“字交换”组合。同样是读地址0的两个寄存器,有的设备先发高16位,有的先发低16位,还有的在中间交换。采集精灵在Modbus驱动里面做了一个非常实用的配置:word_order字段,可选big_endian(正常顺序)、little_endian(字颠倒)、word_swap(字节交换)等几种。每个点位都能独立设置,才把市面上那些杂牌仪表给逐一搞定。
另外要强调一个细节:Modbus TCP的报文里有一个Unit ID字段,通常默认为1,但有些设备厂商会拿它做从站地址的扩展。和带串口服务器的多个Modbus RTU从站通信时,这个字段就是那个从站的地址。如果配置工具只填IP而不填Unit ID,会发现网关能连上但永远读不到数。
3.2 西门子S7协议:比Modbus复杂但接口稳定
西门子PLC的采集,目前主流方案是Snap7。Snap7的好处是它直接基于S7协议,不需要在PLC里额外加程序块,远程读取DB块、I区、Q区、M区都很方便。
在这块我积累的几个经验分享出来:
DB编号和字节地址分开填。S7协议里一个地址类似
DB1.DBX0.0或DB1.DBD4,配置界面上要把DB编号、字节偏移、数据类型拆开处理,不要只给一个字符串让工程师自己拼。采集点多了之后,字符串格式解析很容易出错,而且不好批量操作。读取长度限制。S7协议单次PDU读取长度是有限制的,不是你想读一个DB块里的连续200个字节就能一次读完。Snap7底层会自动切片,但我在调优过程中发现,极限一次读240字节左右通常没问题,超过之后会触发分段读取,反而增加通信开销。最好的办法是点位配置时按“80字节一段”把连续的DB地址分成多次读取。
注意S7-200 Smart和S7-1200/1500的差异。S7-200 Smart走的是PPI协议,和S7-1200/1500的S7通讯虽然都叫“S7”,但不是一个东西。用Snap7默认连S7-200 Smart会一直报“无法协商”,需要在驱动里做特殊参数设置。我第一版就把S7-200 Smart当成普通S7设备处理,现场工程师看看着红色报警灯跟我说采集程序是坏的,其实是协议栈压根没选对。
3.3 CNC设备采集:FOCAS与宏变量的对比
CNC设备是工业采集里比较特殊的一类,因为数控系统厂商各自的通讯协议差异很大。发那科相对好一点,它提供了FOCAS库,能够读取坐标、转速、倍率、报警信息、程序号等标准数据。但是FOCAS只支持Windows并且要安装官方开发包,这在工控机上还算能接受。
在实际项目里,我用FOCAS库做发那科CNC采集时,最常用的是这几种函数:cnc_rdactual(读实际坐标)、cnc_rdspindle(读主轴转速)、cnc_rdalm(读报警)、cnc_rdopnum(读当前程序号)。这些接口调用起来不算复杂,但FOCAS的句柄初始化必须放在一个独立线程里,不能在多线程里共用同一个句柄去并行读数据,否则会出现随机丢包。
国产数控系统那边就完全不一样了,比如广数、凯恩帝,它们通常只能通过宏变量来读取数据。每一台机床的参数含义还不一定相同,需要先查系统参数手册确认哪个宏变量对应主轴倍率、哪个宏变量对应进给速度。这种方式的灵活性很差,但胜在几乎所有系统都支持。采集精灵的做法是,把宏变量地址也纳入了标准的点位配置体系,和Modbus/S7的表单合并在一起,统一调度。
3.4 自定义串口协议:文档缺失时的破局办法
说了这么多标准协议,再聊一个让人头疼的:自定义串口协议。现场有一台老式在线测温仪,走RS485,说明书只写了“请求帧:AA 55 01 00 03 00 00 00 07,响应帧:……”基本上就是给了一堆十六进制报文让我自己去猜。
我的处理思路是用串口监听工具抓真实报文、反推协议结构。先让设备工程师手动操作一次设备面板,在电脑上抓到完整的请求和响应,然后逐个字节比对变化。多试几组数据之后,就能总结出帧头、命令字、数据段、校验码的规律。
对这类自定义协议,采集精灵有一个通用的“样板间”设计:把请求报文模板做成可配置的,点位地址不去解析设备内部地址,而是直接把偏移量写死,然后从响应帧的某个偏移位置取N个字节,按照指定的数据类型和字节序解析。这样一个通用驱动就能覆盖所有串口自定义协议,不必为每一台设备单独写代码。
4. 点位配置从Excel模板到数据库建模
4.1 配置界面是给现场工人用的,不是给自己用的
采集系统开发到后期会发现,最大的工作量不是驱动层,而是点位配置的管理。现场设备可能两三百个点位,每次新增变更都要开发人员去改配置文件、编译、重启,这在交付验收阶段是完全不可接受的。
采集精灵的点位配置我用了两级结构:设备级配置和点位级配置。设备级配置管IP地址、端口、通讯参数、轮询周期;点位级配置管协议地址、数据类型、换算公式、上下限、存储策略。两级分开的好处是现场加一台新设备时,先复制一份类似设备的配置,然后只改差异项,效率高很多。
配置方式我最终选了Excel模板导入加管理界面在线维护并存的方案。核心原因是:现场工程师对Excel太熟了。每家工厂都能给你拿出一份满满当当的设备点位表,里面连注释都写得好好的。我做一个标准Excel模板,把表头固定成系统认识的字段,让现场人员在这个模板里填好,然后一键导入到采集精灵里,再在管理界面里做校验和调整。
模板表头大概长这样:
| device_id | point_id | protocol | slave_id | db_number | area | start_addr | data_type | word_order | scale | offset | unit | collect_interval |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| dev_001 | p1 | s7 | 1 | 1 | DB | 0 | real | big_endian | 1 | 0 | degC | 1 |
| dev_001 | p2 | modbus_tcp | 1 | 0 | 4x | 10 | int16 | little_endian | 0.1 | 0 | MPa | 2 |
4.2 点位表设计的几个关键字段
点位配置表在数据库里的设计直接影响整个系统的灵活度。除了常规的device_id、point_id之外,有几个字段是我在多个项目中反复验证后觉得必不可少的:
quality_enable:该点位是否需要质量判断。有些点位现场设备本身没有返回值,是靠Modbus通信状态来判断的,这种点位不需要单独做质量判断;delta_threshold:变化量阈值。设备数值只有在变化量超过这个值时才会向外推送,否则数据虽然采集到了但不上行。这在处理温度、压力这种缓慢变化的模拟量时能大幅降低数据量;read_only:是否允许远程写操作。采集系统不能只读,MES偶尔要下发一些指令。但写操作权限一定要单独控制,防止误操作导致设备停线;store_policy:存储策略。0表示不存储、1表示按周期存储、2表示变化存储。这个字段决定数据落盘时是全部存还是只存变化的那一部分。
点位表设计还有一个很多人不注意的地方:点位坐标的唯一性约束。对同一台设备,(protocol, slave_id, area, start_addr)必须唯一。否则系统调度轮询时会读到重复数据还不自知。我在数据库里加了联合唯一索引,并在导入Excel时做了二次校验,但凡有重复地址直接拒绝导入并提示具体行号。
4.3 点位告警:边界值判断要放在边缘侧
之前碰到过一个场景:客户MES要统计每台设备的稼动率,判断依据是“设备是否在加工”。但“加工中”这个状态在数据侧没有一个直接的点,只能通过主轴电流是否超过某个阈值来推断。如果把这个逻辑放在MES端处理,MES收到的数据量大且没有边缘判断能力,特别容易因为网络延迟导致判断不准。
因此采集精灵里专门做了告警模板和状态推导功能。用户可以配置一个“虚拟点位”,它的值由关联的几个真实点位经过比较、运算得到。比如spindle_state虚拟点位的定义是:当spindle_current > 8时值为1,否则为0。这样MES拿到的数据里直接就有“加工状态”这一列。
在做这个功能时最大的坑是判断窗口期。主轴电流在启动瞬间会有一个尖峰,如果直接用瞬时值判断,很容易把“准备启动”误判成“加工中”。后来在计算逻辑里加了“连续N个采集周期都满足条件”的前置判断,才把误报压下来。这种经验如果不跑现场,光看算法是想不到的。
5. 断网续传、数据缓存与时间戳一致性
5.1 缓存策略:内存、磁盘与重复数据的取舍
工业现场网络环境永远不能用办公网络的标准来看待。工厂里的交换机可能因为老化、灰尘、重要设备启停造成电压波动而出现短暂断网,如果采集程序这时直接把数据扔了,MES那边在看历史曲线时就会出现空洞。
采集精灵的缓存策略分三层来设计:
第一层是实时推送缓存,只有最近几秒的数据缓存在内存里,用于应对几十毫秒级别的瞬断;第二层是断网归档缓存,当网络断开超过5秒时,数据自动转向本地SQLite落盘,并把状态标记为归档;第三层是补传队列,网络恢复后由上行线程按时间顺序补传,并带有去重标识防止MES收到重复数据。
这个三层设计在实现时有一个很关键的参数配置:retention_days,即本地归档数据保留多少天。保留时间太短,万一断网超过一天就丢了;保留时间太长,工控机硬盘会被撑爆。我在一台装了4G工业SSD的边缘设备上测试过,每秒钟产出100个点位数据,每个数据约150字节,在没有压缩的情况下,一天的数据量也就1.5GB左右。实际部署时保守一些,设为7天。
5.2 时间戳冲突:本地时钟和PLC时钟谁说了算
工业数据带时间戳是刚需,但时间戳的来源一定要选对。很多人直接取采集程序的本地时间,这会在两种情况下出错:
- 采集工控机的时钟没有和上层做NTP同步,运行几天后累计漂移可能达到几十秒;
- 某些PLC或仪表自身带时间戳,但这些时钟的电池老化之后,时间会固定在几年前某个时刻。
我在采集精灵里默认采用“本地时间优先,PLC时间作为参考”的策略。每个点位在配置时可以指定时间戳来源:local或者device。默认是local,并且在系统部署时强制要求工控机加入NTP时间同步,避免系统时间漂移。
这里有个容易被忽略的小细节:时区问题。MES系统如果部署在云端,云服务器默认往往是UTC时间,而现场工控机是北京时间(UTC+8)。如果采集程序直接发送标准Unix毫秒时间戳,双方约定好按UTC处理倒没什么问题,但有些MES在展示时会做一次时区转换,结果就出现了一小时或八小时的偏差。后来我在上行报文里干脆增加了一个timezone_offset字段,每次推送都带上当前时区偏移,这样MES那边无论怎么处理都能对齐。
5.3 数据补传时的“先来后到”和“控制频率”
断网恢复后,把断网期间积累的数据一次性全推出去,好像没什么问题,但实际会遇到两个新问题。
第一个是服务端处理不过来。MES接收端的消息处理队列是有限的,断网两小时积累了上百万条消息,恢复瞬间一股脑全推过去,直接导致对方消费者过载,消息积压甚至触发熔断。解决方式是用一个“斜率控制”的补传逻辑:恢复连接的前30秒,每秒钟补传的数据量只有正常速率的50%,之后每30秒增加10%,直到补传完毕或达到120%速率上限。这样服务端有时间做缓冲。
第二个是补传数据与实时数据重叠。采集程序断网期间,采集线程其实还在跑,恢复后先把历史缓存推送给MES,再推当前实时值。但如果MES端没有去重逻辑,同一时刻的数据可能会收到两次,一次来自断网缓存,一次来自实时队列。解决方式是在每条数据上加了全局自增的seq_id,MES端拿这个字段做幂等判断,重复消息直接丢弃。
6. 现场部署调试与故障排查实录
6.1 一套现场可以落地的部署顺序
总有年轻工程师问我:“你们去现场装采集系统,先去干什么?”这个问题其实非常重要。从我在十几个车间跑下来的经验来看,部署顺序错了会白白绕很多弯路。
我惯用的现场部署顺序是:
- 先做通讯清单盘点:把每台设备的IP地址、端口号、协议类型、点位表物理位置全部记录成一张表,并和客户设备部的人当面确认。很多设备IP地址会冲突有问题,这步越早发现越省钱;
- 再逐台测试协议连通性:写一个简单的批量Ping加协议握手脚本,先确认哪些设备是网络通但协议不通,哪些是IP都不通;
- 搭建采集环境:安装好采集精灵程序,配置好全局参数(如MQTT地址、SQLite存储路径、日志级别),再把设备配置导入;
- 单设备验证:挑一台上线设备,先从协议读取原始值,再经过换算后查看工程值,和现场仪表显示值核对;
- 全量接入并跑24小时稳定性测试:所有设备接入后,观察采集进程的内存占用、CPU使用率、通信失败率、缓存文件增长,确保没有泄漏问题才交付。
6.2 排查了几天的“丢数”问题,最后是它
在某个客户现场交付后次周,客户反馈MES里有个别点位会偶尔少一两分钟的数据,不是大面积丢,就是零星丢。一两个点的数据缺失在报表上看起来很不明显,但客户是做质量追溯的,要求每一个数据都不能丢。
我远程查了采集端日志,发现那一两分钟里采集程序还在正常运行,设备通讯也正常,但那个点位确实没有往MQTT推送数据。排查方向一度锁定在上行推送队列上,以为是队列阻塞。
后来翻了采集程序的内存快照,才发现问题出在点位轮询调度的时钟分配上。那个点位的采集周期配置成了5秒,而系统默认的调度表是按1秒为最小时间片来切分的。5秒的周期和调度表的最小时间片错位之后,每隔一段较长的时间就会产生一次调度“打盹”,恰好把那一次采集跳过了。
数值没有变化的时候还好,因为设置了变化推送,但不巧的是那几分钟设备温度在稳定上升,每次变化都该报却没报,一下就能看出来。修复方案是统一把采集周期调整为1秒的整数倍,并把调度器改成基于固定时间片的离散采样,而不是基于相对时间间隔的连续采样。经过这次教训,我在所有项目的默认配置里都把周期选项限制为:1秒、2秒、3秒、5秒、10秒、15秒、30秒,不允许随意填奇怪的时间间隔。
6.3 日志系统是远程排障的救命稻草
工业采集系统的排障和纯软件开发排障有一个很大区别:开发环境的错误你随手就能复现,但现场的错误不能等,设备24小时在跑,你不可能为了排查问题就停掉客户的产线。所以好日志比好代码还关键。
采集精灵的日志体系我在后期做了几个层面的分级:
DEBUG:记录每一帧完整的收发报文和协议解析详情,日常运行时关闭,定位问题时临时打开;INFO:记录设备上线、下线、重连、配置变更这类关键事件;WARN:记录单次通讯超时、单个点位解析失败等非致命异常;ERROR:记录驱动异常退出、数据库写入失败、上行推送连续失败等致命异常。
日志字段必须包含精确到毫秒的时间戳、设备编号、点位编号、协议类型、耗时、错误码。这样每一条报错都能对应到具体设备的具体点位。
我在连续几个项目中摸索出一条实用规则:日志文件按大小自动滚动,每个文件不超过20MB,最多保留50个文件。这样既保证了排查故障时有足够的历史日志可查,也不会因为日志过多把工控机硬盘占满。配合一个简单的看板页面,现场设备部的人自己也能看到哪些设备通讯不太稳定。
7. 从采集工具到数据基座的演进
7.1 通用数据接入层的沉淀
“采集精灵”做到第三个版本时,我开始意识到如果只把它当作一个专用工具,那路子越走越窄。一个车间的数据采集系统,今天要接的是PLC、CNC,明天可能就要接AGV调度系统、能源电表、光伏逆变器。如果每一次接入都重新开发驱动,项目之间的重复工作量会非常大。
于是我把驱动层和数据模型独立出来,做成一个通用数据接入层。这个接入层不关心数据的最终去向,只做一件事:把不同来源的数据转换成统一格式,交给上层业务去使用。采集精灵是这个接入层的第一个完整用例,但它也可以被其他应用复用。
这个演进方向给后续项目带来的好处非常直接。后来一个客户要求接入光伏逆变器的数据,逆变器走的是标准Modbus TCP,那我只需要在点位配置里加一个新的device_type:solar_inverter,把寄存器映射表填好就能采集。整个交付时间从预估的一周压缩到了两天。
7.2 边缘计算能力是未来分水岭
现在很多客户对数据采集系统的期望已经不只是“把数据拿回来”,而是希望采集端就具备一定的计算和判断能力。比如:
- 设备OEE计算,需要在线获取运行时间、停机时间、加工总数、合格数;
- 异常预警,需要在边缘侧识别工艺参数异常并主动报警;
- 数据压缩,缓慢变化的模拟量在边缘先进行死区判断,再决定是否上行;
- 多设备联动逻辑,比如A设备的温度过高时,自动给B设备下发指令降低转速。
这些功能如果都靠上位平台远程计算,延迟太高且稳定性差。采集精灵在后续版本里增加了一个轻量级的脚本引擎,支持在点位数据上挂载简单的JavaScript规则,让现场技术人员自己写几行判断逻辑。虽然这些规则远不如大数据平台里的算法复杂,但它在边端实时性上的价值是无可替代的。
我的建议是:有自研采集系统的团队,宁可前期多花点时间把边缘计算框架搭好,也不要等客户提需求了再临时改造,那时候的改动成本和风险都会成倍增加。
7.3 在交付之外的几点实在建议
回头看看做了几个工业数据采集项目,有一些建议真希望能早点知道:
第一,不要迷信大而全的平台。很多团队一上来就想做一个能采集所有设备、分析所有数据、展示所有报表的“工业互联网平台”。但这类平台最终大概率会死在“所有”两个字上。从一个具体的采集工具切入,站稳了一个厂、一条产线,再逐步扩展,这条路现在看起来更稳妥。
第二,现场沟通永远比远程看数据重要。有些数据问题在电脑上怎么看都觉得很奇怪,但跑到现场和设备师傅一聊,才知道那台设备的变频器是后来更换的型号,控制字定义和原来不一样。这些隐藏信息,永远不可能从日志里自动获得。
第三,版本管理千万不要忽视。采集系统长期在现场跑,可能一年都没人动它,但每次改动都要非常谨慎。我习惯把采集内核、驱动插件、点位配置、前端界面拆成四个独立版本管理的对象,避免因为一次配置修改导致整个程序需要重新发版的风险。
工业数据采集不是一个可以一劳永逸的“上线”项目,它是一个需要持续运营的系统。今天接好的设备,明天可能因为更换PLC程序导致地址不匹配;今天跑得好好的协议,后天可能因为设备固件升级产生兼容性问题。把工具做得灵活一点、把适配做得快一点、把定位做得清晰一点,这条路就能走得很稳。