☰
WinCC集成深度学习模型:HTTP中间服务实战解析
2026/10/20 17:53:06 网站建设 项目流程

做工业自动化的兄弟应该都有这种感觉:设备、PLC、画面组态搞得很熟,但客户一提到AI就有点犯怵。我前阵子接了个产线升级的活,需求很直白:现场已经上了WinCC,要把一个深度学习视觉质检模型接进去。模型是现成的,准确率也不错,问题卡在了“WinCC怎么把模型跑起来”这一步。网上能找到的资料要么是玩具Demo,要么只讲WinCC和PLC通讯,真正能落地的不多。我前后折腾了两周,从架构选型到脚本编写、从模型部署到现场排错完整跑了一遍,这里把整个过程写下来,给要接类似需求的同行做个参考。

1. 为什么要在WinCC里接深度学习模型

1.1 WinCC的边界在哪里

WinCC作为SCADA软件,强项是采集、监控、报警、趋势、历史归档,它的逻辑处理主要面向确定性的规则:压力超限报警、温度超过多少度触发连锁、液位低于下限启动补液泵。这些规则用C脚本、VB脚本、变量触发器都能做,而且做得很好。

但深度学习的场景恰恰是“规则写不出来”的那类,比如:

  • 产品外观缺陷检测,缺陷形态千变万化,靠灰度阈值和几何特征根本筛不准;
  • 仪表读数识别,现场表盘字体、角度、光线都在变,传统图像处理算法脆弱到换一个光照就要重新调参;
  • 设备预测性维护,振动波形、电流频谱里的早期故障特征,不是几行比较语句能判断的。

这些需求以前没办法接进WinCC,只能单独跑一套AI系统,操作员要看结果得切换电脑,数据也对不上。把深度学习模型直接接到WinCC里,本质上是让SCADA这张“白盒”网络获得“黑盒”判断能力,让AI推理结果像普通模拟量一样显示、报警、归档。

1.2 四种技术路径怎么选

我在开始动手前,把所有可能的技术路线列了一遍,总共四条:

方案原理优点缺点
C脚本直接调用DLL用C语言把深度学习推理封装成WinCC能调用的动态库时延最低,毫秒级,不依赖外部进程开发量大,模型环境与C接口要一起维护,Python生态的模型转成C接口很痛苦
VBS脚本调用COM组件把模型封装成COM对象,VB脚本直接创建对象调用与WinCC集成度高,不用额外起服务COM注册繁琐,32位/64位问题多,调试困难
OPC UA网关中转Python侧接入OPC UA服务器,WinCC作为OPC UA客户端读写数据走标准工业协议,IT和OT两边都认适合小数据量(比如推理结果标签),不适合传图像,且实时性受OPC UA扫描周期限制
HTTP API中间服务模型用Python封装成Web服务,WinCC用脚本发HTTP请求语言解耦、环境独立、部署灵活、模型热更新方便需要多维护一个中间服务,网络开销比DLL大

最后我选了第四种,HTTP API中间服务。

原因是实际项目里约束很明显:模型用PyTorch训练、GPU推理,跑在Python环境里,而WinCC是基于Windows的SCADA系统,两边技术栈完全不同。如果强行用DLL方案,意味着先把PyTorch模型转成ONNX或者TensorRT,再用C++重新写一遍前后处理,工作量直接翻倍,而且以后模型更新一次就要重新编译一次。用HTTP服务,模型侧Python代码基本不用动,WinCC侧只是发几个HTTP请求,两边互不干扰,出问题也能各自排查。

2. 架构设计与数据流动原理

2.1 推荐的集成架构

整体架构分三层:

  • 现场设备层:摄像头、PLC、传感器,负责采集图像和设备状态;
  • 推理服务层:一台独立的AI推理主机,装GPU,跑Python Web服务,加载深度学习模型,接收图像、执行推理、返回结构化结果;
  • WinCC监控层:运行WinCC的工程师站或服务器,通过脚本定时或按变量触发向推理服务发起请求,拿到结果后写入WinCC内部变量,再显示在画面上、触发报警、写入归档。

用文字描述就是:摄像头抓图程序把当前帧存成图片,同时给WinCC发一个“拍照完成”信号,WinCC脚本收到信号后调用推理服务接口,把图片路径或图片数据传过去,服务端完成推理返回标签和置信度,WinCC把这些值写到变量里,画面上的状态控件随之刷新。

2.2 为什么中间服务模式最省心

这个模式的好处,我实际用下来体会最深的有三点。

第一是坏了一个不会拖垮另一个。AI推理服务是Python写的,总会有版本依赖装乱、显存溢出、模型崩掉这类事故,如果模型直接以进程内方式嵌入WinCC,Python解释器一崩,WinCC Runtime进程也可能被拖死。走HTTP中间服务,最坏情况就是WinCC脚本请求超时,画面给个“AI服务离线”的提示,SCADA本身的采集、报警全部正常。这个故障隔离价值在连续生产的现场非常重要。

第二是模型更新成本极低。工业现场的模型几乎隔一段时间就要用新数据重新训练,如果用DLL方案,更新模型就要重新编译、停WinCC、替换文件、重启。而HTTP方案里,模型文件更新后重启一下推理服务进程就行,WinCC侧一行代码都不用改。

第三是可以用上Python生态里最好的东西。图像预处理、深度学习框架、ONNX Runtime、GPU加速,整个AI侧的工具链全部解放,不用迁就WinCC的脚本语言。

2.3 数据链路完整走一遍

以视觉质检为例子,一趟完整的数据流是这样的:

  1. 现场PLC控制相机拍照,拍完把图片保存到共享存储目录,路径是固定的,例如D:/capture/cap_20250910_153201.jpg;
  2. PLC同时把一个“拍照完成”位变量置1,写入WinCC变量;
  3. WinCC的脚本动作被这个变量的上升沿触发;
  4. 脚本拼接好JSON请求体,携带图片路径,调用推理服务的/predict接口;
  5. 推理服务读图片、做预处理、模型前向推理、后处理,返回给WinCC一个JSON,例如{"label": "defect", "score": 0.93, "elapsed_ms": 82};
  6. WinCC脚本解析JSON,写入AI_Result、AI_Score、AI_Elapsed这几个变量;
  7. 画面上对应的颜色状态显示控件、文本框、趋势归档自动更新,同时判断结果异常时触发报警。

难点集中在第5步的服务封装和第6步的脚本解析,下面分开细讲。

3. 实操第一步:把模型封装成推理服务

3.1 用FastAPI和ONNX Runtime搭建推理接口

我推荐的组合是FastAPI加ONNX Runtime,再加一个Uvicorn做ASGI服务器。FastAPI写起来简洁,自带接口文档,调试方便;ONNX Runtime的好处是模型部署不依赖PyTorch或TensorFlow的完整环境,只依赖一个轻量运行库,CPU和GPU都能跑,而且Windows下支持很好,这对工业现场尤其重要,因为现场的推理主机一般不愿意装完整AI框架。

为了让博文可以直接复现,我把核心代码写出来。这是我实际项目里精简过的一个版本,能跑通最小闭环。

import io import time import base64 import numpy as np from PIL import Image from fastapi import FastAPI, HTTPException from pydantic import BaseModel import onnxruntime as ort app = FastAPI() # 选择合适的推理设备,工业现场建议先用CPU跑通,再切GPU providers = ["CUDAExecutionProvider", "CPUExecutionProvider"] session = ort.InferenceSession( "D:/models/defect_detector.onnx", providers=providers ) class PredictRequest(BaseModel): image_path: str = None image_base64: str = None class PredictResponse(BaseModel): ok: bool label: str score: float elapsed_ms: int def preprocess(img: Image.Image): # 根据你模型训练时的预处理参数调整,这里以224x224为例 img = img.convert("RGB").resize((224, 224)) arr = np.asarray(img, dtype=np.float32) / 255.0 # 调整维度为 NCHW,做标准化 arr = arr.transpose(2, 0, 1)[None] mean = np.array([0.485, 0.456, 0.406], dtype=np.float32).reshape(1, 3, 1, 1) std = np.array([0.229, 0.224, 0.225], dtype=np.float32).reshape(1, 3, 1, 1) arr = (arr - mean) / std return arr.astype(np.float32) def postprocess(outputs): # 以单输出分类模型为例 logits = outputs[0][0] label_id = int(np.argmax(logits)) score = float(np.exp(logits[label_id]) / np.exp(logits - max(logits)).sum()) label = "ok" if label_id == 0 else "defect" return label, score @app.on_event("startup") def warmup(): # 启动时用一张假图跑一遍,把模型权重载入显存,避免第一次请求特别慢 dummy = np.zeros((1, 3, 224, 224), dtype=np.float32) session.run(None, {"input": dummy}) @app.post("/predict", response_model=PredictResponse) def predict(req: PredictRequest): t0 = time.time() if req.image_path: img = Image.open(req.image_path) elif req.image_base64: img = Image.open(io.BytesIO(base64.b64decode(req.image_base64))) else: raise HTTPException(status_code=400, detail="image_path or image_base64 required") tensor = preprocess(img) outputs = session.run(None, {"input": tensor}) label, score = postprocess(outputs) elapsed_ms = int((time.time() - t0) * 1000) return {"ok": True, "label": label, "score": score, "elapsed_ms": elapsed_ms}

启动服务只要在推理主机上执行:

pip install fastapi uvicorn onnxruntime pillow numpy uvicorn app:app --host 0.0.0.0 --port 5000

服务起来后,浏览器里打开http://推理主机IP:5000/docs就能看到FastAPI自动生成的接口文档,可以直接调试。这一步跑通了,后面WinCC侧的对接才有基础。

需要注意的是,providers列表里CUDA放在前面,如果在没有GPU的机器上运行,ONNX Runtime会自动fallback到CPU,但会告警。第一次调试我建议先用CPU环境排查逻辑,再上GPU,省得把推理逻辑和驱动问题混在一起。

3.2 图像输入与预处理的三个细节

这里说三个我踩过的坑,都直接影响推理结果。

第一是预处理必须和训练时一致。很多人把模型导出后,Python侧预处理随便写,图像尺寸不一样、标准化参数不对、通道顺序不对,出来的推理结果完全乱套。正确的做法是翻出训练代码里的预处理部分,逐行对照,特别是归一化的均值和标准差、缩放尺寸、是否做通道反转,这三样差一个,准确率可能从95%掉到30%。

第二是图像格式统一。现场抓图程序可能输出BMP、PNG、JPG,模型训练时用的可能是JPG。在预处理入口统一转成RGB再操作,不要直接拿原图喂给模型。另外PIL打开图片后默认可能带EXIF方向信息,某些工业相机会把方向写进EXIF,如果不处理,图像可能是旋转的,推理自然不准。稳妥做法是img = ImageOps.exif_transpose(img)。

第三是输入张量要连续内存。ONNX Runtime对输入数组的内存布局有要求,如果 numpy 数组经过切片、转置后不是C连续布局,运行时会报错或者性能下降。在喂给模型前加一句arr = np.ascontiguousarray(arr),能省掉一堆莫名奇妙的报错。

3.3 服务自检与接口压测

服务写完先别急着接WinCC,先用工具把接口压一遍,确认性能满足现场要求。我用的是Python的 requests 库写了个简单脚本,模拟WinCC的真实调用频率,连续发200次请求,统计耗时分布。

import requests import time import statistics url = "http://127.0.0.1:5000/predict" payload = {"image_path": "D:/capture/test_001.jpg"} times = [] for i in range(200): t0 = time.time() r = requests.post(url, json=payload, timeout=10) times.append((time.time() - t0) * 1000) if r.status_code != 200: print("error", i, r.status_code) print("avg", statistics.mean(times)) print("p95", sorted(times)[int(len(times) * 0.95)])

如果平均耗时超过500ms,就要评估现场的节拍是否接受。像产线质检通常节拍是2到3秒一件,500ms完全没问题;如果是高速运动物体,控制周期在200ms以内,那就要上GPU或者考虑缩小输入图像。

还有一个容易被忽略的点:模型首次加载很慢,但服务启动后才加载,也就是说服务重启后的第一次请求可能耗时几秒。所以我在代码里加了warmup,启动时跑一次假输入,把权重真正载入显存。这个细节在WinCC侧体现为“重启服务后前几个请求偶发超时”,排查起来非常迷惑人。

4. 实操第二步:WinCC脚本调用推理服务

4.1 WinCC脚本环境与触发方式

WinCC的脚本分为C脚本和VBScript,全局脚本编辑器(Global Script)里可以创建两种动作,也可以给画面对象添加事件动作。对HTTP请求这类任务,VBScript写起来更顺手,因为WinCC的C脚本调HTTP协议库比较麻烦,VBS里有现成的XMLHTTP和WinHttp对象可以直接用。

触发方式要根据现场需求选。我用了三种,分别适合不同场景:

  • 按钮事件:操作员点画面上的“开始质检”按钮,触发一次推理;
  • 变量触发:PLC在拍照完成后置位一个变量,WinCC检测到该变量变化的上升沿,自动触发推理,这是产线自动化场景最常用的方式;
  • 定时器触发:WinCC每隔N秒轮询一次,适合预测性维护这种对实时性要求不高、需要周期性判断的场景。

先说变量触发。在全局脚本编辑器里新建一个动作,右击 “变量触发器”,选CAM_Trigger这个二进制变量,设置变化时触发。这样PLC每次把CAM_Trigger从0变1,脚本就会执行一次,执行完把变量复位就行。这个模式非常稳,比定时器也更贴合现场节拍。

4.2 VBS脚本发送HTTP请求

WinCC的VBS脚本访问WinCC变量的标准写法是:

Dim tag Set tag = HMIRuntime.Tags("CAM_Trigger")

发送HTTP请求用的是MSXML2.XMLHTTP对象,或者安全性更高的WinHttp.WinHttpRequest.5.1。前者简单,后者可以设置超时时间,推荐生产环境用后者。核心代码如下:

Dim http, jsonStr, respText Set http = CreateObject("WinHttp.WinHttpRequest.5.1") ' 参数依次是解析超时、连接超时、发送超时、接收超时,单位毫秒 http.SetTimeouts 5000, 5000, 5000, 15000 http.Open "POST", "http://192.168.1.100:5000/predict", False http.setRequestHeader "Content-Type", "application/json; charset=utf-8" jsonStr = "{""image_path"": ""D:/capture/cap_20250910_153201.jpg""}" http.Send jsonStr If http.Status = 200 Then respText = http.responseText ' 后续解析代码 End If Set http = Nothing

注意我把Open的第三个参数设成了False,也就是同步请求。同步请求在WinCC里执行时会阻塞脚本线程,直到响应返回。如果推理服务可用,一般几百毫秒就返回,现场可以用。但服务挂掉、网络不通时,这个同步请求会一直阻塞到SetTimeouts的最大时间,WinCC画面会明显卡顿。这个问题我后面专门讲,这里先记住一个原则:推理服务的健康状态必须单独监控,不要让业务脚本去等一个很可能失败的请求。

4.3 解析JSON并写回WinCC变量

VBScript没有原生JSON解析函数,直接用responseText里的字符串做正则提取是最简单的。只要服务端返回格式固定,这个办法非常可靠。

Dim label, score, tagLabel, tagScore ' 使用正则从JSON字符串中提取指定key的值,这里简化处理只提取字符串和数字 Set reg = New RegExp reg.Pattern = """label"":""([^""]*)""" Set matches = reg.Execute(respText) If matches.Count > 0 Then label = matches(0).SubMatches(0) End If reg.Pattern = """score"":([0-9.]+)" Set matches = reg.Execute(respText) If matches.Count > 0 Then score = CDbl(matches(0).SubMatches(0)) End If Set tagLabel = HMIRuntime.Tags("AI_Label") Set tagScore = HMIRuntime.Tags("AI_Score") tagLabel.Write label tagScore.Write score

写回变量的名字要提前在WinCC变量管理里建好,且类型要匹配:AI_Label建议用文本变量(字符串),AI_Score用32位浮点数。如果类型不一致,Write会返回失败,但VBS不报错,调试时容易一头雾水。

如果返回的JSON里还有其他字段比如elapsed_ms,按同样方法提取。我习惯把耗时也显示在画面上,这样运维人员能直观看到服务性能是不是劣化了。

还有一个更完整的办法:用HtmlFile对象执行JavaScript来解析JSON,好处是支持任意嵌套结构,坏处是依赖Internet Explorer组件,现场精简系统上不一定能跑。正则提取虽然土,但依赖最少,工业现场最放心。

5. 实操第三步:工程化部署与踩坑

5.1 图像传输:base64还是共享目录

WinCC把图片数据传给推理服务,有两条路线。我两种都试过,结论很明确:有共享文件夹条件就用文件路径,别用base64传大数据。

用base64,脚本读取图片文件转字节流再编码:

Dim fso, file, base64Str Set fso = CreateObject("Scripting.FileSystemObject") file = "D:/capture/cap_001.jpg" ' 用ADODB.Stream读取二进制并base64编码

但工业相机拍的图很容易到10MB以上,base64编码后体积再膨胀三分之一,走一趟HTTP请求要传十几MB数据,网络稍微波动就会超时。而且WinCC的VBS处理大字符串性能很差,读文件、编码、拼接字符串都要时间去。

所以我推荐用共享目录方案:抓图程序把图片保存到一个WinCC和推理服务都能访问的目录(比如NAS或推理主机上的共享文件夹),WinCC脚本只需要在JSON里传文件路径字符串,服务端直接Image.open(path),短短几百字节就能完成一次调用。实测下来,这个方案对网络带宽的要求低一个数量级。

唯一要注意的是权限问题:推理服务进程运行账户必须对共享目录有读权限,WinCC运行账户要有项目目录的写权限。权限问题在测试环境一般不暴露,一上生产就出现“路径找不到”或“拒绝访问”。排查时先手动从两个进程的机器上分别打开同一个文件路径,确认都通再看代码。

5.2 超时、并发与WinCC界面卡死

这是整个集成项目里我最想展开讲的部分,也是最容易翻车的点。

WinCC的VBS脚本动作是跑在Runtime进程的主线程上下文里的,同步HTTP请求发出后,如果服务响应慢,界面交互、报警刷新、数据归档都会受牵连。我遇到过最夸张的一次,AI服务因为GPU被别的任务占满,单次推理耗时飙到5秒,WinCC操作画面直接“假死”了十几秒,操作员在控制室里急得拍鼠标。

解决思路是不要把慢请求直接放在关键UI节点上。我最终采用的方案是“触发脚本只负责发请求,结果脚本负责收数据”,也就是异步化。

具体实现是这样的:

  1. 画面按钮或PLC触发信号到来时,一个短脚本只做一件事:把图片路径写入一个待处理队列表,同时调用HTTP请求发出请求,然后在请求等待期间立刻退出(或者干脆不等待);
  2. 推理服务处理完请求后,把结果以JSON格式写入一个结果目录下的文件,文件名带流水号;
  3. WinCC另起一个周期为1秒的定时器脚本,轮询结果目录,发现新结果文件就读取、解析、更新变量、显示。

这套方案里WinCC永远不被阻塞,最慢的操作也只是读一个很小的结果文件。代价是结果不是严格的实时返回,会有一秒左右的延迟。对视觉质检、仪表识别这种场景完全够用,对需要严格闭环控制的场景才需要考虑更低延迟的方案。

如果现场网络条件好,推理服务又足够快,直接同步调用也可以接受。我在多个项目里都是先同步调通,再根据现场操作员的反馈决定要不要异步化。一上来就做异步,中间环节多了反而难排查。

5.3 服务守护、日志与模型热更新

推理服务是独立进程,就有进程崩溃的可能。我习惯把它注册成Windows计划任务开机自启,再用一个简单的守护脚本检测端口或健康接口。最简单实用的做法是加一个/health接口,返回服务状态,WinCC每10秒调用一次这个接口,把结果写到一个二进制变量AI_Online。画面上放一个状态显示控件,AI_Online=1显示绿色“AI在线”,AI_Online=0显示红色“AI服务离线”。一旦服务异常,操作员和运维马上能看到,而不是等业务脚本超时才发现。

日志方面,推理服务侧把每次请求的图片路径、推理结果、耗时写入本地日志文件,我用的是Python标准库logging,加一个按天切割的TimedRotatingFileHandler。这非常重要,因为模型偶尔会误判,当现场质量人员和WinCC上的结果对不上时,日志是唯一能复盘的数据,光靠WinCC侧的几个变量肯定不够。

模型热更新其实很简单,因为推理服务是独立进程,更新流程就是:准备新模型文件,命名成带版本号的路径,然后修改服务里的模型路径配置并重启服务。我为了避免切换瞬间的请求失败,做了一个平滑重启:先启动新的服务实例监听5001端口,确认新实例健康后把主服务的监听端口切到5001,再关掉旧实例。实际小项目中没必要搞这么重,直接停服务、替换模型文件、启动服务,总计一两分钟停机就够了,反正WinCC那边的健康检查会自动报警。

6. 典型应用场景与效果复盘

6.1 视觉质检场景

我落地最成功的一个场景是某汽车零部件厂的外观缺陷检查。现场原来靠人工目检,节拍快的时候漏检率居高不下,客户要求上AI。他们的产线控制用的是WinCC,初始需求只是“能不能在WinCC里显示AI结果并联动报警”。

最终方案:工位相机拍照后图片存到NAS,PLC置位触发WinCC脚本,WinCC调用推理服务,缺陷结果写回WinCC变量。画面里加了一个表格,最近200件的检测结果滚动显示,同时当AI_Result = "defect"时报警闪烁,并把结果写入归档,后面能按批次导出质量报表。

部署后实测,单件检测从拍照到画面刷新大约1.2秒,其中推理占80毫秒,剩下的时间都花在文件传输和WinCC变量刷新上,满足节拍要求。这里有个经验:工业现场的性能瓶颈往往不在GPU推理,而在数据搬运和SCADA内部刷新,不要一慢就想着升级显卡。

6.2 仪表读数识别场景

另一个场景是化工厂的老式压力表读数识别。现场几十块指针表,没有模拟量输出,工人每天要抄表。我们加了几路高清摄像头,按固定角度定时抓拍,WinCC定时器每隔15分钟触发一次批量识别。

这里和视觉质检有个明显区别:识别结果不是简单的“OK”或“缺陷”,而是一个连续的数值,要参与趋势归档。我的做法是服务端后处理直接返回到小数点后一位的读数,WinCC侧解析成浮点数,写入一个模拟量变量,原本WinCC的区域归档功能就能自动生成趋势曲线,完全不额外开发。

这个场景的教训是摄像头角度必须固定。刚开始有一路摄像头被蒸汽管道的维修工碰歪了几度,读数偏差从0.1级跳到了0.5级,现场没发现,后来靠WinCC趋势曲线和人工抄表数据比对才揪出来。后来我加了定期“标定检查”,识别零点和满量程两个特殊位置的读数,一旦偏差超阈值就报警,让维护人员重新校正摄像头。

6.3 预测性维护场景

还有一个偏数据的场景:电机轴承预测性维护。振动传感器数据通过PLC送到WinCC,但故障特征不明显。我们把振动数据的频谱特征统计好后,由WinCC周期性地把最近一段时间的特征向量发给推理服务,模型判断轴承健康状态。

这个场景的特殊之处在于,WinCC需要先做特征提取和降维,处理逻辑放在C脚本里反而比VBS更顺,因为要处理数组。C脚本调用HTTP是比较繁琐的事,我的做法是让C脚本把特征向量拼成字符串,写到几个WinCC变量里,再由VBS脚本读取这些变量并组装JSON发送。跨脚本语言的变量交接,是WinCC开发里非常实用的一个技巧。

我后来把这三个场景沉淀成了一个通用模板:图片或特征数据进WinCC,WinCC负责触发和展示,HTTP服务负责AI推理。新项目对接只需要改模型文件和JSON字段,不需要重写脚本,这是这套架构给我带来的最大收益。

7. 常见问题排查速查表

这段是给现场调试验收用的,全部来自我自己遇到过的真实问题。

现象可能原因解决办法
VBS脚本执行报 80072efdHTTP连接失败,服务没启动或端口不对在WinCC机器上浏览器访问接口地址,确认服务可达;检查防火墙入站规则
responseText为空,但状态200同步请求尚未完成就读取响应确认 Open 第三参数为 False;必要时在 Send 后加循环判断 readyState
返回中文乱码服务端返回GBK或WinCC错误解码UTF-8用ADODB.Stream读取 responseBody 并指定 charset=UTF-8 解码
WinCC画面卡顿十几秒同步HTTP请求阻塞UI线程改成异步轮询方案,或缩短服务推理耗时,增加健康检查提前预警
偶发请求超时首次推理慢、GPU忙于其他任务服务启动时预热;推理请求加锁或队列;升级GPU显存
识别结果随机乱跳图像预处理或输入张量布局有问题对照训练代码检查预处理;添加np.ascontiguousarray
模型文件被占用无法更新推理进程未完全退出先停服务进程,确认端口释放后再替换模型文件
WinCC变量写不进去变量类型与脚本写入类型不匹配在变量管理里核对类型:文本变量写字符串、浮点变量写Double
服务重启后请求失败模型加载需要时间,健康检查报假警服务启动后自动预热,再开始对外服务,健康检查返回“模型已加载”后才置在线

我强烈建议在调试阶段分步验证,不要一上来就把整条链路跑起来。先单独用工具测接口,再用简单的脚本测WinCC发请求,最后才接真实PLC和相机。每步都确认变量、字段、类型一致,出问题了能迅速定位是服务端、脚本还是网络的问题。

最后说点实在的

如果你手头也有类似的“WinCC调用深度学习模型”需求,我的建议是从HTTP中间服务这条路径入手,别被DLL那种看上去更“高级”的方案带偏。整个集成里真正难的其实不是WinCC,也不是模型训练,而是两侧工程师的协作方式。做WinCC的人不熟悉Python环境,做AI的人不熟悉SCADA变量体系,两拨人要把“图片路径、JSON字段、变量类型、触发时机”这几个点对齐,才算真正把一个项目做成。

我个人的体会是,先把数据流图画清楚比写代码更重要。你用一张纸把现场摄像头怎么抓图、文件存在哪、WinCC怎么触发、服务怎么调用、结果写哪个变量画出来,项目就已经成功了一半。后面照着这张图一步步去实现,哪怕中间踩坑,也知道是哪个环节的问题。这套方法我用了好几个项目都顺下来了,分享给你。

最后再分享一个小技巧:WinCC侧写脚本时,所有的IP地址、端口、文件路径都定义在脚本最顶部的常量区,不要散落在代码里。这样换服务器、换网络环境时,只需要改几行配置,整个项目迁移的成本能省掉大半。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询