昨天又有人問(wèn)我 OPC Client 編寫,實(shí)際是他們不了解OPC 客戶端的工作原理,要想寫客戶端程序,必須知道OPC對(duì)象, OPC邏輯對(duì)象模型包括3類對(duì)象:OPC server對(duì)象、OPC group對(duì)象、OPC item對(duì)象,每類對(duì)象都包括一系列接口。 OPC Server對(duì)象 主要功能為:1、創(chuàng)建和管理OPC Group對(duì)象; 2、管理服務(wù)器內(nèi)部的狀態(tài)信息; OPC Group對(duì)象 主要功能為:1、管理OPC Group對(duì)象的內(nèi)部狀態(tài)信息; 2、創(chuàng)建和管理Items對(duì)象。 3、OPC服務(wù)器內(nèi)部的實(shí)時(shí)數(shù)據(jù)存取服務(wù)(同步與異步方式)。 OPC組中有以下幾個(gè)主要屬性:Name :組的名字 ;Active:組的激活狀態(tài)標(biāo)志 ;Update Rate OPC:服務(wù)器向客戶程序提交數(shù)據(jù)變化的刷新速率;Percent Dead band:數(shù)據(jù)死區(qū),即能引起數(shù)據(jù)變化的最小數(shù)值百分比。 OPC ITEM 是非COM對(duì)象,在OPC標(biāo)準(zhǔn)中用來(lái)描述實(shí)時(shí)數(shù)據(jù),是客戶端不可見(jiàn)的對(duì)象。代表了與服務(wù)器中的數(shù)據(jù)的連接,它并不是數(shù)據(jù)源,而僅僅是與數(shù)據(jù)源的連接。每個(gè)項(xiàng)都有以下主要屬性: Active項(xiàng)的激活狀態(tài)、Value項(xiàng)的數(shù)值、類型為VARIANT、Quality項(xiàng)的品質(zhì),代表數(shù)值的可信度,類型為SHORT、TimeStamp時(shí)間戳,代表數(shù)據(jù)的存取時(shí)間。 你不管用什么開發(fā)語(yǔ)言只要了解上面幾個(gè)對(duì)象,就會(huì)寫程序了 下面舉個(gè)VC的例子 HRESULT r1; CLSID clsid; LONG TimeBias = 0; FLOAT PercentDeadband = 0.0; DWORD RevisedUpdateRate; LPWSTR ErrorStr; char str[100]; CString szErrorText; m_pItemResult = NULL; 客戶端程序必須對(duì)DCOM進(jìn)行初始化設(shè)置,以保證OPC服務(wù)器端回調(diào)函數(shù)不會(huì)被堵塞。 r1 = CoInitialize(NULL); if (r1 != S_OK) { if (r1 == S_FALSE) { MessageBox("COM Library already initialized", "Error CoInitialize()", MB_OK+MB_ICONEXCLAMATION); } else { szErrorText.Format("Initialisation of COM Library failed. Error Code= %4x", r1); MessageBox(szErrorText,"Error CoInitialize()", MB_OK+MB_ICONERROR); SendMessage(WM_CLOSE); return; } } 通過(guò)OPC服務(wù)器的ProgID查詢注冊(cè)表中相關(guān)CLSID。每個(gè)COM服務(wù)器都有一個(gè)字符串型的ProgID,通過(guò)ProgID可以得到全球惟一的CLSID,使用CLSIDFromProgID( )函數(shù)實(shí)現(xiàn)ProgID到CLSID的轉(zhuǎn)換。 r1 = CLSIDFromProgID(L"OPC.SimaticNET", &clsid); if (r1 != S_OK) { MessageBox("Retrival of CLSID failed", "Error CLSIDFromProgID()", MB_OK+MB_ICONERROR); CoUninitialize(); SendMessage(WM_CLOSE); return; } 連接OPC服務(wù)器,查詢對(duì)象的IID_IOPCServer接口。在連接OPC服務(wù)器前,OPC客戶端需要事先指定計(jì)算機(jī)名和OPC數(shù)據(jù)訪問(wèn)服務(wù)器名,建立連接后,創(chuàng)建OPC組并添加OPC數(shù)據(jù)項(xiàng)。 r1 = CoCreateInstance (clsid, NULL, CLSCTX_LOCAL_SERVER ,IID_IOPCServer, (void**)&m_pIOPCServer); if (r1 != S_OK) { MessageBox("Creation of IOPCServer-Object failed", "Error CoCreateInstance()", MB_OK+MB_ICONERROR); m_pIOPCServer = NULL; CoUninitialize(); SendMessage(WM_CLOSE); return; } 創(chuàng)建OPC組,查詢IOPCItemMgt接口。IOPCServer接口的AddGroup()方法可以創(chuàng)建一個(gè)有指定名稱和屬性的OPC組。 r1=m_pIOPCServer->AddGroup(L"grp1", // [in] group name TRUE, // [in] active 500, // [in] request this Update Rate from Server 1, // [in] Client handle &TimeBias, // [in] no time interval to system UTC time &PercentDeadband, // [in] no deadband, so all data changes are reported LOCALE_ID, // [in] Server uses English language for text values &m_GrpSrvHandle, // [out] Server handle to identify this group in later calls &RevisedUpdateRate, // [out] the answer form the Server to the requested update rate IID_IOPCItemMgt, // [in] requested interface type of the group object (LPUNKNOWN*)&m_pIOPCItemMgt); // [out] pointer to the requested interface if (r1 == OPC_S_UNSUPPORTEDRATE) { szErrorText.Format ("Revised Update Rate %d is different from Requested Update Rate 500",RevisedUpdateRate ); AfxMessageBox(szErrorText); } else if (FAILED(r1)){ MessageBox("Can't add Group to Server!", "Error AddGroup()", MB_OK+MB_ICONERROR); m_pIOPCServer->Release(); m_pIOPCServer = NULL; CoUninitialize(); SendMessage(WM_CLOSE); return; } 添加OPC數(shù)據(jù)項(xiàng)。使用IOPCItemMgt接口的AddItem()方法可以添加具有特殊屬性的指定數(shù)量的數(shù)據(jù)項(xiàng)。 // define an item table with one item as in-paramter for AddItem m_Items[0].szAccessPath = L""; m_Items[0].szItemID = szItemID; // 影響數(shù)據(jù)類型 m_Items[0].bActive = TRUE; m_Items[0].hClient = 1; m_Items[0].dwBlobSize = 0; m_Items[0].pBlob = NULL; m_Items[0].vtRequestedDataType = 0; // defined by the item itself r1 = m_pIOPCItemMgt->AddItems(1, // [in] add one item m_Items, // [in] see above &m_pItemResult, // [out] array with additional information about the item &m_pErrors); // [out] tells which of the items was successfully added. // For any item which failed it provides a reason |
|
來(lái)自: ThinkTank_引擎 > 《OPC》