飞道的博客

C#开发OPC客户端实现OPCDA与KepServer通讯

566人阅读  评论(0)

 

目录

一、实现效果

二、准备内容

1.1、KepServer 6.5软件

1.2、OPCDAAuto.dll

三、实现思路

四、补充知识

4.1、OPC逻辑对象模型

4.2、OPC Server对象

4.3、OPC Group对象

4.4、OPC Item对象

4.5、OPC通信

4.6、OPC测试常用的OPCClient和OPCServer软件推荐


一、实现效果

①点击刷新获自动获取取本机的计算机名称

②点击服务节点的下拉框选择该计算机名称,可以自动获取到该计算机的OPC服务名称(或者手动输入)

③选择服务名称的下选择该就算机上的服务名称(或者可以手动输入)

④当【服务节点、服务名称】都存在时,点击连接按钮,即可获取到该计算机服务器上的所有节点内容。

⑤点击获取到的服务器任意节点内容,即可显示该节点的实时数据信息。

C#实现OPC客户端通过OPCDA方式与KepServer通讯项目下载

局域网环境下远程连接 OPC 配置方法下载

二、准备内容

1.1、KepServer 6.5软件

KepServer6.5软件下载

1.2、OPCDAAuto.dll

OPCDAAuto.dll下载

三、实现思路

①获取OPC网络服务器和OPC服务名称

②打开与OPC服务的连接,通过OPCGroups、OPCGroup获取对应的OPCItem项

③建立OPCItem项目需要展示的内容实体展现数据


  
  1. /***
  2. * Title:"数据采集" 项目
  3. * 主题:OPCDA与kepserver通讯帮助类
  4. * Description:
  5. * 功能:
  6. * 1、获取到OPC服务器
  7. * 2、打开OPCServe连接
  8. * 3、获取到OPC服务器的所有节点内容
  9. * 4、进行OPCGroups设置
  10. * 5、进行OPCGroup设置
  11. * 6、关闭OPCServe连接
  12. * Date:2021
  13. * Version:0.1版本
  14. * Author:Coffee
  15. * Modify Recoder:
  16. */
  17. using OPCAutomation;
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Linq;
  21. using System.Text;
  22. using System.Threading.Tasks;
  23. using System.Windows.Forms;
  24. namespace Utils
  25. {
  26. class OPCDAHelper
  27. {
  28. #region 基础参数
  29. //OPCServer服务器
  30. private OPCServer oPCServer;
  31. //OPC浏览对象
  32. private OPCBrowser oPcBrower;
  33. #endregion
  34. //构造函数
  35. public OPCDAHelper()
  36. {
  37. oPCServer = new OPCServer();
  38. }
  39. /// <summary>
  40. /// 获取到OPC服务器
  41. /// </summary>
  42. /// <param name="serverNode">服务器节点</param>
  43. /// <returns>返回该服务器节点对应的所有服务器列表</returns>
  44. public Array GetOPCServerList(string serverNode)
  45. {
  46. try
  47. {
  48. object serverListObj = oPCServer.GetOPCServers(serverNode);
  49. Array serverList = (Array)serverListObj;
  50. return serverList;
  51. }
  52. catch (Exception ex)
  53. {
  54. MessageBox.Show( "获取服务器列表出错!!!" + ex.Message, "一般错误", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
  55. return null;
  56. }
  57. }
  58. /// <summary>
  59. /// 打开连接
  60. /// </summary>
  61. /// <param name="serverName">服务器的名称</param>
  62. /// <param name="serverIP">服务器的IP地址</param>
  63. /// <returns>true:表示连接成功</returns>
  64. public bool OpenConnect(string serverName,string serverIP)
  65. {
  66. bool success = false;
  67. if (! string.IsNullOrEmpty(serverIP) &&! string.IsNullOrEmpty(serverName))
  68. {
  69. try
  70. {
  71. if (oPCServer== null)
  72. {
  73. oPCServer = new OPCServer();
  74. }
  75. oPCServer.Connect(serverName,serverIP);
  76. success = true;
  77. }
  78. catch (Exception ex)
  79. {
  80. success = false;
  81. MessageBox.Show(ex.Message, "严重错误", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
  82. }
  83. }
  84. return success;
  85. }
  86. /// <summary>
  87. /// 获取到OPC服务器的所有节点内容
  88. /// </summary>
  89. /// <returns>返回OPC服务器的所有节点内容</returns>
  90. public OPCBrowser GetAllBrowser()
  91. {
  92. try
  93. {
  94. oPcBrower = oPCServer.CreateBrowser();
  95. oPcBrower.ShowBranches();
  96. oPcBrower.ShowLeafs( true);
  97. }
  98. catch (Exception ex)
  99. {
  100. MessageBox.Show(ex.Message, "严重错误",MessageBoxButtons.YesNo,MessageBoxIcon.Error);
  101. }
  102. return oPcBrower;
  103. }
  104. /// <summary>
  105. /// OPCGroups设置
  106. /// </summary>
  107. /// <param name="oPCGroups">需要设置的OPCGroups</param>
  108. public void OPCGroupsSettings(ref OPCGroups oPCGroups)
  109. {
  110. oPCGroups = oPCServer.OPCGroups;
  111. oPCGroups.DefaultGroupDeadband = 0;
  112. oPCGroups.DefaultGroupIsActive = true;
  113. }
  114. /// <summary>
  115. /// OPCGroup设置
  116. /// </summary>
  117. /// <param name="oPCGroups">OPCGroups</param>
  118. /// <param name="oPCGroup">OPCGroup</param>
  119. /// <param name="oPCGroupName">oPCGroupName</param>
  120. /// <param name="updateRate">更新频率</param>
  121. public void OPCGroupSettings(OPCGroups oPCGroups,ref OPCGroup oPCGroup,string oPCGroupName,int updateRate=250)
  122. {
  123. if (oPCGroups!= null &&
  124. ! string.IsNullOrEmpty(oPCGroupName)&& updateRate> 0)
  125. {
  126. oPCGroup = oPCGroups.Add(oPCGroupName);
  127. oPCGroup.IsActive = true;
  128. oPCGroup.IsSubscribed = true;
  129. oPCGroup.UpdateRate = updateRate;
  130. }
  131. }
  132. /// <summary>
  133. /// 关闭连接
  134. /// </summary>
  135. /// <returns>true:表示关闭</returns>
  136. public bool CloseConnect()
  137. {
  138. bool success = false;
  139. try
  140. {
  141. if (oPCServer!= null)
  142. {
  143. oPCServer.Disconnect();
  144. success = true;
  145. }
  146. }
  147. catch (Exception ex)
  148. {
  149. success = false;
  150. MessageBox.Show(ex.Message, "严重错误", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
  151. }
  152. return success;
  153. }
  154. } //Class_end
  155. }

  
  1. /***
  2. * Title:"数据采集" 项目
  3. * 主题:OPC数据项实体
  4. * Description:
  5. * 功能:XXX
  6. * Date:2021
  7. * Version:0.1版本
  8. * Author:Coffee
  9. * Modify Recoder:
  10. */
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Linq;
  14. using System.Text;
  15. using System.Threading.Tasks;
  16. namespace OPCDAOfKEPServer.Model
  17. {
  18. class OPCBrowserItem
  19. {
  20. //变量ID
  21. public string ItemID { get; set; }
  22. //变量值
  23. public string Value { get; set; }
  24. //更新时间
  25. public string UpdateTime { get; set; }
  26. //质量
  27. public string Quality { get; set; }
  28. } //Class_end
  29. }

四、补充知识

4.1、OPC逻辑对象模型

OPC逻辑对象模型包括3类对象:OPC server对象、OPC group对象、OPC item对象,每类对象都包括一系列接口。

 

这里最需要注意的是项并不是数据源,项代表了到数据源的连接。

例如一个在一个DCS 系统中的TAG 不论OPC 客户程序是否访问都是实际存在的。项应该被认为是到一个地址的数据。大家一定要注意项的概念。不同的组对象里可以拥有相同的项,如组1 中有对应于一个开关的Itemaaa,组2 中也可以有同样意义对应于一个开关的Itemaaa,即

同样的项可以出现在不同的组中。

4.2、OPC Server对象

主要功能:

1、创建和管理OPC Group对象;

2、管理服务器内部的状态信息。

4.3、OPC Group对象

主要功能:

1、管理OPC Group对象的内部状态信息;

2、创建和管理Items对象;

3、OPC服务器内部的实时数据存取服务(同步与异步方式)。

属性:

name:组的名字,由客户端自己定义。

active:组的激活状态,如果为false则组内全部Item将不再从数据源取数据,在客户端中的表现是读取不到数据,同时写数据也影响不到服务器端。

update rate:服务器向客户端提交变化数据的更新速率(这个数值应比服务器设定的最小值大)。

Percent Dead band:数据死区,即能引起数据变化的最小数值百分比。

4.4、OPC Item对象

主要功能

用来描述实时数据,代表了与服务器数据源的连接,而不是数据源。一个项不能被OPC客户端访问,因此在OPC规范中没有对应于项的COM接口,所有对项的访问都需要通过OPC Group对象来实现

属性:

name:项的名称,在服务器对应于Item ID。

active:项的激活状态。

value:项的数据值。

quality:项的品质,代表数值的可信度。

The OPC_QUALITY_xxx 定义了一个过程值或者事件的品质。并且分为3类,good, uncertain和bad。

下面的类型为合法的:

类型 值 说明

OPC_QUALITY_GOOD 0xC0 值是好的。

OPC_QUALITY_LOCAL_OVERRIDE 0xD8 值被覆盖。典型意思为输入失去连接和手动被强制。

下面的类型为不确定:

类型 值 说明

OPC_QUALITY_UNCERTAIN 0x40 没有指定原因说明值为什么不确定。

OPC_QUALITY_LAST_USABLE 0x44 最后的可用值。

OPC_QUALITY_SENSOR_CAL 0x50 传感器达到了它的一个限值或者超过了它的量程。

OPC_QUALITY_EGU_EXCEEDED 0x54 返回值越限。

OPC_QUALITY_SUB_NORMAL 0x58 值有几个源,并且可用的源少于规定的品质好的源。

下面的类型为坏的:

类型 值 说明

OPC_QUALITY_BAD 0x00 值为坏的,没有标明原因。

OPC_QUALITY_CONFIG_ERROR 0x04 服务器特定的配置问题。

OPC_QUALITY_NOT_CONNECTED 0x08 输入没有可用的连接。

OPC_QUALITY_DEVICE_FAILURE 0x0c 设备故障。

OPC_QUALITY_LAST_KNOWN 0x14 通讯失败。最后的值是可用的。

OPC_QUALITY_COMM_FAILURE 0x18 通讯失败,最后的值不可用。

OPC_QUALITY_OUT_OF_SERVICE 0x1C 块脱离扫描或者被锁。

OPC_QUALITY_SENSOR_FAILURE 0x10 传感器故障。

The OPC_LIMIT_xxx定义了值的限制范围。

类型 值 说明

OPC_LIMIT_OK 0x00 值在上低限,高限之内。

OPC_LIMIT_LOW 0x01 值低限。

OPC_LIMIT_HIGH 0x02 值高限。

OPC_LIMIT_CONST 0x03 值是常数。

Timestamp:时间戳,代表数据的存取时间。

 

注:

1.Item的存储类型————VARIANT(编写程序时使用的主要也是它)

2.Item的数据类型(VARTYPE):

3.Item的Alias:项的别名,由服务器设置,避免了项名称过长所带来的麻烦。

4.Group类型:公共组和私有组。公共组由多个客户共享,私有组只属于某一OPC客户。公共组对连接到服务器的所有客户都有效,而私有组只能对建立它的客户程序有效。(大多服务器未实现有公共组)

5.Item在服务器端定义,对应于硬件实际地址,客户端连接服务器端后创建并添加OPC Group,并创建一系列OPC Item(连接到服务器端定义的Item),将逻辑上等价的一组OPCItem添加到OPC Group中才能通过组对象来对数据进行存取操作。

4.5、OPC通信

1. 同步通信:OPC客户端对OPC服务端进行读取操作时,OPC客户端必须等到OPC服务器端完成对应操作后才能返回,在此期间OPC客户端处于一直等待的状态。

2. 异步通信:OPC客户端对OPC服务器端进行读取操作时,OPC客户端发送请求后立即返回,不用等待服务器端,当OPC服务器端完成操作后再通知客户端程序。

3. 订阅:需要服务器端支持OPC A&E规范,由客户端设定数据的变化限度,如果数据源的实时数据变化超过了该限度,服务器则通过回调返回数据给客户端。

4.6、OPC测试常用的OPCClient和OPCServer软件推荐

OPCDA Client

1、OPCClient.exe

把它放在第一位并不是有多好,而是100KB的体积,单文件,也很符合OPC标准,所以是个超便携的OPCClient。

2、Matrikon公司的OPCClient.

很不错的一个OPCClient,标准,稳定,单文件,通讯过程的信息还比较丰富,我是比较喜欢用它在创建OPC组时定义同步方式或异步方式来验证远程计算机的OPC配置是否正确。缺点就是大了点,2M多。

3、Kepware公司的OPCClient

功能很强大,标准,稳定,日志信息很丰富,最推荐的功能是支持对OPCServer中点名的条件过滤,支持点表的导入导出,支持自动导入OPCServer的所有点,根据点表识别好点坏点,按照列排序,用它可以弥补很多国产组态软件不能在线遍历OPCServer点表的功能、不能过滤OPCServer点的功能、不能识别OPCServer中好点坏点的功能等。缺点就是非单文件。

OPCDA Server

1、Knight.OPCServer

简单,还是简单,单文件运行起来啥都有了,148KB,很适合做简单的测试。

2、Matrikon公司的OPCServer Simulator

简单,单文件注册后,各种数据类型,各种点类型(只读点,只写点,读写点)都有了,更好的一点是,如果想做大规模的测试,10万点,那么只需要在它的Random.下添加任意名称即可,OPCServer会自动给你建出对应的测点,还是随机数变化。

3、Kepware公司的OPCServer

这是一个商业软件,需要花费金钱购买License的,但Kepware公司的OPCServer需要花钱的不是OPCServer本身,而是采集驱动。不过Kepware公司的OPCServer提供了不花钱的仿真驱动,用来测试上正是杀人越货的好东西啊,推荐理由的第三条就是说它老兄了。缺点就是太庞大,不简单,学习成本较高。但为了能满足OPC这类产品的各种测试,它真的是最佳选择。由于它是商业软件,我就不提供下载地址了,各位去它的官方网站可以下载,做好的几万点的测试工程需要的找我要。

4、iFiX

支持双向OPC支持所有类型的ActiveX、OLE,对不健全的控件所引发的错误进行保护,对控件的属性操作完全控制。有全面解决扩展点的报警、报警记录、历史记录的方法,有查找替换功能,可以替换整个图画以及画面中的对象的属性、组态点信息,对于同类型物体,避免重复组态。内嵌VBA,具有自己的内部函数,又有广泛的VB函数,功能扩展更为有利。编辑与运行是切换进行的,这有利于对现场生产安全的保障;有独立的报警监视程序,支持在线修改,具有画面分层功能,运行时可以根据程序很方便地更换对象的连接数据源,可以使控制更灵活。支持Oracle、SQL Server2000、Access等关系型数据库。

5、Cimplicity

支持OPC服务器,编辑与运行分开,有独立的报警、历史趋势运行管理程序,内嵌VBA,具有自己的内部函数,又有广泛的VB函数,组VBA与通用运行方式不一样,支持ActiveX、OLE插入,但对控件其中的一些属性进行了锁定。点的扩展功能与iFIX一样强大,但对于扩展点的报警设定比较难解决,输出问题,历史记录是没问题的。支持Oracle,SQLServer2000,Access关系型数据库。

6、InTouch

提供双向OPC支持,支持ActiveX控件,但不具有第三方控件的出错保护,不健全的控件会造成系统出错。采用有限的内部函数,其功能也只是常用监控的功能,复杂一点的功能如报表就只能借助于其他工具。支持关系型数据库。

7、WinCC

双向OPC支持,支持ActiveX。使用内部语言,环境如同C语言。同样使得其功能扩展变得容易。最新的WinCC 6.0只支持连接SQL2000数据库。

4.7、开源OPC项目

LIGHTOPC:OPC服务器,是C/C++语言开发的,http://www.ipi.ac.ru/lab43/lopc-en.html

OpenOpcUa:是C/C++语言开发的跨平台项目,http://www.openopcua.org/

OpenOPC:是基于Python语言的项目,http://openopc.sourceforge.net/

freeopcua:https://github.com/FreeOpcUa/freeopcua

open source and free implementation of OPC UA:https://github.com/open62541/open62541

OPC-Client-X64:https://github.com/edimetia3d/OPC-Client-X64

node-opcda:https://github.com/lizhengzhou/node-opcda

Utgard:OpenSCADA项目底下的子项目,纯Java编写,具有跨平台特性,全部基于DCOM实现(划重点),目前只支持DA 2.0协议,3.0协议的支持还在开发中。http://openscada.org/projects/utgard/

JEasyOPC Client:底层依赖JNI,只能跑在windows环境,不能跨平台。整个类库比较古老,使用的dll是32位的,整个项目只能使用32位的JRE运行。同时支持DA 2.0与3.0协议。但64位系统兼容性不好,容易出错。https://sourceforge.net/projects/jeasyopc/

 

 

 


转载:https://blog.csdn.net/xiaochenXIHUA/article/details/117035998
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场