C#开发OPC客户端实现OPCDA与KepServer通讯
目录一、实现效果二、准备内容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软件推荐一、实现效果二、准备内容1.1、KepServer 6.5软件1.2、o
目录
4.6、OPC测试常用的OPCClient和OPCServer软件推荐
一、实现效果
①点击刷新获自动获取取本机的计算机名称
②点击服务节点的下拉框选择该计算机名称,可以自动获取到该计算机的OPC服务名称(或者手动输入)
③选择服务名称的下选择该就算机上的服务名称(或者可以手动输入)
④当【服务节点、服务名称】都存在时,点击连接按钮,即可获取到该计算机服务器上的所有节点内容。
⑤点击获取到的服务器任意节点内容,即可显示该节点的实时数据信息。
C#实现OPC客户端通过OPCDA方式与KepServer通讯项目下载
二、准备内容
1.1、KepServer 6.5软件
1.2、OPCDAAuto.dll
三、实现思路
①获取OPC网络服务器和OPC服务名称
②打开与OPC服务的连接,通过OPCGroups、OPCGroup获取对应的OPCItem项
③建立OPCItem项目需要展示的内容实体展现数据
/***
* Title:"数据采集" 项目
* 主题:OPCDA与kepserver通讯帮助类
* Description:
* 功能:
* 1、获取到OPC服务器
* 2、打开OPCServe连接
* 3、获取到OPC服务器的所有节点内容
* 4、进行OPCGroups设置
* 5、进行OPCGroup设置
* 6、关闭OPCServe连接
* Date:2021
* Version:0.1版本
* Author:Coffee
* Modify Recoder:
*/
using OPCAutomation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Utils
{
class OPCDAHelper
{
#region 基础参数
//OPCServer服务器
private OPCServer oPCServer;
//OPC浏览对象
private OPCBrowser oPcBrower;
#endregion
//构造函数
public OPCDAHelper()
{
oPCServer = new OPCServer();
}
/// <summary>
/// 获取到OPC服务器
/// </summary>
/// <param name="serverNode">服务器节点</param>
/// <returns>返回该服务器节点对应的所有服务器列表</returns>
public Array GetOPCServerList(string serverNode)
{
try
{
object serverListObj = oPCServer.GetOPCServers(serverNode);
Array serverList = (Array)serverListObj;
return serverList;
}
catch (Exception ex)
{
MessageBox.Show("获取服务器列表出错!!!" + ex.Message, "一般错误", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
return null;
}
}
/// <summary>
/// 打开连接
/// </summary>
/// <param name="serverName">服务器的名称</param>
/// <param name="serverIP">服务器的IP地址</param>
/// <returns>true:表示连接成功</returns>
public bool OpenConnect(string serverName,string serverIP)
{
bool success = false;
if (!string.IsNullOrEmpty(serverIP) &&!string.IsNullOrEmpty(serverName))
{
try
{
if (oPCServer==null)
{
oPCServer = new OPCServer();
}
oPCServer.Connect(serverName,serverIP);
success = true;
}
catch (Exception ex)
{
success = false;
MessageBox.Show(ex.Message, "严重错误", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
}
}
return success;
}
/// <summary>
/// 获取到OPC服务器的所有节点内容
/// </summary>
/// <returns>返回OPC服务器的所有节点内容</returns>
public OPCBrowser GetAllBrowser()
{
try
{
oPcBrower = oPCServer.CreateBrowser();
oPcBrower.ShowBranches();
oPcBrower.ShowLeafs(true);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,"严重错误",MessageBoxButtons.YesNo,MessageBoxIcon.Error);
}
return oPcBrower;
}
/// <summary>
/// OPCGroups设置
/// </summary>
/// <param name="oPCGroups">需要设置的OPCGroups</param>
public void OPCGroupsSettings(ref OPCGroups oPCGroups)
{
oPCGroups = oPCServer.OPCGroups;
oPCGroups.DefaultGroupDeadband = 0;
oPCGroups.DefaultGroupIsActive = true;
}
/// <summary>
/// OPCGroup设置
/// </summary>
/// <param name="oPCGroups">OPCGroups</param>
/// <param name="oPCGroup">OPCGroup</param>
/// <param name="oPCGroupName">oPCGroupName</param>
/// <param name="updateRate">更新频率</param>
public void OPCGroupSettings(OPCGroups oPCGroups,ref OPCGroup oPCGroup,string oPCGroupName,int updateRate=250)
{
if (oPCGroups!=null &&
!string.IsNullOrEmpty(oPCGroupName)&& updateRate>0)
{
oPCGroup = oPCGroups.Add(oPCGroupName);
oPCGroup.IsActive = true;
oPCGroup.IsSubscribed = true;
oPCGroup.UpdateRate = updateRate;
}
}
/// <summary>
/// 关闭连接
/// </summary>
/// <returns>true:表示关闭</returns>
public bool CloseConnect()
{
bool success = false;
try
{
if (oPCServer!=null)
{
oPCServer.Disconnect();
success = true;
}
}
catch (Exception ex)
{
success = false;
MessageBox.Show(ex.Message, "严重错误", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
}
return success;
}
}//Class_end
}
/***
* Title:"数据采集" 项目
* 主题:OPC数据项实体
* Description:
* 功能:XXX
* Date:2021
* Version:0.1版本
* Author:Coffee
* Modify Recoder:
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OPCDAOfKEPServer.Model
{
class OPCBrowserItem
{
//变量ID
public string ItemID { get; set; }
//变量值
public string Value { get; set; }
//更新时间
public string UpdateTime { get; set; }
//质量
public string Quality { get; set; }
}//Class_end
}
四、补充知识
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/
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)