目的:
本文目的为介绍创建数据引用的方法,请不要将本文例子作为产品使用,这里有一个性能的问题,该问题将在本文最后予以说明。
背景:
本文创建的这个例子,是读取使用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,并查看显示出的值列表。
之后,我们使用本文创建新的PI AF Data Reference (Array_show)显示一个单一值。
例如,Attribute2是一个基于PI Point Array Data Reference的PI AF attribute,下面是使用基于Array_show的Attribute3显示Attribute2中的第一个值:
过程:
下面是Array_show的制作过程。
打开MS VS 2012,并创建一个项目。需要选择”Class Library“, 这是创建.dll文件的要求。本文例子将使用C#代码。
项目创建好之后,请加入 “OSIsoft.AFSDK”函数库引用
准备:
创建.dll项目的GUID。一般在VS的“工具”菜单中均会有这个工具。
在项目中加入GUID,以及一些需要的头文件名。同时,该例子需要一个字符串类型的变量传递PI AF attribute的名字,以及一个整形变量传递值编号。
主要功能:
1. public override string ConfigString
熟悉PI AF Data Reference的朋友会注意到在“Setting"按钮下面,会有一串字符。这串字符就是用于将这个attribute的基本配置信息传递给 PI AF Server。如下面的PI Point Data Reference,其可以传递链接的PI Server的信息和点名传递给PI AF Server。
因此,对于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”按钮后,会有一个配置界面弹出:
因此,给一个新的Data Reference创建一个这样的界面,将使得以后使用更加友好和方便。
请右击该项目,加入windows form:
方便起见,这里仅创建以下的这个简单的编辑器作为例子,这个编辑器可以使用MS VS中的windows form工具制作完成:
完成设计后,下面的工作就是给这个编辑器定义功能。这里,我们将传递"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文件:
2. 注册这个.dll到PI AF Server上:
复制这个.dll文件的全路径,并使用"RegPlugIn.exe"进行注册:
现在,您可以使用这个新的Data Reference像本文中在“结果”部分一样。
注:
性能问题是由于所有的输出值将从PI Point Array Data Reference中来。因此,这将比直接从PI Point中来慢很多(Ling Fung Mok --- PI AF SDK Developer)