
半夜两点手机响那头是值班小伙子略带慌张的声音“X工2号线又停了中控室这个画面红灯一直闪我看不懂是啥故障。”我明白他看不懂的其实不是画面而是这个点该不该打扰我。这种场景搞WinCC运维的基本都经历过。WinCC作为老牌SCADA稳定是真稳定报警画面、趋势归档、事件记录都做得规规矩矩可惜一切都被锁在中控室里。人一离开操作台现场就像断了线的风筝啥也看不见。要是车间没配短信猫连个自动拨号都没有全靠值班员那一嗓子。这篇聊聊我自己解决这个问题的方案不碰老WinCC系统在它旁边塞一台基于Node-RED的边缘计算网关把报警直接推到企业微信。这套做法成本极低硬件几百到两三千部署快而且对原有系统几乎零侵入。适合谁参考老产线不能停机、预算有限、又想随时随地用手机看到设备报警的自动化工程师、车间设备管理员以及负责工厂IT/OT融合的运维团队。1. 老WinCC报警能力的真实短板以及为什么我选“外挂”而不是升级先说说我面对的实际情况。现场是一套跑了快十年的WinCC 7.4 SP1服务器是台老款戴尔塔式机下挂两条S7-300产线以太网早就通了但报警系统还停留在“中控室看得见、出了门就瞎”的阶段。白天人在中控室还没事到了晚上、周末、节假日设备一停等值班员电话打到你这里往往已经过去半小时了。WinCC原厂不是没给报警扩展能力但算下来都不划算。官方有个WebUX选件能把画面发到浏览器上可它要单独授权价格按变量点数算老版本升级还要过一遍兼容性测试。再往上走升级到V8.x意味着操作系统、数据库、授权狗全要换服务器硬件大概率也得跟着升级停机窗口至少按周末算车间根本抽不出这个时间。对很多厂来说WinCC本身没坏坏的是“报警出不了门”这件事为这个去动手术换心脏亏。所以我当时定的调子是“外挂”旁路部署网关接在控制网交换机上逻辑上跟WinCC并行谁也不是谁的前提。只读优先网关只从PLC或WinCC侧读数据绝不写任何控制相关的内容。独立生存网关挂了、断电了、网络断了原WinCC系统毫发无损生产画面照常跑。低成本试错硬件加调试两天内搞定觉得不行拔了网线就撤没有任何历史包袱。这套思路本质上就是“边缘计算网关”最常见的落地姿势把老系统的数据在边缘侧接出来做现代应用需要的活。WinCC负责它擅长的SCADA监控Node-RED负责它擅长的接口粘合和消息推送各干各的互不添乱。2. 数据从哪儿来四种取数路线的取舍我最后选了哪条报警要推出去第一步是让Node-RED拿到现场状态。看起来简单实际操作里有四条路线坑的深浅完全不一样。2.1 路线ANode-RED直接读PLC——最稳但要有图纸既然WinCC下面的PLC本来就是通过以太网通信的Node-RED完全可以直接跟PLC对话把WinCC整个绕开。S7-300/400支持ISO-on-TCP的S7通信协议端口102Node-RED生态里有现成的node-red-contrib-s7节点装上以后填PLC的IP、机架号、槽号就能按字节、字、位去读DB块和标志位。报警点位如果是存在DB里的位轮询周期设1秒到3秒基本能做到“现场变化手机秒收”。这条路最大的优点是完全不碰WinCC老系统稳如泰山。缺点也很明显你得知道报警点在PLC程序里的具体地址。老项目的图纸如果还在问题不大图纸丢了或者厂家当初加密了程序块那就麻烦了。我这边还好主设备的报警字集中在DB10和DB11里每个字节对应一台设备的若干个故障位拿地址表一对照就出来了。2.2 路线B从WinCC的OPC服务器取数——理论上美配置上烦如果PLC程序地址拿不到可以退一步让WinCC当数据源。WinCC自带OPC DA服务器你甚至可以把WinCC画面里的变量直接暴露出去Node-RED这边用OPC UA客户端去连。但坑来了WinCC 7.4自带的还是OPC DA 2.0DCOM那一套跨机器配置相当折腾Windows防火墙要开135端口和动态端口范围DCOM组件里要给匿名用户加权限用户名密码得跟WinCC服务器本地账户对上。我调试那两天一半时间耗在“OPC客户端连上了读一秒卡十秒”和“明明同一网段却提示拒绝访问”这种问题上。如果你一定要走这条路建议让Node-RED去连一个OPC UA网关比如Kepware或者软网关由网关去跟WinCC的DA通信再以UA协议暴露给Node-RED。等于多一层但把最难的DCOM问题隔离在了网关和WinCC之间后面Node-RED侧就清爽很多。2.3 路线C直接读WinCC后台SQL库——最不建议WinCC的历史数据、报警记录都存在自带的SQL Server里懂点SQL的工程师自然会想能不能直接查数据库拿报警我的回答是能但强烈不建议。一是WinCC的归档表结构属于内部实现官方不承诺兼容你查表的SQL这次能用下个补丁包一打可能就不能用了二是实时性不行SQL Server里的过程值经过归档周期延迟少则几十秒多则分钟级三是最要命的如果你只读还好万一查询条件写得不合适把WinCC的数据连接拖垮了那问题就大了你本来是来解决报警的结果把监控搞挂了。这条路线我直接排除。2.4 路线D让WinCC脚本导出CSV文件——做补充可以做主力别想也有一种思路在WinCC里写个全局脚本把报警信息定时写成CSV文件Node-RED通过共享文件夹或者FTP去读。实现简单适合WinCC侧不方便开OPC、PLC地址表也拿不到的场景。缺点同样明显脚本跑在WinCC服务器上WinCC负载高的时候脚本会卡文件轮转要处理两台机器之间还得搞网络共享。我把它定位为“临时顶一下”的方案不推荐当作长期主力。2.5 我的最终选择综合考虑我选了PLC直接读路线A为主OPC DA转UA路线B做补充。因为S7直读最稳实时性最好还不依赖WinCC的状态只有个别拿不到地址的点才从WinCC变量里绕一下。下面对比表是我当时做决定用的也放出来供你参考取数路线实时性对原系统侵入性实施难度维护成本S7直读PLC秒级极低仅占用通信资源低需要地址表低WinCC OPC DA转UA秒级到数秒低需配置DCOM较高依赖OPC网关中查SQL Server归档表分钟级高有拖垮库的风险中表结构不公开高WinCC脚本导出CSV秒级到数十秒中脚本跑在WinCC上低中文件轮转繁琐3. 报警流的核心设计Node-RED里别只做“转发”很多教程让你装个节点、拉根线、连上微信就完事。真按那个做上线当晚你就得被报警刷屏刷到怀疑人生。我这边刚开始就是吃了这个亏后来把报警逻辑重写了一遍才消停。3.1 轮询、变化检测和去抖Node-RED里用S7节点定时读报警字默认就是周期轮询。最简单的做法是每个周期把读到的值直接发到微信结果就是只要某个位是1微信每秒钟响一次手机直接变震动棒。所以第一步必须做变化检测。在function节点里把本次读的值跟上次的值做异或只有发生变化的位才进入后续判断。第二步是去抖。工业现场电磁干扰、接触器吸合、通信瞬时中断都会让点位状态闪一下。我踩过一次一夜之间推了四十多条假报警全是机柜里一个24V继电器抖动带出来的。后来加了个“连续三次读到同一个状态才确认为真”的规则误报基本归零。代价是报警延迟增加了几秒但对微信通知来说完全可接受。下面是我这个function节点里去抖和变化检测的核心思路供参考// 假设msg.payload是S7读回的报警字数值 let current msg.payload; let ctx context.get(alarm-filter) || { last: null, count: 0, confirmed: null }; // 如果当前值与上一次一致累计计数否则置零 if (ctx.last current) { ctx.count Math.min(ctx.count 1, 3); } else { ctx.count 1; ctx.last current; } // 连续3次一致才认为状态稳定 if (ctx.count 3 ctx.confirmed ! current) { ctx.confirmed current; context.set(alarm-filter, ctx); // 此时才把数据交给后续消息分发节点 return msg; } context.set(alarm-filter, ctx); return null; // 不满足条件流程到此为止3.2 报警级别、恢复通知和防刷屏不是所有报警都值得半夜把人吵醒。我按现场重要性把报警分成两级一级报警是设备停机、安全回路断开这类必须立即推送二级报警是温度偏高、压力波动这类白天推送、晚上合并到次日早报里。Node-RED里实现很直接判断点在变化检测之后根据报警字对应的位掩码决定走哪条分支。恢复通知容易被忽略但不做的话你半夜被叫醒处理完故障刚要睡报警还是挂在那里。我在状态机里加了一个“从报警到正常”的翻转判断某一位从1变回0就推一条“XX设备报警恢复”的消息。这样值班人员看到“恢复”两个字就知道事情翻篇了。防刷屏同样是刚需。如果现场出了大故障几十个点同时报警就算做了去抖微信也会瞬间收到几十条。我加了个简单聚合一分钟内如果报警条数超过10条后面就不再逐条推改成每5分钟推一条汇总比如“当前共15个报警最新2号线主电机过载”。真正常见的故障场景用这一招基本能压住。3.3 状态存哪里以及网关重启后的恢复Node-RED的上下文默认存在内存里一重启之前“是否在报警中”的记性全没了。更尴尬的是如果网关半夜自动重启而现场刚好有报警重启后Node-RED读到报警位是1但由于没有历史状态对比它可能认为状态没变化就不推送了。解决方法是把上下文改成文件持久化在settings.js里配置contextStorageNode-RED会把context存到本地文件。然后加一个启动节点inject节点设为“启动时触发一次”让流程启动后主动把所有报警点位的当前值读一遍跟文件里保存的“上次确认状态”做比较如果发现本来就该报警却没推过立即补推一条“网关重启当前设备处于报警状态”。这个细节实测能避免大部分“网关重启导致漏报”的背锅。4. 微信通道怎么选企业微信群机器人还是应用消息数据拿到手、逻辑判完了接下来就是最后一公里怎么把消息送到人的手机上。微信通道这块我试过几条路结论比较明确。4.1 个人微信方案我不推荐碰有人会提“用个人微信的hook协议”去发消息实现起来看起来很简单但我劝你别碰。原因有三一是个人微信没有官方开放接口所有hook都处于灰色地带随时可能被限制甚至封号二是工厂的报警消息属于生产数据走一个不稳定的通道哪天半夜悄无声息挂了你压根不知道三是维护成本全在你身上账号一掉线第一责任人就是你。做自动化运维的稳定压倒一切这种方案再省事也pass。4.2 企业微信群机器人最简单的广播通道企业微信里可以创建一个群把设备运维、车间值班的人都拉进去然后在群设置里添加一个“群机器人”会得到一个Webhook地址。Node-RED这边不需要装任何额外节点用HTTP Request节点POST一段JSON就够了{ msgtype: markdown, markdown: { content: ## 2号线停机报警\n设备主电机过热\n时间2025-01-15 02:13:45\n建议请值班人员立即到配电柜检查 } }请求地址是https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key你的机器人key。群机器人最大的优势是简单不涉及token获取、用户管理二十分钟就能通。缺点是只能往群里推不能精确指定某个人所有人一视同仁。4.3 企业微信应用消息能到具体责任人的定向通道如果想要“白天推值班群、晚上只推车间主任”这种精细化规则就得用企业微信的自建应用。流程稍微绕一点先在企业管理后台创建一个“报警通知”应用拿到CorpID、Secret和AgentIdNode-RED里先请求gettoken接口换取access_token有效期7200秒建议缓存起来别每次都换然后调用message/send接口按用户账号发消息。请求体大致是{ touser: zhangsan, msgtype: text, agentid: 1000002, text: { content: 2号线主电机过载请立即处理。 } }实际用下来应用消息和群机器人不是二选一而是组合使用一般报警走群机器人广播到值班大群严重报警走应用消息点对点推给车间主任和设备员。另外提醒一句企业微信接口有频率限制群机器人官方限制是每分钟20条正常报警场景完全够用但如果你的报警聚合逻辑没做好触发了频控微信侧会返回错误码这时Node-RED里要做错误重试不然消息就悄悄丢了。4.4 第三方推送服务也能用但工厂场景慎选市面上还有Server酱、PushPlus这类推送服务注册后给个KeyHTTP请求一发消息就到微信。个人项目或设备数量很少的场景可以玩但我没把它作为生产主力原因是数据要经过第三方服务器报警点位、设备名称这些信息等于裸奔给外部很多工厂的信息安全要求不允许。企业微信是官方通道消息不出企业域合规性上踏实得多。5. 边缘网关硬件选型与现场部署的几个关键决定Node-RED本身对硬件要求很低一块树莓派就能跑。但“能跑”和“能稳定跑在工业现场”是两码事硬件选型上我有几个实际经验。5.1 几种硬件方案的对比方案成本稳定性推荐程度树莓派4B/5300-600元SD卡容易坏工业现场慎用不推荐作主力二手迷你工控机如戴尔3050微型机300-800元配SSD后很稳定推荐全新工业防火墙/边缘网关2000-4000元高有商业支持预算充足选这个复用现有服务器开虚拟机0-1000元高但依赖宿主机看现场条件我最后用的是二手迷你工控机i5处理器、8G内存、256G SSD价格五百出头。Node-RED只占其中很小一部分资源剩下的算力我还顺便跑了一个Modbus TCP采集服务把几台老变频器的数据也接进来了。工业现场不建议用树莓派的SD卡我见过太多“跑着跑着文件系统只读”的案例换成SSD以后基本不会犯病。另外电源一定要原装或工业级适配器最好再挂一个小的UPS。网关电源挂了的案例比网关本身坏掉的还多。5.2 网络接线和访问控制网关接在PLC同一台交换机上IP规划要避开WinCC服务器、工程师站和触摸屏设一个固定IP。接下来是容易被忽略的一点只放行必要流量。我在网关的操作系统里用iptables做了限制入方向只允许以下几类PLC的102端口S7通信如果走OPC UA则允许OPC UA服务端口通常4840本机SSH、Node-RED管理端口1880只允许工程师站IP访问出方向只允许HTTPS到企业微信接口域名。这个规则我强烈建议你按同样思路做一遍。边缘网关一旦暴露太开等于给控制网开了个口子哪怕内网相对可信多一层隔离多一分安心。Node-RED的管理界面也要设置用户名密码默认无认证直接访问这在工控网里太危险了。5.3 成本算总账硬件五百多加上调试两天的人力总成本不到两千块。对比官方WebUX选件几万块的报价或者升级V8整套工程几十万的花费这套方案基本等于“不要钱”。而且网关后续还能干很多事采集设备OEE数据、做能耗统计、给MES系统喂数据相当于花一次钱搭了一个长期的边缘数据底座。6. 上线半年踩过的坑以及现在的运行习惯方案跑到现在小半年了从最初“半夜群里闹翻天”到现在的“安静到快忘了它的存在”中间踩了不少坑挑几个值得说说的。6.1 坑一S7连接资源被占满了Node-RED通过S7协议跟S7-300通信占的是CPU的PG/OP连接资源。老款S7-300这块资源本来就紧张WinCC占了两个工程师站的编程器占了一个触摸屏再占一个Node-RED再挤进去CPU直接报“通信连接资源不足”。一开始我百思不得其解明明昨天还好好的过了一天就断了。后来去硬件组态里看CPU属性里的通信资源才发现连接数已经顶格。解决办法有几个一是把Node-RED的轮询周期从1秒放到3秒连接资源占用会明显下降二是如果还有富余的通信处理器CP卡把连接放到CP卡上三是换用OPC UA路线避开这个资源问题。我最后是“降频规范重启时间”双管齐下才消停。6.2 坑二DCOM时好时坏差点劝退第一次尝试OPC DA的时候DCOM问题简直是我那两天的噩梦。白天配好了能读到了晚上WinCC服务器一锁屏或者安全策略一刷新又连不上了。后来我看清楚了DCOM的坑不在于配置项本身而在于Windows环境和域策略一变化就得重来。这也是为什么我更推荐直接走S7协议的原因——它根本不依赖Windows那一堆用户权限模型TCP 102端口一开通信干干净净。6.3 坑三报警抖动半夜被误报“轰炸”去抖逻辑是上线后第二周补上的。当时2号线的冷却风机一启动接触器吸合的瞬间PLC输入模块上有个备用点信号闪了一下Node-RED检测到变化就直接推了“风机故障”报警。值班员跑过去一看风机转得好好的。这种事一晚上发生三次群里怨声载道。加了“连续三次确认”的去抖之后这种物理抖动基本被过滤干净了。小经验去抖的确认次数不要设太大否则真实报警也会被拖得响应很慢三次是个不错的平衡点。6.4 坑四网关重启后状态丢失漏报有一次厂里检修顺便给网关所在的机柜断电了。恢复供电后网关自己起来了WinCC和PLC都正常但Node-RED内存里的状态全没了。最尴尬的是当时恰好有一台泵处于报警状态但因为“没有状态变化”Node-RED认为无需推送一直没发消息。第二天早上我是看到现场值班记录才发现这个漏报。从那以后我就做了两件事第一context持久化到文件这是必须的第二在Node-RED启动时增加“全量状态核对”逻辑把所有报警位读一遍凡是没有推送过且当前确实处于报警状态的补发一条“网关重启后恢复报警上下文”。这两件事做完“重启丢状态”这个隐患彻底解决。6.5 坑五时间不同步报警时间戳对不上网关的时间和PLC时间如果差了五分钟报警消息里显示的时间和WinCC趋势图的时间就对不上排查故障的时候会把方向带偏。解决很简单在网关里配了NTP同步指向厂里的时间服务器同时把PLC的时钟同步也打开两边时间严格对齐。这个细节看着小但等你真靠时间戳去倒查故障前因后果的时候就知道有多重要了。6.6 现在的运行习惯每周自动备份Node-RED的流程存在flows.json里我写了个定时任务每周打包一次备份到另一台机器。网关自监控给网关本身加了个心跳机制每隔5分钟往值班群推一条“心跳正常”消息。如果群里超过10分钟没看到心跳就说明网关可能挂了值班员会第一时间通知我。代价是群里多了点无用消息但换来的安心感值了。升级前先测Node-RED生态更新很快但我不在生产环境随便升级节点库。每次都是先在备用环境测一天确认不破坏现有流程再动手。这套微信报警方案其实只是边缘计算网关在老产线上的一次小试水。数据既然已经能从PLC里出来了后面能做的东西还有很多比如设备OEE统计、能耗分析、关键参数趋势预测。对我个人来说最大的体会就一条老系统能不动就不动用最小的改动去解决现场最痛的问题。微信报警只是起点边缘侧的玩法才刚刚拉开序幕。