Created
August 3, 2011 11:39
-
-
Save atimin/1122431 to your computer and use it in GitHub Desktop.
Simple OPC Client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////////////////////////// | |
// project: SimpleOPCClient | |
// version: 2 | |
// | |
// subject: this is a simple OPC Client that read the value of an item | |
// from an OPC server. | |
// | |
// file: SimpleOPCClient.cpp | |
// | |
// writer: Philippe GRAS - CERN / EP | |
// | |
//http://lhcb-online.web.cern.ch/lhcb-online/ecs/opcevaluation/opcclienttutorial/SimpleClient.html | |
#include <atlbase.h> | |
#include <objbase.h> | |
#include <iostream> | |
#include "opc.h" | |
#include "SimpleOPCClient.h" | |
#include "opc_i.c" | |
using namespace std; | |
#define OPC_SERVER_NAME L"OPC.Evaluation:HV supply.1" // e.g.: L"OPC.Evaluation:HV supply.1" | |
#define ITEM_ID L"cr02.ch00.V0" | |
#define VT VT_R4 | |
#define XVAL fltVal | |
//#define REMOTE_SERVER_NAME L"your_path" | |
////////////////////////////////////////////////////////////////////// | |
// Read the value of an item on an OPC server. | |
// | |
void main(void) | |
{ | |
IOPCServer* pIOPCServer = NULL; //pointer to IOPServer interface | |
IOPCItemMgt* pIOPCItemMgt = NULL; //pointer to IOPCItemMgt interface | |
OPCHANDLE hServerGroup; // server handle to the group | |
OPCHANDLE hServerItem; // server handle to the item | |
// have to be done before using microsoft COM library: | |
CoInitialize(NULL); | |
// Let's instantiante the IOPCServer interface and get a pointer of it: | |
pIOPCServer = InstantiateServer(OPC_SERVER_NAME); | |
// Add the OPC group the OPC server and get an handle to the IOPCItemMgt | |
//interface: | |
AddTheGroup(pIOPCServer, pIOPCItemMgt, hServerGroup); | |
// Add the OPC item | |
AddTheItem(pIOPCItemMgt, hServerItem); | |
//Read the value of the item from device: | |
VARIANT varValue; //to stor the read value | |
VariantInit(&varValue); | |
ReadItem(pIOPCItemMgt, hServerItem, varValue); | |
// print the read value: | |
cout << "Read value: " << varValue.XVAL << endl; | |
// Remove the OPC item: | |
RemoveItem(pIOPCItemMgt, hServerItem); | |
// Remove the OPC group: | |
RemoveGroup(pIOPCServer, hServerGroup); | |
// release the interface references: | |
pIOPCItemMgt->Release(); | |
pIOPCServer->Release(); | |
//close the COM library: | |
CoUninitialize(); | |
} | |
//////////////////////////////////////////////////////////////////// | |
// Instantiate the IOPCServer interface of the OPCServer | |
// having the name ServerName. Return a pointer to this interface | |
// | |
IOPCServer* InstantiateServer(wchar_t ServerName[]) | |
{ | |
CLSID CLSID_OPCServer; | |
HRESULT hr; | |
// get the CLSID from the OPC Server Name: | |
hr = CLSIDFromString(ServerName, &CLSID_OPCServer); | |
_ASSERT(!FAILED(hr)); | |
//queue of the class instances to create | |
LONG cmq = 1; // nbr of class instance to create. | |
MULTI_QI queue[1] = | |
{{&IID_IOPCServer, | |
NULL, | |
0}}; | |
//Server info: | |
//COSERVERINFO CoServerInfo = | |
//{ | |
// /*dwReserved1*/ 0, | |
// /*pwszName*/ REMOTE_SERVER_NAME, | |
// /*COAUTHINFO*/ NULL, | |
// /*dwReserved2*/ 0 | |
//}; | |
// create an instance of the IOPCServer | |
hr = CoCreateInstanceEx(CLSID_OPCServer, NULL, CLSCTX_SERVER, | |
/*&CoServerInfo*/NULL, cmq, queue); | |
_ASSERT(!hr); | |
// return a pointer to the IOPCServer interface: | |
return(IOPCServer*) queue[0].pItf; | |
} | |
///////////////////////////////////////////////////////////////////// | |
// Add group "Group1" to the Server whose IOPCServer interface | |
// is pointed by pIOPCServer. | |
// Returns a pointer to the IOPCItemMgt interface of the added group | |
// and a server opc handle to the added group. | |
// | |
void AddTheGroup(IOPCServer* pIOPCServer, IOPCItemMgt* &pIOPCItemMgt, | |
OPCHANDLE& hServerGroup) | |
{ | |
DWORD dwUpdateRate = 0; | |
OPCHANDLE hClientGroup = 0; | |
// Add an OPC group and get a pointer to the IUnknown I/F: | |
HRESULT hr = pIOPCServer->AddGroup(/*szName*/ L"Group1", | |
/*bActive*/ FALSE, | |
/*dwRequestedUpdateRate*/ dwUpdateRate, | |
/*hClientGroup*/ hClientGroup, | |
/*pTimeBias*/ 0, | |
/*pPercentDeadband*/ 0, | |
/*dwLCID*/0, | |
/*phServerGroup*/&hServerGroup, | |
&dwUpdateRate, | |
/*riid*/ IID_IOPCItemMgt, | |
/*ppUnk*/ (IUnknown**) &pIOPCItemMgt); | |
_ASSERT(!FAILED(hr)); | |
} | |
////////////////////////////////////////////////////////////////// | |
// Add the Item ITEM_ID to the group whose IOPCItemMgt interface | |
// is pointed by pIOPCItemMgt pointer. Return a server opc handle | |
// to the item. | |
void AddTheItem(IOPCItemMgt* pIOPCItemMgt, OPCHANDLE& hServerItem) | |
{ | |
HRESULT hr; | |
// Array of items to add: | |
OPCITEMDEF ItemArray[1] = | |
{{ | |
/*szAccessPath*/ L"", | |
/*szItemID*/ ITEM_ID, | |
/*bActive*/ FALSE, | |
/*hClient*/ 1, | |
/*dwBlobSize*/ 0, | |
/*pBlob*/ NULL, | |
/*vtRequestedDataType*/ VT, | |
/*wReserved*/0 | |
}}; | |
//Add Result: | |
OPCITEMRESULT* pAddResult=NULL; | |
HRESULT* pErrors = NULL; | |
// Add an Item to the previous Group: | |
hr = pIOPCItemMgt->AddItems(1, ItemArray, &pAddResult, &pErrors); | |
_ASSERT(!hr); | |
// Server handle for the added item: | |
hServerItem = pAddResult[0].hServer; | |
// release memory allocated by the server: | |
CoTaskMemFree(pAddResult->pBlob); | |
CoTaskMemFree(pAddResult); | |
pAddResult = NULL; | |
CoTaskMemFree(pErrors); | |
pErrors = NULL; | |
} | |
/////////////////////////////////////////////////////////////////////////////// | |
// Read from device the value of the item having the "hServerItem" server | |
// handle and belonging to the group whose one interface is pointed by | |
// pGroupIUnknown. The value is put in varValue. | |
// | |
void ReadItem(IUnknown* pGroupIUnknown, OPCHANDLE hServerItem, VARIANT& varValue) | |
{ | |
// value of the item: | |
OPCITEMSTATE* pValue = NULL; | |
//get a pointer to the IOPCSyncIOInterface: | |
IOPCSyncIO* pIOPCSyncIO; | |
pGroupIUnknown->QueryInterface(__uuidof(pIOPCSyncIO), (void**) &pIOPCSyncIO); | |
// read the item value from the device: | |
HRESULT* pErrors = NULL; //to store error code(s) | |
HRESULT hr = pIOPCSyncIO->Read(OPC_DS_DEVICE, 1, &hServerItem, &pValue, &pErrors); | |
_ASSERT(!hr); | |
_ASSERT(pValue!=NULL); | |
varValue = pValue[0].vDataValue; | |
//Release memeory allocated by the OPC server: | |
CoTaskMemFree(pErrors); | |
pErrors = NULL; | |
CoTaskMemFree(pValue); | |
pValue = NULL; | |
// release the reference to the IOPCSyncIO interface: | |
pIOPCSyncIO->Release(); | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
// Remove the item whose server handle is hServerItem from the group | |
// whose IOPCItemMgt interface is pointed by pIOPCItemMgt | |
// | |
void RemoveItem(IOPCItemMgt* pIOPCItemMgt, OPCHANDLE hServerItem) | |
{ | |
// server handle of items to remove: | |
OPCHANDLE hServerArray[1]; | |
hServerArray[0] = hServerItem; | |
//Remove the item: | |
HRESULT* pErrors; // to store error code(s) | |
HRESULT hr = pIOPCItemMgt->RemoveItems(1, hServerArray, &pErrors); | |
_ASSERT(!hr); | |
//release memory allocated by the server: | |
CoTaskMemFree(pErrors); | |
pErrors = NULL; | |
} | |
//////////////////////////////////////////////////////////////////////// | |
// Remove the Group whose server handle is hServerGroup from the server | |
// whose IOPCServer interface is pointed by pIOPCServer | |
// | |
void RemoveGroup (IOPCServer* pIOPCServer, OPCHANDLE hServerGroup) | |
{ | |
// Remove the group: | |
HRESULT hr = pIOPCServer->RemoveGroup(hServerGroup, FALSE); | |
_ASSERT(!hr); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////////////////////////// | |
// project: SimpleOPCClient | |
// version: 2 | |
// | |
// subject: this is a simple OPC Client that read the value of an item | |
// from an OPC server. | |
// | |
// file: SimpleOPCClient.h | |
// | |
// writer: Philippe GRAS - CERN / EP | |
// | |
#ifndef SIMPLE_OPC_CLIENT_H | |
#define SIMPLE_OPC_CLIENT_H | |
IOPCServer* InstantiateServer(wchar_t ServerName[]); | |
void AddTheGroup(IOPCServer* pIOPCServer, IOPCItemMgt* &pIOPCItemMgt, | |
OPCHANDLE& hServerGroup); | |
void AddTheItem(IOPCItemMgt* pIOPCItemMgt, OPCHANDLE& hServerItem); | |
void ReadItem(IUnknown* pGroupIUnknown, OPCHANDLE hServerItem, VARIANT& varValue); | |
void RemoveItem(IOPCItemMgt* pIOPCItemMgt, OPCHANDLE hServerItem); | |
void RemoveGroup (IOPCServer* pIOPCServer, OPCHANDLE hServerGroup); | |
#endif // SIMPLE_OPC_CLIENT_H not defined |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment