andreas

The IDataProvider3

Blog Post created by andreas Employee on Nov 1, 2011

Have you ever thought about an IDataProvider3 Add In that exposes more than just a single trace? In this blog post we will fill some example code into the Add-in to help you achieve this.

 

First we start using the AddInPB_IDP3_CS template:

 

20111031_5F00_01.png

 

Note that I am using Visual Studio 2010 and set the .NET Framework 2.0.

 

As a good practice let's rename the menu item. We open IDP3Shell.cs and expand the IDataProvider3_configuration_methods region. We locate PBObjLib.IDataProvider3.GetMenuItem and change the string to something meaningful:

 
string PBObjLib.IDataProvider3.GetMenuItem()
{
    return "MyMultiTrace";
}

Now as we want to get multiple traces we need to add them to the cols collection in bool PBObjLib.IDataProvider3.ShowColumnConfiguration:

 
bool PBObjLib.IDataProvider3.ShowColumnConfiguration(ref PBObjLib.Columns cols, PBObjLib.DataPoint dp)
{
    cols.Add(this.dataSetName + ".RandomData");
    cols.Add(this.dataSetName + ".SinusData");
    return true;
}

Let's collapse the IDataProvider3_configuration_methods region and expand the IDataProvider3_optional_methods region. We are going to add a check on the two columns here as well:

 
bool PBObjLib.IDataProvider3.IsColumnValid(PBObjLib.DataPoint dp)
{
    if (dp == null) 
        return false;
    if (String.Compare(dp.ColumnName, "RandomData", true) == 0) 
        return true;
    if (String.Compare(dp.ColumnName, "SinusData", true) == 0) 
        return true; 
    else return false; 
}

We take care of the configuration later and focus on the data now. Let us collapse the IDataProvider3_optional_methods region and expand the IDataProvider3_data_methods region.

 

To tell PI ProcessBook some necessary information we need to visit PBObjLib.IDataProvider3.GetColumnAttributes. According to the data we are going to change it to:

 
// Set type to Float32
type.Value = PISDK.PointTypeConstants.pttypFloat32;
 
// Check external data provider to determine what the attributes should be
// for the shell dataset, using constants
if (String.Compare(dp.ColumnName, "RandomData", true) == 0)
{
    zero.Value = 3.0;
    span.Value = 0.3;
}
 
if (String.Compare(dp.ColumnName, "SinusData", true) == 0)
{
    zero.Value = -1.0;
    span.Value = 2.0;
}

Keeping it simple we return some random data and a sine wave. So let's go to PBObjLib.IDataProvider3.GetData and do some checks:

 
// Limit the amount of values to 100
if (maxvalues > 100)
    maxvalues = 100;

// Limit the amount of values to 1 value per second
if (maxvalues > (endtime - starttime))
    maxvalues = (endtime - starttime);

 then we add a random and a double:

 
Random random = new Random();
double num = random.Next(100) / 1000.0;

and we extend the for loop:

 
// for the random column
if (String.Compare(dp.ColumnName, "RandomData", true) == 0)
{
    num = 3.1415 +  0.001 * random.Next(100);
}

// for the sinus column
if (String.Compare(dp.ColumnName, "SinusData", true) == 0)
{
    num = Math.Sin(4 * 3.1415 * i / maxvalues);
}
pivalues.Add(timePT, num, attrs);

Now - to debug that thing we need to set the path to PI ProcessBook by a right click on the project:

 

20111031_5F00_02.png

 

Ready to hit F5 and build a trend!

 

20111031_5F00_03.png

 

While this works fine on a trend - a value symbol will always show only the first trace. So let us add a Windows Form to choose what trace we want to show. Two CheckBoxes and two buttons should be enough:

 

20111031_5F00_04.png

 

Let us define some variables for later usage:

 
// the columns
public  PBObjLib.Columns mCols { get; set; }
// the dataset name
public  String mDataSetName { get; set; }
// the application object
public PBObjLib.Application mApp { get; set; }

When activating the form we update the text on the checkboxes

 
DS_random.Text = mDataSetName + ".RandomData";
DS_sinus.Text = mDataSetName + ".SinusData";

and also check what datasets we already use

 
if (mApp.ActiveDisplay.SelectedSymbols.Count > 0)
{
    // get the active symbol
    PBObjLib.Symbol mSymbol = mApp.ActiveDisplay.SelectedSymbols.Item(1);
    // iterate through all tags
    for (int i = 1; i <= mSymbol.PtCount; i++)
    {
        if (String.Compare(mSymbol.GetTagName(i), DS_random.Text, true) == 0)
        {
            DS_random.Enabled = false;
        }
        if (String.Compare(mSymbol.GetTagName(i), DS_sinus.Text, true) == 0)
        {
            DS_sinus.Enabled = false;
        }
    }
}

This is necessary as the column collection only contains the selected column when opened from an existing trend definition.

 

Now we have to fill the ok and the cancel button:

 
private void btnOK_Click(object sender, EventArgs e)
{
    // here we add the columns to the data set
    if (DS_random.Checked)
    {
        mCols.Add(mDataSetName + ".RandomData");
    }
    // here we add the columns to the data set
    if (DS_sinus.Checked)
    {
        mCols.Add(mDataSetName + ".SinusData");
    }
    this.Close();
}

private void btnCancel_Click(object sender, EventArgs e)
{
    this.Close();
}

To make use of this - lets go back to PBObjLib.IDataProvider3.ShowColumnConfiguration and use the form:

 
bool PBObjLib.IDataProvider3.ShowColumnConfiguration(ref PBObjLib.Columns cols, PBObjLib.DataPoint dp)
{
    // This is the configuration form. It is used to choose the columns
    AS_IDP3_MT.ConfigDS MyForm = new AS_IDP3_MT.ConfigDS();
    MyForm.mCols = cols;
    MyForm.mApp = this.app;
    MyForm.mDataSetName = this.dataSetName;
    MyForm.ShowDialog();
    cols = MyForm.mCols;
    return true;
}

Time to hit F5 again:

 

 20111031_5F00_05.png

 

And we can select the two different datasets in our Add-In!

Attachments

Outcomes