乔富强,赵 旭
(天津中德职业技术学院 信息系,天津 300350)
在能源信息化集成过程中,环保局要求各热电厂的锅炉实时数据进行上传,企业内部也需要通过浏览器实时监控锅炉数据。这些数据的传输从起点到终点要经过现场工控机(配有OPC服务器)、OPC客户端、UDP传输层和监控主机,其中OPC客户端为分散于各处的生产数据与中央监控搭建了桥梁。大部分热电厂都通过配置OPC服务器,向外提供符合OPC标准的统一接口[1],但传统的OPC客户端都是基于一个客户端访问一台服务器开发的[2-3]。为了适应环保局对多个热电厂数据的同时采集,本系统实现了单一客户端对多服务器的连接。同时考虑到每个连接应独立工作,当一个连接出现问题,不影响其它服务器的访问,采用了多线程模型解决这一问题。另外,数据采集是长期的工作,由于网络环境的不稳定性,客户端与服务器的连接经常断开,因此,系统提供了自动监控连接状态,断点续连的功能,减少了操作人员的负担。
OPC(OLE for process control)是一个用于过程控制的技术标准,它基于微软的OLE(现在的Active X)、COM(部件对象模型)和DCOM(分布式部件对象模型)技术,采用客户/服务器模式,制定了关于数据采集、历史趋势以及事件报警等接口标准[4]。只要遵守这些标准,在客户机和服务器之间就可以交换数据。
OPC逻辑对象模型中包括3种对象:服务器对 象 (OPCServer)、 组 对 象 (OPCGroup) 和 项 对 象(OPCItem)。这3种对象层次不同,每种对象都包括一系列接口。如图1所示,一个OPCItem对应实际的硬件装置上的某一个channel或port,它包括值(Value)、品质(Quality)、时间戳(Time Stamp)3 个基本属性;一个OPCGroup则包含了许多的OPCItem,同时也定义了这些OPCItem更新的时间、方式,并提供读取OPCItem属性的接口;而一个OPCServer则包含若干个OPCGroup,同时提供操作这些OPCGroup的接口[5]。OPC客户端若要从服务器中采集数据,首先应得到服务器对象的引用,然后通过操作组对象的接口动态创建组对象,最后通过组对象读取项对象的属性值。
图1 OPC服务器结构图Fig.1 OPC server structure diagram
本系统以Visual Studio 2010为平台,应用VB.Net语言开发,项目中引入了OPCAutomation.dll组件,其中封装了客户端与服务器交互的方法。
项目中建立了3个与功能相关的类,其中Opc-ClientOperator类主要表达了客户端与服务器一对一的连接,并提供了采集数据方法;ThreadsOperator类封装了OpcClientOperator类的对象数组,每个对象代表一个与服务器的连接,从而实现客户端与多服务器的交互,这个类也定义了线程数组,它为每个连接启动一个线程,避免了多连接情况下的相互冲突;OpcClientObserver类提供了异常处理以及修复连接的方法,当连接发生异常时,调用这些方法实现断点续连。这3个类的主要成员如图2所示,详细介绍这些类的实现细节。
图2 OPC客户端类视图Fig.2 OPC client class view
OpcClientOperator对象可完成对一台OPC服务器的数据采集,其工作过程由以下步骤组成:
步骤1调用ConnectRemoteServer函数连接到指定的服务器,该函数以服务器IP地址或主机名作为参数,若连接成功,MyOpcServer变量保留服务器对象的引用,并用ServerState记录服务器连通状态(OPCServerState.OPCRunning),否则捕获异常,提示错误信息。
步骤2调用CreateGroup函数创建组对象,MyOpcGroup保存组对象的引用,当成功创建了组对象,可添加即将被采集的项对象序列,其中组名称及项变量名称由项目的配置文件导入,关键语句如下:
步骤3调用SetGroupProperty函数设置组的属性,主要包括下列内容:
步骤4采集数据,StartClientChannel是本类中的主要函数,也是启动线程时的绑定函数,该函数内部首先执行了以上3个过程,然后开始从服务器采集数据,而本类定义了3种客户端与服务器的通信方式:
①同步方式MyOPCGroup_SyncRead
OPC服务器把项对象的值、品质和时间戳作为函数的参数返回给客户端,在结果被返回之前客户端程序必须处于等待状态。
②异步方式MyOPCGroup_AsyncRead
OPC服务器接到客户端的请求后,几乎立即将方法返回。OPC客户端随后可以进行其他处理。当完成数据访问时,OPC服务器主动触发客户端的异步访问完成事件,将数据访问结果传送给OPC客户端。OPC客户端在事件处理过程中接收传来的数据。
③订阅方式MyOPCGroup_DataChange
服务器按一定的更新周期(UpdateRate)更新数据缓冲区的数值时,如果发现数据有变化,就会触发组对象的DataChange事件通知客户端,而发生变化的数据作为事件处理函数的参数返回给客户端。
步骤5启动定时器timer,定期监测服务器连接状态 CheckServerState,若连接异常,则触发OffLine事件通知OpcClientObserver来处理。
为解决断点续连问题,本系统采用了事件和委托机制[6],事件是对象发送的消息,以通知操作的发生。操作可能是由用户交互引起的,也可能是由某些其他的程序逻辑触发的。引发事件的对象称为事件发送方。捕获事件并对其作出响应的对象叫做事件接收方。这种机制源自于Observer(观察者)模式,事件的发送方是被观察的主体,事件的接收方是观察者,当主体发生变化时,观察者被自动告知更新[7]。在事件通信中,事件发送方不知道哪个对象或方法将接收并处理该事件。因此在发送和接收方之间必须存在一个媒介 (类似函数指针)。.NET Framework定义了一个特殊的类型–委托类型(Delegate),该类型提供函数指针的功能。委托是可保存对方法的引用的类,与其他的类不同,委托类具有一个签名,并且它只能引用与其签名匹配的方法。这样委托就等效于一个类型安全的函数指针或一个回调。
根据事件和委托机制,首先在OpcClientOperator类中声明了一个委托类型OffLineEventHandler,以及依托于该委托的事件OffLine,当触发事件时,由该委托所指向的函数来处理。
其中参数sender表示引发事件的对象,而参数e中记录了事件接收方感兴趣的信息,比如服务器的连接状态ServerState和地址等,接收方通过这些值判断异常的类型以及重新连接的地址。
接下来在OpcClientObserver类中定义了3个函数,其中RepairConnection是符合OffLineEventHandler委托类型的事件处理函数,它先调用ExceptionHandle来判断连接异常的类型,若为物理性断网,则通知用户手动操作,否则尝试重新建立与Opc服务器的连接,若一次连接不成功,则等待若干秒后重新尝试,反复几次,其中等待时间和最大重连次数由用户在ThreadWaitingTime和MaxConnCount成员变量中的赋值所决定。若连接成功则调用ThreadHandle恢复数据采集的线程;若达到最大重连次数仍未成功,则提示用户手动操作,并结束数据采集线程。
.NET Framework允许用户将事件与处理程序动态绑定,当主程序启动后,分别为每个OpcClient-Operator对象绑定事件处理函数。
这样,在对数据采集线程实施定时监控过程中,如果发现某个连接断开,则引发OffLine事件,根据委托,操作系统自动调用事件处理函数重新建立连接。
该类封装了OpcClientOperator类的对象数组ClientOp,和.Net线程数组 Threads。DoClientJob 是客户端工作的启动函数,它首先初始化ClientOp数组的每个对象,为每个对象设置连接服务器的地址,组信息及项信息,然后将这些对象的Start-ClientChannel函数分别绑定到Threads数组的每个线程对象,作为工作线程的函数,最后依次启动这些线程。
每个线程独立处理客户端与一台服务器的连接及数据采集工作,当一个连接异常时,不影响其它线程的工作[8]。
虽然本系统实现了断点续连的功能,但在某些情况下,比如网络物理性断开,或重新连接数次达到上限都不成功,还是需要人员手工操作,基于这些考量,本类也提供了动态管理线程的方法。ResetOneThread函数用于重置某个指定的线程,当某个线程异常而中止工作时,可以调用该函数重新启动这个线程。当客户端不再需要访问某个服务器时,可以调用StopOneThread函数停止某个指定的线程,它们以服务器地址和线程对象的下标为参数。OPC客户端完整的工作流程如图3所示。
图3 OPC客户端工作流程图Fig.3 OPC client working flow chart
系统测试工作在一个真实的环境下进行,应用该OPC客户端采集天津市滨能集团5组锅炉的参数,首先在各自的工控机上搭建OPC服务器环境,应用的服务软件是西门子的WinCC。然后设置组和项的参数,并将这些参数导出到配置文件供OPC客户端使用,这些参数包括OPC服务器地址、类型、组名、项变量名以及相关注释。最后在一个远程主机上启动客户端,开始访问这5个OPC服务器。
配置客户端的操作如图4所示,列表框中导入了所有服务器的地址,当选择某个地址时,文本框中会显示该服务器类型和已添加的组。当点击“导入参数项”时,系统会读取配置文件中的项变量信息,包括序号、变量名和标题。启动客户端以后开始采集所有服务器的项变量数据。
图4 配置OPC客户端Fig.4 Configure OPC client
在列表中选择某个服务器地址,可以查看从该服务器上接收的项变量的值、质量和时间戳信息。通过“重置线程”和“终止线程”,用户可以手动的重启或停止当前线程,而不影响另外4个线程的采集工作。当重启某个OPC服务器时,连接发生异常,此时断点续连机制生效,经过数次的重连、等待,连接恢复,照常接收数据。
本系统通过OPC技术,采用面向对象封装的思想,充分利用VB.NET的多线程机制进行多服务器的连接,动态地管理线程,提高了系统的稳定性,完成了企业锅炉数据的采集与发送的开发。系统提供了便利的人机界面,方便了使用者的操作,在实际应用过程中达到了预期的效果。
[1]蒋近,段斌.基于OPC技术的监控主站实时数据传输[J].电力自动化设备,2008,28(9):97-100.
[2]黄锦花,常喜茂.基于快速开发工具的OPC客户端的开发与实现[J].化工自动化及仪表,2013,40(7):893-897.
[3]苏磊,李茜,汤伟.OPC数据访问客户端的研究与实现[J].计算机工程,2010,36(11):80-82.
[4]陈烨,仓小金,彭蓬,袁小平.基于OPC中问件技术的网络控制系统[J].电力自动化设备,2011,31(1):100-104.
[5]望荆沙.基于OPC DA 3.0的OPC服务器与客户端的研究与实现[D].西安:西安电子科技大学,2012.
[6]任玉辉,张新海.动态连接多服务器的OPC客户端在烧结控制系统中的应用[J].烧结球团,2011,36(1):19-24.
[7]James W.Cooper.C#设计模式[M].北京:科学出版社,2011.
[8]Gastón C.Hillar.C#并行编程高级教程:精通NET 4 Parallel Extensions[M].北京:清华大学出版社,2012.