喬富強(qiáng),趙 旭
(天津中德職業(yè)技術(shù)學(xué)院 信息系,天津 300350)
在能源信息化集成過(guò)程中,環(huán)保局要求各熱電廠的鍋爐實(shí)時(shí)數(shù)據(jù)進(jìn)行上傳,企業(yè)內(nèi)部也需要通過(guò)瀏覽器實(shí)時(shí)監(jiān)控鍋爐數(shù)據(jù)。這些數(shù)據(jù)的傳輸從起點(diǎn)到終點(diǎn)要經(jīng)過(guò)現(xiàn)場(chǎng)工控機(jī)(配有OPC服務(wù)器)、OPC客戶端、UDP傳輸層和監(jiān)控主機(jī),其中OPC客戶端為分散于各處的生產(chǎn)數(shù)據(jù)與中央監(jiān)控搭建了橋梁。大部分熱電廠都通過(guò)配置OPC服務(wù)器,向外提供符合OPC標(biāo)準(zhǔn)的統(tǒng)一接口[1],但傳統(tǒng)的OPC客戶端都是基于一個(gè)客戶端訪問(wèn)一臺(tái)服務(wù)器開(kāi)發(fā)的[2-3]。為了適應(yīng)環(huán)保局對(duì)多個(gè)熱電廠數(shù)據(jù)的同時(shí)采集,本系統(tǒng)實(shí)現(xiàn)了單一客戶端對(duì)多服務(wù)器的連接。同時(shí)考慮到每個(gè)連接應(yīng)獨(dú)立工作,當(dāng)一個(gè)連接出現(xiàn)問(wèn)題,不影響其它服務(wù)器的訪問(wèn),采用了多線程模型解決這一問(wèn)題。另外,數(shù)據(jù)采集是長(zhǎng)期的工作,由于網(wǎng)絡(luò)環(huán)境的不穩(wěn)定性,客戶端與服務(wù)器的連接經(jīng)常斷開(kāi),因此,系統(tǒng)提供了自動(dòng)監(jiān)控連接狀態(tài),斷點(diǎn)續(xù)連的功能,減少了操作人員的負(fù)擔(dān)。
OPC(OLE for process control)是一個(gè)用于過(guò)程控制的技術(shù)標(biāo)準(zhǔn),它基于微軟的OLE(現(xiàn)在的Active X)、COM(部件對(duì)象模型)和DCOM(分布式部件對(duì)象模型)技術(shù),采用客戶/服務(wù)器模式,制定了關(guān)于數(shù)據(jù)采集、歷史趨勢(shì)以及事件報(bào)警等接口標(biāo)準(zhǔn)[4]。只要遵守這些標(biāo)準(zhǔn),在客戶機(jī)和服務(wù)器之間就可以交換數(shù)據(jù)。
OPC邏輯對(duì)象模型中包括3種對(duì)象:服務(wù)器對(duì) 象 (OPCServer)、 組 對(duì) 象 (OPCGroup) 和 項(xiàng) 對(duì) 象(OPCItem)。這3種對(duì)象層次不同,每種對(duì)象都包括一系列接口。如圖1所示,一個(gè)OPCItem對(duì)應(yīng)實(shí)際的硬件裝置上的某一個(gè)channel或port,它包括值(Value)、品質(zhì)(Quality)、時(shí)間戳(Time Stamp)3 個(gè)基本屬性;一個(gè)OPCGroup則包含了許多的OPCItem,同時(shí)也定義了這些OPCItem更新的時(shí)間、方式,并提供讀取OPCItem屬性的接口;而一個(gè)OPCServer則包含若干個(gè)OPCGroup,同時(shí)提供操作這些OPCGroup的接口[5]。OPC客戶端若要從服務(wù)器中采集數(shù)據(jù),首先應(yīng)得到服務(wù)器對(duì)象的引用,然后通過(guò)操作組對(duì)象的接口動(dòng)態(tài)創(chuàng)建組對(duì)象,最后通過(guò)組對(duì)象讀取項(xiàng)對(duì)象的屬性值。
圖1 OPC服務(wù)器結(jié)構(gòu)圖Fig.1 OPC server structure diagram
本系統(tǒng)以Visual Studio 2010為平臺(tái),應(yīng)用VB.Net語(yǔ)言開(kāi)發(fā),項(xiàng)目中引入了OPCAutomation.dll組件,其中封裝了客戶端與服務(wù)器交互的方法。
項(xiàng)目中建立了3個(gè)與功能相關(guān)的類,其中Opc-ClientOperator類主要表達(dá)了客戶端與服務(wù)器一對(duì)一的連接,并提供了采集數(shù)據(jù)方法;ThreadsOperator類封裝了OpcClientOperator類的對(duì)象數(shù)組,每個(gè)對(duì)象代表一個(gè)與服務(wù)器的連接,從而實(shí)現(xiàn)客戶端與多服務(wù)器的交互,這個(gè)類也定義了線程數(shù)組,它為每個(gè)連接啟動(dòng)一個(gè)線程,避免了多連接情況下的相互沖突;OpcClientObserver類提供了異常處理以及修復(fù)連接的方法,當(dāng)連接發(fā)生異常時(shí),調(diào)用這些方法實(shí)現(xiàn)斷點(diǎn)續(xù)連。這3個(gè)類的主要成員如圖2所示,詳細(xì)介紹這些類的實(shí)現(xiàn)細(xì)節(jié)。
圖2 OPC客戶端類視圖Fig.2 OPC client class view
OpcClientOperator對(duì)象可完成對(duì)一臺(tái)OPC服務(wù)器的數(shù)據(jù)采集,其工作過(guò)程由以下步驟組成:
步驟1調(diào)用ConnectRemoteServer函數(shù)連接到指定的服務(wù)器,該函數(shù)以服務(wù)器IP地址或主機(jī)名作為參數(shù),若連接成功,MyOpcServer變量保留服務(wù)器對(duì)象的引用,并用ServerState記錄服務(wù)器連通狀態(tài)(OPCServerState.OPCRunning),否則捕獲異常,提示錯(cuò)誤信息。
步驟2調(diào)用CreateGroup函數(shù)創(chuàng)建組對(duì)象,MyOpcGroup保存組對(duì)象的引用,當(dāng)成功創(chuàng)建了組對(duì)象,可添加即將被采集的項(xiàng)對(duì)象序列,其中組名稱及項(xiàng)變量名稱由項(xiàng)目的配置文件導(dǎo)入,關(guān)鍵語(yǔ)句如下:
步驟3調(diào)用SetGroupProperty函數(shù)設(shè)置組的屬性,主要包括下列內(nèi)容:
步驟4采集數(shù)據(jù),StartClientChannel是本類中的主要函數(shù),也是啟動(dòng)線程時(shí)的綁定函數(shù),該函數(shù)內(nèi)部首先執(zhí)行了以上3個(gè)過(guò)程,然后開(kāi)始從服務(wù)器采集數(shù)據(jù),而本類定義了3種客戶端與服務(wù)器的通信方式:
①同步方式MyOPCGroup_SyncRead
OPC服務(wù)器把項(xiàng)對(duì)象的值、品質(zhì)和時(shí)間戳作為函數(shù)的參數(shù)返回給客戶端,在結(jié)果被返回之前客戶端程序必須處于等待狀態(tài)。
②異步方式MyOPCGroup_AsyncRead
OPC服務(wù)器接到客戶端的請(qǐng)求后,幾乎立即將方法返回。OPC客戶端隨后可以進(jìn)行其他處理。當(dāng)完成數(shù)據(jù)訪問(wèn)時(shí),OPC服務(wù)器主動(dòng)觸發(fā)客戶端的異步訪問(wèn)完成事件,將數(shù)據(jù)訪問(wèn)結(jié)果傳送給OPC客戶端。OPC客戶端在事件處理過(guò)程中接收傳來(lái)的數(shù)據(jù)。
③訂閱方式MyOPCGroup_DataChange
服務(wù)器按一定的更新周期(UpdateRate)更新數(shù)據(jù)緩沖區(qū)的數(shù)值時(shí),如果發(fā)現(xiàn)數(shù)據(jù)有變化,就會(huì)觸發(fā)組對(duì)象的DataChange事件通知客戶端,而發(fā)生變化的數(shù)據(jù)作為事件處理函數(shù)的參數(shù)返回給客戶端。
步驟5啟動(dòng)定時(shí)器timer,定期監(jiān)測(cè)服務(wù)器連接狀態(tài) CheckServerState,若連接異常,則觸發(fā)OffLine事件通知OpcClientObserver來(lái)處理。
為解決斷點(diǎn)續(xù)連問(wèn)題,本系統(tǒng)采用了事件和委托機(jī)制[6],事件是對(duì)象發(fā)送的消息,以通知操作的發(fā)生。操作可能是由用戶交互引起的,也可能是由某些其他的程序邏輯觸發(fā)的。引發(fā)事件的對(duì)象稱為事件發(fā)送方。捕獲事件并對(duì)其作出響應(yīng)的對(duì)象叫做事件接收方。這種機(jī)制源自于Observer(觀察者)模式,事件的發(fā)送方是被觀察的主體,事件的接收方是觀察者,當(dāng)主體發(fā)生變化時(shí),觀察者被自動(dòng)告知更新[7]。在事件通信中,事件發(fā)送方不知道哪個(gè)對(duì)象或方法將接收并處理該事件。因此在發(fā)送和接收方之間必須存在一個(gè)媒介 (類似函數(shù)指針)。.NET Framework定義了一個(gè)特殊的類型–委托類型(Delegate),該類型提供函數(shù)指針的功能。委托是可保存對(duì)方法的引用的類,與其他的類不同,委托類具有一個(gè)簽名,并且它只能引用與其簽名匹配的方法。這樣委托就等效于一個(gè)類型安全的函數(shù)指針或一個(gè)回調(diào)。
根據(jù)事件和委托機(jī)制,首先在OpcClientOperator類中聲明了一個(gè)委托類型OffLineEventHandler,以及依托于該委托的事件OffLine,當(dāng)觸發(fā)事件時(shí),由該委托所指向的函數(shù)來(lái)處理。
其中參數(shù)sender表示引發(fā)事件的對(duì)象,而參數(shù)e中記錄了事件接收方感興趣的信息,比如服務(wù)器的連接狀態(tài)ServerState和地址等,接收方通過(guò)這些值判斷異常的類型以及重新連接的地址。
接下來(lái)在OpcClientObserver類中定義了3個(gè)函數(shù),其中RepairConnection是符合OffLineEventHandler委托類型的事件處理函數(shù),它先調(diào)用ExceptionHandle來(lái)判斷連接異常的類型,若為物理性斷網(wǎng),則通知用戶手動(dòng)操作,否則嘗試重新建立與Opc服務(wù)器的連接,若一次連接不成功,則等待若干秒后重新嘗試,反復(fù)幾次,其中等待時(shí)間和最大重連次數(shù)由用戶在ThreadWaitingTime和MaxConnCount成員變量中的賦值所決定。若連接成功則調(diào)用ThreadHandle恢復(fù)數(shù)據(jù)采集的線程;若達(dá)到最大重連次數(shù)仍未成功,則提示用戶手動(dòng)操作,并結(jié)束數(shù)據(jù)采集線程。
.NET Framework允許用戶將事件與處理程序動(dòng)態(tài)綁定,當(dāng)主程序啟動(dòng)后,分別為每個(gè)OpcClient-Operator對(duì)象綁定事件處理函數(shù)。
這樣,在對(duì)數(shù)據(jù)采集線程實(shí)施定時(shí)監(jiān)控過(guò)程中,如果發(fā)現(xiàn)某個(gè)連接斷開(kāi),則引發(fā)OffLine事件,根據(jù)委托,操作系統(tǒng)自動(dòng)調(diào)用事件處理函數(shù)重新建立連接。
該類封裝了OpcClientOperator類的對(duì)象數(shù)組ClientOp,和.Net線程數(shù)組 Threads。DoClientJob 是客戶端工作的啟動(dòng)函數(shù),它首先初始化ClientOp數(shù)組的每個(gè)對(duì)象,為每個(gè)對(duì)象設(shè)置連接服務(wù)器的地址,組信息及項(xiàng)信息,然后將這些對(duì)象的Start-ClientChannel函數(shù)分別綁定到Threads數(shù)組的每個(gè)線程對(duì)象,作為工作線程的函數(shù),最后依次啟動(dòng)這些線程。
每個(gè)線程獨(dú)立處理客戶端與一臺(tái)服務(wù)器的連接及數(shù)據(jù)采集工作,當(dāng)一個(gè)連接異常時(shí),不影響其它線程的工作[8]。
雖然本系統(tǒng)實(shí)現(xiàn)了斷點(diǎn)續(xù)連的功能,但在某些情況下,比如網(wǎng)絡(luò)物理性斷開(kāi),或重新連接數(shù)次達(dá)到上限都不成功,還是需要人員手工操作,基于這些考量,本類也提供了動(dòng)態(tài)管理線程的方法。ResetOneThread函數(shù)用于重置某個(gè)指定的線程,當(dāng)某個(gè)線程異常而中止工作時(shí),可以調(diào)用該函數(shù)重新啟動(dòng)這個(gè)線程。當(dāng)客戶端不再需要訪問(wèn)某個(gè)服務(wù)器時(shí),可以調(diào)用StopOneThread函數(shù)停止某個(gè)指定的線程,它們以服務(wù)器地址和線程對(duì)象的下標(biāo)為參數(shù)。OPC客戶端完整的工作流程如圖3所示。
圖3 OPC客戶端工作流程圖Fig.3 OPC client working flow chart
系統(tǒng)測(cè)試工作在一個(gè)真實(shí)的環(huán)境下進(jìn)行,應(yīng)用該OPC客戶端采集天津市濱能集團(tuán)5組鍋爐的參數(shù),首先在各自的工控機(jī)上搭建OPC服務(wù)器環(huán)境,應(yīng)用的服務(wù)軟件是西門子的WinCC。然后設(shè)置組和項(xiàng)的參數(shù),并將這些參數(shù)導(dǎo)出到配置文件供OPC客戶端使用,這些參數(shù)包括OPC服務(wù)器地址、類型、組名、項(xiàng)變量名以及相關(guān)注釋。最后在一個(gè)遠(yuǎn)程主機(jī)上啟動(dòng)客戶端,開(kāi)始訪問(wèn)這5個(gè)OPC服務(wù)器。
配置客戶端的操作如圖4所示,列表框中導(dǎo)入了所有服務(wù)器的地址,當(dāng)選擇某個(gè)地址時(shí),文本框中會(huì)顯示該服務(wù)器類型和已添加的組。當(dāng)點(diǎn)擊“導(dǎo)入?yún)?shù)項(xiàng)”時(shí),系統(tǒng)會(huì)讀取配置文件中的項(xiàng)變量信息,包括序號(hào)、變量名和標(biāo)題。啟動(dòng)客戶端以后開(kāi)始采集所有服務(wù)器的項(xiàng)變量數(shù)據(jù)。
圖4 配置OPC客戶端Fig.4 Configure OPC client
在列表中選擇某個(gè)服務(wù)器地址,可以查看從該服務(wù)器上接收的項(xiàng)變量的值、質(zhì)量和時(shí)間戳信息。通過(guò)“重置線程”和“終止線程”,用戶可以手動(dòng)的重啟或停止當(dāng)前線程,而不影響另外4個(gè)線程的采集工作。當(dāng)重啟某個(gè)OPC服務(wù)器時(shí),連接發(fā)生異常,此時(shí)斷點(diǎn)續(xù)連機(jī)制生效,經(jīng)過(guò)數(shù)次的重連、等待,連接恢復(fù),照常接收數(shù)據(jù)。
本系統(tǒng)通過(guò)OPC技術(shù),采用面向?qū)ο蠓庋b的思想,充分利用VB.NET的多線程機(jī)制進(jìn)行多服務(wù)器的連接,動(dòng)態(tài)地管理線程,提高了系統(tǒng)的穩(wěn)定性,完成了企業(yè)鍋爐數(shù)據(jù)的采集與發(fā)送的開(kāi)發(fā)。系統(tǒng)提供了便利的人機(jī)界面,方便了使用者的操作,在實(shí)際應(yīng)用過(guò)程中達(dá)到了預(yù)期的效果。
[1]蔣近,段斌.基于OPC技術(shù)的監(jiān)控主站實(shí)時(shí)數(shù)據(jù)傳輸[J].電力自動(dòng)化設(shè)備,2008,28(9):97-100.
[2]黃錦花,常喜茂.基于快速開(kāi)發(fā)工具的OPC客戶端的開(kāi)發(fā)與實(shí)現(xiàn)[J].化工自動(dòng)化及儀表,2013,40(7):893-897.
[3]蘇磊,李茜,湯偉.OPC數(shù)據(jù)訪問(wèn)客戶端的研究與實(shí)現(xiàn)[J].計(jì)算機(jī)工程,2010,36(11):80-82.
[4]陳燁,倉(cāng)小金,彭蓬,袁小平.基于OPC中問(wèn)件技術(shù)的網(wǎng)絡(luò)控制系統(tǒng)[J].電力自動(dòng)化設(shè)備,2011,31(1):100-104.
[5]望荊沙.基于OPC DA 3.0的OPC服務(wù)器與客戶端的研究與實(shí)現(xiàn)[D].西安:西安電子科技大學(xué),2012.
[6]任玉輝,張新海.動(dòng)態(tài)連接多服務(wù)器的OPC客戶端在燒結(jié)控制系統(tǒng)中的應(yīng)用[J].燒結(jié)球團(tuán),2011,36(1):19-24.
[7]James W.Cooper.C#設(shè)計(jì)模式[M].北京:科學(xué)出版社,2011.
[8]Gastón C.Hillar.C#并行編程高級(jí)教程:精通NET 4 Parallel Extensions[M].北京:清華大學(xué)出版社,2012.