简介:这份PDF教程面向物联网与工业自动化方向的开发者,聚焦Kepware中OPC DA Client的配置与使用,帮助读者解决设备连接、数据采集与传输中的实际问题。内容从新建Project、创建Channel、添加Device到利用KEPServerEX的QC动态监测,完整覆盖基础操作流程,并涉及Optimization Method、Duty Cycle等关键参数设置,适合具备一定工控基础、希望快速上手Kepware的工程师学习。资源包内共1个PDF文件,约614KB,以图文步骤形式呈现,便于对照操作与查阅。目前已有5919人学习,说明该教程在同类资料中具有较高参考价值。通过阅读,读者可掌握Channel与Device的配置方法、理解数据质量代码含义,并借助动态监测验证数据传输,为后续物联网应用开发与维护打下基础。
1. 为什么你的 OPC DA Client 连不上 Kepware:从一次现场排查说起
很多做工业自动化的朋友第一次接触 Kepware,都是被同一个场景逼的:现场一台老 PLC 只支持 OPC DA,上位机却要换成新架构,中间必须有个稳定的数据通道。Kepware 使用教程里被搜得最多的关键词就是 OPC DA Client,因为这是最经典的组合——Kepware 当 OPC DA Server,你的程序当 OPC DA Client,两边通过 DCOM 握手。听起来简单,实际第一次配十有八九连不上,报错还特别玄学,不是「拒绝访问」就是「类未注册」,翻遍日志也看不出所以然。
这篇笔记就围绕这个组合展开:Kepware 侧怎么建通道、建标签、配 DCOM 权限,Client 侧怎么用代码连上去读值、订阅、断线重连,以及那些让人抓狂的坑到底怎么排。适合两类人:刚接手 OPC DA 对接、需要一份能照着跑通的最小流程的新手;以及已经能连上、但被稳定性、权限、性能问题反复折磨的老手。下面所有步骤都按「先能通、再谈稳」的顺序来,不跳步。
2. 把 Kepware 配成 OPC DA Server:通道、设备、标签三步走
2.1 先搞清楚 Kepware 里 OPC DA 到底暴露了什么
Kepware 本身是一个多协议采集平台,它对外可以同时提供 OPC DA、OPC UA、MQTT 等多种接口。当你用 OPC DA Client 去连它时,你连的不是某个 PLC,而是 Kepware 内部的「标签数据库」。所以第一步不是急着写 Client 代码,而是先在 Kepware 里把数据源接进来,让标签有值。
Kepware 的数据组织是三层:Channel(通道)→ Device(设备)→ Tag(标签)。Channel 对应一种驱动协议,比如某品牌以太网驱动;Device 对应一台具体设备,填 IP 和端口;Tag 就是你要读的点位,比如寄存器地址。只有这三层都建好、并且 Kepware 的 OPC DA Server 运行时处于启动状态,Client 才能看到标签。
常见做法是:先建一个 Channel,选对驱动,再在 Channel 下建 Device,填通信参数,最后批量导入或手动建 Tag。建完后在 Kepware 的 Quick Client 里能看到值在刷新,说明 Server 侧没问题,再去搞 Client。
2.2 建通道和设备的参数怎么填
打开 Kepware 配置界面,右键 Connectivity → New Channel。向导会让你选驱动,这里必须和现场设备匹配,选错了后面全白搭。给通道起个名字,比如Ch1,然后一路 Next,直到 Device 层。
Device 层最关键的是通信参数。以常见的以太网设备为例,需要填:
| 参数 | 说明 | 典型值 |
|---|---|---|
| Device ID | 设备标识,自定义 | PLC1 |
| IP Address | 设备 IP | 192.168.1.10 |
| Port | 通信端口 | 502 或驱动默认 |
| Scan Rate | 扫描周期,毫秒 | 1000 |
| Timeout | 单次请求超时,毫秒 | 3000 |
| Retry Attempts | 失败重试次数 | 3 |
Scan Rate 不要设太小,老设备扛不住高频轮询,1000ms 起步比较稳。Timeout 要大于设备正常响应时间,否则会频繁报超时。填完点 Finish,Kepware 会自动尝试连接,如果 Device 图标变绿或显示 Connected,说明通信通了。
2.3 建标签并确认 OPC DA 能读到
在 Device 下右键 New Tag,填地址。不同驱动的地址格式不一样,比如有的写40001,有的写R0001,必须查对应驱动的地址说明。建几个测试标签后,打开 Kepware 自带的 Quick Client,找到 OPC DA 分支,展开到你的标签,看 Quality 是不是 Good、Value 是不是在变。
如果 Quick Client 里能看到好值,说明 Kepware 作为 OPC DA Server 已经就绪。记下这个 OPC DA Server 的 ProgID,通常是Kepware.KEPServerEX.V6这类形式,Client 连接时要用到。不同版本 ProgID 可能不同,在 Kepware 的 OPC DA 配置里能看到实际值。
提示:Quick Client 能读到值,不代表远程 Client 能连上。远程连接还涉及 DCOM 权限,这是后面避坑章的重点。
3. 用代码写一个最小 OPC DA Client:连接、读值、订阅
3.1 选型:为什么多数人用 Python 或 C# 写 Client
OPC DA 基于 COM/DCOM,原生开发用 C++ 最直接但成本高。实际项目里常见两种选择:C# 用OpcNetApi或OpcRcw系列库,Python 用OpenOPC或pywin32调 COM。C# 类型安全、事件订阅写起来顺;Python 上手快、适合做数据转发和脚本化测试。
我一般先用 Python 快速验证连通性,确认 Server 侧和 DCOM 都没问题后,再用 C# 写正式服务。下面给一个 Python 的最小示例,依赖OpenOPC-Python3x这类兼容包,安装后直接调。
3.2 Python 最小 Client:连接、读单点、读多点
# 依赖:pip install OpenOPC-Python3x import OpenOPC import time # 连接 Kepware 的 OPC DA Server # opc_host 填 Kepware 所在机器 IP,本机可写 localhost opc = OpenOPC.client() try: opc.connect('Kepware.KEPServerEX.V6', '192.168.1.100') print('connected:', opc.servers()) except Exception as e: print('connect failed:', e) raise # 读单个标签 tag = 'Ch1.PLC1.Tag1' value, quality, timestamp = opc.read(tag) print(f'{tag} = {value}, quality={quality}, ts={timestamp}') # 批量读多个标签,减少往返 tags = ['Ch1.PLC1.Tag1', 'Ch1.PLC1.Tag2', 'Ch1.PLC1.Tag3'] results = opc.read(tags) for item in results: print(item) opc.close()逻辑说明:connect的第一个参数是 Server 的 ProgID,必须和 Kepware 里显示的一致;第二个参数是 Kepware 主机地址。read返回三元组,quality 为Good才说明值可信。批量读把多个标签一次发过去,比循环单点读快很多,标签多的时候差别明显。
参数说明:ProgID 写错会报「类未注册」;主机地址写错会报「拒绝访问」或超时。如果本机测试,主机地址用localhost即可,但远程连接必须处理 DCOM。
3.3 用订阅代替轮询:数据变化才回调
轮询读适合低频、少量标签。标签多、要求实时性时,应该用订阅(Subscription)。OPC DA 的订阅由 Server 在值变化时主动通知 Client,能大幅降低通信开销。
# 基于 OpenOPC 的订阅示例(部分兼容包支持 group/subscribe) import OpenOPC import time opc = OpenOPC.client() opc.connect('Kepware.KEPServerEX.V6', '192.168.1.100') # 创建组,设置更新周期 500ms group = opc.create_group('g1', update_rate=500) group.add('Ch1.PLC1.Tag1') group.add('Ch1.PLC1.Tag2') # 回调:值变化时触发 def on_change(tag, value, quality, timestamp): print(f'change: {tag}={value} q={quality}') group.callback = on_change # 保持运行 while True: time.sleep(1)逻辑说明:create_group的update_rate是 Server 检查变化的周期,不是每次强制读。add把标签加入组,Server 内部维护这些点的缓存。回调函数在值或质量变化时被调用。注意不同库的订阅 API 差异较大,如果用的包不支持 group,就退回轮询,或者换 C# 的OpcNetApi,它的订阅模型更标准。
参数说明:update_rate设太小会增加 Server 和网络负担,500ms 到 1000ms 是常见区间。回调里不要做耗时操作,否则会阻塞后续通知,建议只把数据塞进队列,由另一个线程处理。
4. DCOM 配置:远程 OPC DA Client 绕不过去的一道坎
4.1 为什么本机通、远程就不通
OPC DA 依赖 DCOM,DCOM 的安全模型默认只允许本机或同域内的受信调用。当 Client 和 Kepware 不在同一台机器、又不在同一个域时,默认配置几乎必然拒绝访问。表现就是本机 Quick Client 一切正常,远程代码一跑就报「拒绝访问」或「RPC 服务器不可用」。
解决思路是双向的:Kepware 所在机器要允许远程用户调用,Client 所在机器要允许以指定身份发起调用。两边都要配,只配一边通常不够。
4.2 Kepware 侧:DCOM 权限怎么给
在 Kepware 主机上运行dcomcnfg,展开 Component Services → Computers → My Computer → DCOM Config,找到 Kepware 的 OPC DA Server 项(名称里带 KEPServerEX 或对应 ProgID)。右键属性,重点配三处:
| 选项卡 | 要改什么 | 建议值 |
|---|---|---|
| General | Authentication Level | None 或 Connect |
| Security | Launch Permissions | 加入 Client 使用的账号 |
| Security | Access Permissions | 加入同一账号 |
| Identity | 运行身份 | 指定用户 或 交互式用户 |
Launch 和 Access 里加入的账号,必须是 Client 端发起连接时使用的账号。如果 Client 用当前登录用户,就把这个用户加到 Kepware 主机(或域)并授权。Identity 选「指定用户」时,填一个有权限的本地或域账号,并确保密码正确,否则 Server 起不来。
4.3 Client 侧:让调用带上正确身份
Client 侧同样运行dcomcnfg,在 My Computer 属性里配默认权限,或者在代码里显式指定身份。Python 的 OpenOPC 支持在 connect 时传用户名密码:
opc.connect( 'Kepware.KEPServerEX.V6', '192.168.1.100', username='opcuser', password='yourpassword' )逻辑说明:这里传的账号必须和 Kepware 侧 DCOM 授权里加的一致。如果两边机器不在同一域,需要在两台机器上都建同名同密码的本地账号,否则 DCOM 无法完成身份验证。
参数说明:用户名密码不要硬编码在代码里,正式环境用配置文件或凭据管理。如果连接仍失败,先在 Client 机器上用该账号登录,手动跑一次 Quick Client 远程连接,能通再回到代码。
注意:DCOM 配置改完后,最好重启 Kepware 服务和 Client 机器,部分权限变更不会立即生效。
5. 避坑与排查:OPC DA Client 连 Kepware 最常见的 5 个翻车点
5.1 报「类未注册」或「ProgID 无效」
现象:Client 一 connect 就抛异常,提示类未注册或找不到 ProgID。 原因:ProgID 写错,或者 Client 机器上没注册 Kepware 的 OPC DA 代理组件。 解决:在 Kepware 的 OPC DA 配置里复制准确的 ProgID;Client 机器上安装 Kepware 提供的 OPC Core Components,注册后再试。
5.2 报「拒绝访问」但账号密码都对
现象:账号密码确认无误,仍然拒绝访问。 原因:DCOM 的 Launch/Access 权限没加这个账号,或者 Identity 配错导致 Server 以错误身份运行。 解决:回到 Kepware 主机dcomcnfg,逐项检查 Launch 和 Access 列表,确认账号在列;Identity 改成「交互式用户」先试通,再换指定用户。
5.3 能连上但读值全是 Bad
现象:连接成功,read 返回 quality 为 Bad。 原因:标签地址写错、设备没连上、或者标签名大小写不匹配。 解决:先在 Kepware Quick Client 里确认该标签是 Good;检查 Client 里的标签路径是否包含 Channel 和 Device 前缀;地址格式对照驱动说明。
5.4 运行一段时间后断连,重连失败
现象:跑几小时后连接断开,代码重连报错。 原因:DCOM 连接被网络抖动或空闲超时断开,Server 侧会话未释放。 解决:加心跳读,定期读一个固定标签保持连接;重连前先opc.close()释放旧会话,再重新 connect;网络层确保 Client 和 Kepware 之间没有频繁丢包。
5.5 标签多了以后读取变慢
现象:几十个标签时正常,几百个后单次读取耗时明显上升。 原因:循环单点读,每次都是一次 DCOM 往返。 解决:改用批量读或订阅;批量读一次传标签列表;订阅让 Server 主动推变化。如果必须轮询,把标签分组,每组一次批量读,控制单次数量。
6. 让 Client 更稳:重连策略、心跳与性能取舍
6.1 一个可复用的重连封装
正式项目里,连接不能裸奔。我一般会包一层带重试和心跳的 Client 类,核心逻辑是:连接失败按退避重试,连接成功后起一个心跳线程定期读固定标签,读失败则触发重连。
import OpenOPC import time import threading class OpcClient: def __init__(self, progid, host, heartbeat_tag, interval=5): self.progid = progid self.host = host self.heartbeat_tag = heartbeat_tag self.interval = interval self.opc = None self._stop = threading.Event() def connect(self): while not self._stop.is_set(): try: self.opc = OpenOPC.client() self.opc.connect(self.progid, self.host) print('connected') return except Exception as e: print('retry:', e) time.sleep(3) def heartbeat(self): while not self._stop.is_set(): try: self.opc.read(self.heartbeat_tag) except Exception: print('heartbeat lost, reconnecting') self.reconnect() time.sleep(self.interval) def reconnect(self): try: self.opc.close() except Exception: pass self.connect() def start(self): self.connect() t = threading.Thread(target=self.heartbeat, daemon=True) t.start()逻辑说明:connect用循环加 sleep 实现退避重试,避免瞬间高频重连打爆 Server。heartbeat定期读一个固定标签,失败就重连。reconnect先关旧会话再连,防止句柄泄漏。
参数说明:心跳间隔 5 秒适合多数场景,太短增加负担,太长断连发现慢。重试 sleep 3 秒是经验值,网络差的环境可以拉长。
6.2 轮询和订阅怎么选
| 场景 | 推荐方式 | 理由 |
|---|---|---|
| 标签少于 50,实时性要求低 | 批量轮询 | 实现简单,可控 |
| 标签多,要求变化即知 | 订阅 | 减少往返,Server 主动推 |
| 网络不稳定 | 轮询 + 心跳 | 订阅断线恢复更复杂 |
| 需要历史归档 | 轮询定时采 | 采样节奏自己掌握 |
订阅不是万能,DCOM 下订阅断线后的恢复比轮询麻烦,很多现场最后还是用轮询加批量读。选型时先看标签规模和实时性要求,别一上来就追订阅。
6.3 最后一句实在话
我踩过最深的坑不是代码,是 DCOM 权限——曾经为了一个「拒绝访问」折腾了一整天,最后发现只是 Kepware 主机上 Access 权限少加了一个账号。所以现在我的习惯是:任何 OPC DA 项目,先把 Quick Client 本机跑通,再配 DCOM 远程跑通,最后才写业务代码。顺序反了,后面全是黑匣子。希望帮到你。
本文还有配套的精品资源,点击获取