目的:

 

本文目的为介绍创建数据引用的方法,请不要将本文例子作为产品使用,这里有一个性能的问题,该问题将在本文最后予以说明。

 

背景:

 

本文创建的这个例子,是读取使用PI Point Array Data Reference创建的PI AF attribute中的单一值。PI Point Array Data Reference可以使一个PI AF attribute获得多个PI点的值,并以一个值列表的方式进行展示。然而,如果工作中对于这个列表中的某一个值感兴趣,目前没有方法可以直接将这个感兴趣的值使用另一个PI AF attribute在PI AF客端展示出来。因此,本文创建的这个例子,可以使用已存在的基于PI Point Array Data Reference的PI AF attribute的名字和单一值在值列表中的编号作为参数,使用另一个PI AF attribute展示出该值。

 

结果:

 

让我们先看一下使用本文例子的展示结果。

 

我们先创建一个基于PI Point Array Data Reference的PI AF attribute,并查看显示出的值列表。

 

8168.1.png

 

之后,我们使用本文创建新的PI AF Data Reference (Array_show)显示一个单一值。

 

例如,Attribute2是一个基于PI Point Array Data Reference的PI AF attribute,下面是使用基于Array_show的Attribute3显示Attribute2中的第一个值:

 

8420.2.png

 

过程:

 

下面是Array_show的制作过程。

 

打开MS VS 2012,并创建一个项目。需要选择”Class Library“, 这是创建.dll文件的要求。本文例子将使用C#代码。

 

4810.3.png

 

项目创建好之后,请加入 “OSIsoft.AFSDK”函数库引用

 

7802.4.png

 

准备:

 

创建.dll项目的GUID。一般在VS的“工具”菜单中均会有这个工具。

 

3107.5.png

 

在项目中加入GUID,以及一些需要的头文件名。同时,该例子需要一个字符串类型的变量传递PI AF attribute的名字,以及一个整形变量传递值编号。

 

2234.6.png

 

主要功能:

 

1. public override string ConfigString

 

熟悉PI AF Data Reference的朋友会注意到在“Setting"按钮下面,会有一串字符。这串字符就是用于将这个attribute的基本配置信息传递给 PI AF Server。如下面的PI Point Data Reference,其可以传递链接的PI Server的信息和点名传递给PI AF Server。

 

2705.7.png

 

因此,对于Array_show来说,有两个参数需要传递给PI AF Server --- 基于PI Point Array Data Reference的PI AF attribute的名字和值编号。

 

 

 
public override string ConfigString
{
    get
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("{0} = {1};", "Target Attribute",target_attribute_name);
        sb.AppendFormat("{0} = {1};", "Index", index);
        return sb.ToString();
    }
    set
    {
        var tokens = value.Split(';');
        foreach (var token in tokens)
        {
            var key = token.Split('=');
            switch (key[0])
            {
                case "Target Attribute":
                    target_attribute_name = key[1];
                    break;
                case "Index":
                    index = Convert.ToInt32(key[1]);
                    break;
            }
        }
        SaveConfigChanges();  // save the change to PI AF Server
 
    }
}

 

 

2. public override AFValue GetValue

 

此方法是给PI AF attribute传递值。本例中,基于Array_show的attribute需要获取另一个attribute中的一个值。因此我们需要使用一个额外的方法获取原始attribute,并传递一个AFAttributeList的类给GetValue方法。原始的attribute的名字是由上述的ConfigString提供的。

 

 

 
public override AFAttributeList GetInputs(object context)
{
    AFAttributeList attribute_list = new AFAttributeList();
    attribute_list.Add(this.GetAttribute(target_attribute_name));  // get the attribute name from the configstring
    return attribute_list;
}
 
public override AFValue GetValue(object context, object timeContext, AFAttributeList inputAttributes, AFValues inputValues)
{
    AFValue result = new AFValue();
    AFValue input = inputValues[0];
    if (input.IsGood)
    {
        result.Timestamp = input.Timestamp;
        Array values = input.Value as Array;
        result.Value = values.GetValue(index - 1); 
    }
    else
    {
        result.Status = AFValueStatus.Bad;
        result.Value = new Exception("Bad Value");
    }
    return result;
}

 

 

3. Support function:

 

PI AF Server需要知道AFDataReference class中的哪些方法被使用到这个项目中。因此,以下3个support function是非常重要的。

 

 

 
public override AFDataReferenceMethod SupportedMethods
{
    get
    {
        return AFDataReferenceMethod.GetValue | AFDataReferenceMethod.GetValues;  // 实际使用GetValue即可。这里列出了GetValues是用于显示如何支持多个function
    }
}
 
public override AFDataMethods SupportedDataMethods
{
    get
    {
        return this.DefaultSupportedDataMethods;
    }
}
 
public override AFDataReferenceContext SupportedContexts
{
    get
    {
        return AFDataReferenceContext.All;
    }
}

 4. 配置编辑器:

 

像PI Point Data Reference,当点击”Settings”按钮后,会有一个配置界面弹出:

 

8171.8.png

 

因此,给一个新的Data Reference创建一个这样的界面,将使得以后使用更加友好和方便。

 

请右击该项目,加入windows form:

 

1680.9.png

 

方便起见,这里仅创建以下的这个简单的编辑器作为例子,这个编辑器可以使用MS VS中的windows form工具制作完成:

 

2604.10.png

 

完成设计后,下面的工作就是给这个编辑器定义功能。这里,我们将传递"Attribute”文本框中的原始attribute的名字,以及“index"数字选择框中的数字作为值编号。

 

 

 
public partial class Array_showEditor : Form
 {
       Array_show _dr;
 
       public Array_showEditor(Array_show dr, bool IsreadOnly)
       {
           InitializeComponent();
           _dr = dr;
           textBox_Attribute.Text = dr.Get_Attribute_Name;
           numericUpDown_Index.Value= dr.Get_Index;
       }
 
       private void button_Cancel_Click(object sender, EventArgs e)
       {
           this.Close();
           this.Dispose();
       }
 
       private void button_OK_Click(object sender, EventArgs e)
       {
           _dr.Get_Attribute_Name = textBox_Attribute.Text;
           _dr.Get_Index = (int)numericUpDown_Index.Value;
           this.Close();
           this.Dispose();
       }
   }

 编辑器创建好之后,请返回项目代码,将这个编辑器加入。

 

 

 
public override Type EditorType
{
    get
    {
        return typeof(Array_showEditor);
    }
}

 这个方法是AFDataReference class中让PI AF Server知道不同的Data Reference将跳出不同的编辑器界面。

 

同时,我们需要另外两个方法来在两个.cs文件中传递”Attribute"和“index"中的值。

 

 

 
public string Get_Attribute_Name
{
    get
    {
        return target_attribute_name;
    }
    set
    {
        if (target_attribute_name != value)
        {
            target_attribute_name = value;
            SaveConfigChanges();
        }
    }
}
 
public int Get_Index
{
    get
    {
        return index;
    }
    set
    {
        if (value != index)
        {
            index = value;
            SaveConfigChanges();
        }
    }
}

 注册:

 

最后的一步是将我们创建好的项目注册到PI AF Server上:

 

1. 创建.dll文件:

 

2318.11.jpg

 

2. 注册这个.dll到PI AF Server上:

 

复制这个.dll文件的全路径,并使用"RegPlugIn.exe"进行注册:

 

7411.12.jpg

 

现在,您可以使用这个新的Data Reference像本文中在“结果”部分一样。

 

注:

 

性能问题是由于所有的输出值将从PI Point Array Data Reference中来。因此,这将比直接从PI Point中来慢很多(Ling Fung Mok --- PI AF SDK Developer)