C++ and PI - PI SDK - UpdateValues

Blog Post created by andreas on May 9, 2012

As a follow up to this post, today I will write a value with annotations to PI.


In order to do this, we need the usual preparation. In other words, I need to get my imports:

//need to import sdk  
#pragma warning( disable : 4786 4146 )    
#import "E:\PIPC\PISDK\PISDKCommon.dll"    no_namespace 
#import "E:\PIPC\PISDK\PITimeServer.dll"   no_namespace 
#import "E:\PIPC\PISDK\PISDK.dll"          rename("Connected", "PISDKConnected") no_namespace

and some pointers and strings:

/* PISDK */
IPISDKPtr       spPISDK = NULL;                /* the PISDK */
ServerPtr       spServer = NULL;               /* the server */
PIPointPtr      spPIPoint = NULL;              /* the pi point */
_bstr_t         bstrServer = "SCHREMMERAVMPI"; /* the pi servername*/
_bstr_t         bstrPointName = "MyLabTag";      /* the tagname */  

now let's start with the initialization:

// initialize the COM library

// Create an instance of the PISDK
// get the PI server 
spServer = spPISDK->GetServers()->GetItem(bstrServer);     
// get the PI point 
spPIPoint = spServer->PIPoints->GetItem(bstrPointName);       

to make my life easier I am going to use a Float32 tag, and I am assuming it does not have a bad value now. I get the snapshot:

// get the current value
_PIValuePtr _pv = spPIPoint->Data->GetSnapshot();

and now I need some annotations:

// the PI Annotations 
_PIAnnotationsPtr spPIAnns;
// a string annotation
// an integer annotation
// a float annotation

As usual we have to deal with VARIANTs:

// We need a variant to pass
_variant_t vAnns;
VariantInit (&vAnns);
// the type is VT_DISPATCH
V_VT (&vAnns) = VT_DISPATCH;
// assign the annotations to the variant
V_DISPATCH(&vAnns) = spPIAnns;

Now that there is a VARIANT that refers to my annotations. I am going to use UpdateValues to send my value to PI, and to pass the annotations I will need a named values collection, containing the VARIANT:

// named values :-)
_NamedValuesPtr spNVValAttr;
// add the annotations to the named values
spNVValAttr->Add("Annotations", &vAnns);

almost there now. The remaining part is as simple as creating my PIValues collection, adding my PIValue to it, and sending it to PI. Remember, I am assuming my tag is a Float32 and has no bad value :

// PI Values
_PIValuesPtr spPIValues;

// make the PI values writeable
// add a new value with current time, new float value and annotations
spPIValues->Add("*",_pv->Value.fltVal + 1,spNVValAttr);
// make the PI values readonly
// write the value to PI
HRESULT hr = spPIPoint->Data->UpdateValues(spPIValues, dmInsertDuplicates, NULL);

cleaning up: 

// we don't need the variant anymore
V_VT (&vAnns) = VT_EMPTY;

// Closes the COM library

and leaving:

if (hr < 0)         
     return hr;     
     return 0;  

 hope you had as much fun reading as I had writing !