Skip navigation
All Places > PI Developers Club > Blog > Authors xwang

PI Developers Club

4 Posts authored by: xwang Employee

目的:

 

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

 

背景:

 

本文创建的这个例子,是读取使用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)

xwang

Create your own Data Reference

Posted by xwang Employee Sep 1, 2014

Purpose:

 

The aim of this post is to introduce the method on Data Reference creation, please do not use it as a product, as there is the performance issue, which will be explained at the end of this post.

 

 

 

Background:

 

The example I used is to create a Data Reference to read the single value from one existed PI AF Attribute which with PI Point Array Data Reference.  As we know, PI Point Array Data Reference could let the PI AF attribute to get all values from many PI points with one timestamp into one value list.  However, if I am interested in one single value in this value list, it seems no way to get that value out from this attribute to show on PI System Explore via another PI AF attribute directly.  Therefore, I create this Data Reference, passing the existed attribute’s name and the index of the value in the value list as the parameter to fetch this single value, and show it on another attribute.

 

 

 

Rusult:

 

Let us see what the result is for this Data Reference at first.

 

We could set an attribute to use PI Point Array Data Reference (PI PA DR) to show a value list for different PI Point.

 

0844.1.png

 

After that, it will be very easy to use Array_show Data Reference (AS DR) to show a single value from that list by index.

 

For example, I wish to show the first value of “Attribute2”.  It will be clear that the value is shown as Attribute3’s value.

 

4667.2.png

 

 

 

Procedures:

 

Now, let me introduct how to do this Data Reference.

 

Open MS VS 2012, and create a new project.  It will be “Class Library”, as the .dll file is needed.  I use C# code to do this example.

 

7824.3.png

 

After the project created, please add “OSIsoft.AFSDK” as the new reference for this project.

 

6366.4.png

 

 

 

Preparations:

 

The GUID is necessary for the .dll project.  Therefore, please go to create a GUID.  It will be under “TOOLS” menu of VS.

 

3276.5.png

 

Add the GUID and some namespace in this project.  Moreover, please remember to inherit the AFDataReference class, as the main functions to do this project is from this class.

 

We also need to initialize a string type parameter to store the name of the PI AF attribute with PI PA DR, and the integer type parameter to store the index number.

 

4265.6.png

 

 

 

Key functions:

 

The following is the functions for this project.

 

1. public override string ConfigString

 

If familiar with any PI AF Data Reference (PI Point Data Reference for example), there will be a string under “Setting” button.  This string is configuration string, used to transfer some basic information to PI AF Server.  For PI Point Data Reference following, it will provide PI Server name and PI point name to PI AF attribute.

 

4812.7.png

 

Therefore, for AS DR, I decide to transfer 2 information to PI AF Server --- the "attribute name" which PI AF attribute will be with PI PA DR and the "index number" which is to index one single value in the value list.

 

 

 
        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

 

This is the main function to pass the value to one PI AF attribute.  In this project, my original value is from another PI AF attribute with PI PA DR.  Therefore, it is necessary to include another function to pass the original PI AF attribute name to GetValue function.  The name of the original PI AF attribute will be from the ConfigString function (the previous function).

 

 

 
        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 needs to know which functions in AFDataReference class will be support for this project.  Therefore, the following 3 support function is very important for this project:

 

 

 
        public override AFDataReferenceMethod SupportedMethods
        {
            get
            {
                return AFDataReferenceMethod.GetValue | AFDataReferenceMethod.GetValues;  // Actually, only GetValue is enough for this project.  This is just to show how to support many functions inherit from AFDataReference class
            }
        }
   
        public override AFDataMethods SupportedDataMethods
        {
            get
            {
                return this.DefaultSupportedDataMethods;
            }
        }

        public override AFDataReferenceContext SupportedContexts
        {
            get
            {
                return AFDataReferenceContext.All;
            }
        }

 4. Editor:

 

Like PI Point Data Reference, after click “Settings” button, there will be a friendly editor to help us make the configuration string.  For example, the following is PI Point Data Reference's Editor:

 

5228.8.png

 

Therefore, to create an editor should be better for this project.

 

Please right click the project, and add a windows form to this project:

 

7674.9.png

 

To easy show, I just create a very simple editor like following, it should be easy to create by VS windows form tools:

 

5684.10.png

 

Then, I used the following code to define the function of this editor.  The function is very easy that “Attribute” field will pass the original PI PA DR attribute’s name, and the index will pass the index number.

 

 

 
 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();
        }
    }

 After finish the editor, we will back the project code to make some functions and let the editor work.  The most important function should be:

 

 

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

This function is inherited from AFDataReference class to let PI AF Server know the “Setting” button will invoke our new editor for our new Data Reference.

 

We also need 2 functions to transfer the value in “Attribute” field and “index” field between our 2 .cs files.

 

 

 
        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();
                }
            }
        }

 

 

Registration:

 

The last step is to create this .dll file and register it in to PI AF Server.

 

1. Create .dll file:

 

"Build" this project, and you could see the .dll location in "Output" window:

 

0317.11.jpg

 

2. Register this .dll file to PI AF Server:

 

Copy the full path of this .dll file, and use "RegPlugIn.exe" to register this .dll file to PI AF Server:

 

1323.12.jpg

 

Now, you could use this new Data Reference for your PI AF attribute as the "Result" part of this post.

 

 

 

Notes:

 

The performance issue is that all the out value will be from the value list made by PI Point Array Data Reference.  Therefore, it will be slower than read it from the PI point directly (From Ling Fung Mok --- PI AF SDK Developer).

介绍:

 

PI Web Services 已经发布了较长的时间。 这种数据传输的方法可以向所有支持web services的平台发布数据。PI Web Services 丰富了PI系统数据传输的类型, 并使得跨平台的PI数据传输变得简单方便。PI Web Services可与PI Server和PI AF Server链接并协同工作。李捍永,OSIsoft COE 工程师已经写过一篇博客,关于PI Web Services如何与PI AF Server协同工作。这篇博客将使用一些C#程序的例子介绍PI Web Services与PI Server工作的基本方法。在这篇博客中,您将看到PI Web Services如何从PI Server中获取数据,及如何向PI Server写入数据。

 

首先,PI Web Service 可以通过 “Add Service Reference” 添加到一个新建的项目中。

1.jpg

在点击“Add Service Reference”后, 请输入PI Web Services安装后的URL  (详情请见PI Web Services的安装手册).  注意:请在“Namespace”处填写在本项目中,PI Web Services所使用的名字。

2.jpg

当上述的配置完成后,您可以开始在您的项目中使用PI Web Services了。您可以参考下面的例子:

 

 

 

GetSnapshot from PI server:

PIWebService.PITimeSeriesClient client = new PIWebService.PITimeSeriesClient();    // 创建一个PI Web Services的链接

string[] path = new string[1];

path[0] = @"pi:\\WIN-01ARJPPGTEJ\SINUSOID";  //  PI Web Services可使用批次的概念获取数据

                                                                                             这意味着您可以使用一个数组储存一系列PI点的路径,并获取这些PI点的快照值,而仅仅与PI Server进行一次通信

PIWebService.TimeSeries[] values = client.GetPISnapshotData(path);

foreach (PIWebService.TimedValue value in values[0].TimedValues)

Console.WriteLine("{0} --- {1}", value.Value, value.Time.ToLocalTime());

Console.Read();

 

GetPIarchiveData from PI Server:

 

与GetSnapshot类似, GetPIarchiveData可以使用一次通信获取多个PI点的归档值。

 

PIWebService.PITimeSeriesClient client = new PIWebService.PITimeSeriesClient();
PIWebService.TimeRange timerange = new PIWebService.TimeRange();
timerange.Start = "*-1h";
timerange.End = "*";

 

PIWebService.PIArcDataRequest[] list = new PIWebService.PIArcDataRequest[1];   // 创建一个PIArcDataRequest 数组来储存所有的条件信息。请看下面条件信息的详情:

 

PIWebService.PIArcDataRequest single = new PIWebService.PIArcDataRequest(); //  创建一个PIArcDataRequest实例将来会将这个实例添加到上面的数组中

 

PIWebService.PIArcManner manner = new PIWebService.PIArcManner();  //  PIArcManner 包含很多获取数据的过滤条件条件:

 

manner.Boundaries = PIWebService.PIArcMannerBoundaries.Inside;
manner.RetrievalType = PIWebService.PIArcMannerRetrievalType.Compressed;
manner.Updates = false;

 

single.TimeRange = timerange;

 

single.PIArcManner = manner;    //  将所有的 PIArcManner中的过滤条件添加到PIArcDataRequest实例中

 

single.Path = @"pi:\\WIN-01ARJPPGTEJ\cdt158";

 

list[0] = new PIWebService.PIArcDataRequest();

 

list[0] = single;    //  为了测试的简单明了,本次只创建一个PIArcDataRequest实例

 

PIWebService.TimeSeries[] values = client.GetPIArchiveData(list);
foreach (PIWebService.TimedValue value in values[0].TimedValues)
Console.WriteLine("{0} --- {1}", value.Value, value.Time.ToLocalTime());
Console.Read();

 

 

 

GetPISummaryData (Total) from PI server:

 

GetPISummaryData包括Average, Count, Maximum, Minimum, PStdDev, Range, StdDev and Total等功能.  这些公能实现的代码类似。因此,本次使用Total 作程序示例。

 

GetPISummaryData功能与GetPIarchiveData类似,都使用数组来存储条件信息。不同在于使用不同的类。

 

PIWebService.PITimeSeriesClient client = new PIWebService.PITimeSeriesClient();

PIWebService.PISummaryDataRequest[] list = new PIWebService.PISummaryDataRequest[1];  //  类名变为PISummaryDataRequest.

PIWebService.PISummaryDataRequest request = new PIWebService.PISummaryDataRequest();

PIWebService.PISummaryManner manner = new PIWebService.PISummaryManner();

 

manner.SummaryValue = PIWebService.PISummaryMannerSummaryValue.Total;  //  这里可以选择不同的统计方法,如Average, Count, Maximum, Minimum, PStdDev, Range, StdDev and Total.

manner.WeightType = PIWebService.PISummaryMannerWeightType.EventWeighted;
manner.Updates = false;

manner.Intervals = 1;   //  Intervals是一个非常重要得条件。

 

                                             它将觉得在给定时间段内有多少的返回值。

 

                                              如,如果Intervals = 10, 并且给定的时间段是*-1h”到 “*”, 之后,如果统计方法选择了Average, Maximum and Minimum,那么将有10个值返回。

 

                                             意思是,将给定的时间段做i10等分,每个返回值对应每一等分时间段的统计值。

// manner.TimeStep = "20m";  //  TimeStep是PI Web Services 2012的新参数。

 

                                                           这个参数可以代替Intervals来分割给定的时间段。

 

                                                           如,如果TimeStep = "40m", 并且给定时间段是"*-1h" 到“*"。

 

                                                           那么返回值只有一个,因为1小时内只有一个”40分钟“。

 

                                                           TimeStep的读取优先级高于Intervals。

 

                                                          意思是如果这两个参数都被配置,那么Intervals的配置将被忽视。

PIWebService.TimeRange timerange = new PIWebService.TimeRange();
timerange.Start = "*-1h";
timerange.End = "*";

request.Path = @"pi:\\WIN-01ARJPPGTEJ\cdt158";
request.TimeRange = timerange;
request.PISummaryManner = manner;

list[0] = new PIWebService.PISummaryDataRequest();
list[0] = request;

PIWebService.TimeSeries[] values = client.GetPISummaryData(list);
foreach (PIWebService.TimedValue value in values[0].TimedValues)
Console.WriteLine("{0} --- {1}", value.Value, value.Time.ToLocalTime());
Console.Read();

 

 

 

InsertPIData:

 

这是向PI Server写数据的方法。注意:如果使用这个方法,运行方法的账户必须有目的PI服务器的”写“权限。

 

如果上面的代码已经理解,那么下面的代码将会非常简单。

 

PI Web Services 2012 可以使用本地的 PI Buffer Subsystem来向PI Server或PI集群缓存并发送数据。详情请见PI Web Services 2012用户手册。

 

PIWebService.PITimeSeriesClient client = new PIWebService.PITimeSeriesClient();
PIWebService.TimeSeries[] input = new PIWebService.TimeSeries[1];
PIWebService.TimeSeries time_series = new PIWebService.TimeSeries();
PIWebService.TimedValue my_value = new PIWebService.TimedValue();

my_value.Path = @"pi:\\WIN-01ARJPPGTEJ\cdt158";
my_value.Time = DateTime.Now;
my_value.DataType = "dateTime";
my_value.Value = "300.00";
my_value.Status = null;

time_series.TimedValues = new PIWebServices.TimedValue[1];
time_series.TimedValues[0] = my_value;
input[0] = time_series;

PIWebService.TimeSeries my_result = new PIWebService.TimeSeries();
my_result = client.InsertPIData(input, PIWebService.InsertPIDataDuplicateSwitch.InsertDuplicate)

 

 

 

 

 

 

 

 

 

小结:

 

PI Web Services是在网络编程中非常有用的技术,可以跨越不同的平台,如.net 和 JAVA平台。PI Web Services在安全性和可管理性上优于PI API,因此,它将会在JAVA平台上代替PI API。

Edit: Please note, that PI Web Services is announced to become deprecated some time in future. Not only for this reason, we recommend to decide in favor of PI Web API for recent development projects. Even we consider below content kind of outdated, we've decided for keeping this post.

 

Introduction:

 

PI Web Services has been out for several years.  This PI Data Access package could work with any platform which allows web services technology as the adding reference.  PI Web Services riches PI Data Access type , and makes it easier to transfer PI data across different platforms.  This blog post will use some examples (C# code) to introduce the functions in PI Web Services working with PI Server.  There has been another blog made by Hanyong Lee to introduce how PI Web Services works with PI AF Server.  You can read that post here.  After reading this blog post, you should expect to be able to use PI Web Services to fetch values from the PI Server and insert values to a PI Point.

 

Firstly, PI Web Service could be added from “Add Service Reference” after creating a new project.

1.jpg

After clicking “Add Service Reference”, enter the URL which is the address after installing PI Web Services package (Please see the installation menu).  Note that Namespace field will determine the PI Web Services name in this project.

2.jpg

When the above configuration is complete you can start coding. Below you can find the examples:

 

GetSnapshot from PI server:

PIWebService.PITimeSeriesClient client = new PIWebService.PITimeSeriesClient();    // create PI Web Services connection

string[] path = new string[1];

path[0] = @"pi:\\WIN-01ARJPPGTEJ\SINUSOID";  //  PI Web Services will use batch concept to get the data.

                                                                                             This means you could use an array to store all the pathes of PI points which you need, and you will get all snapshot data of them just consuming one PI server connecting call.

PIWebService.TimeSeries[] values = client.GetPISnapshotData(path);

foreach (PIWebService.TimedValue value in values[0].TimedValues)

Console.WriteLine("{0} --- {1}", value.Value, value.Time.ToLocalTime());

Console.Read();

 

 

GetPIarchiveData from PI Server:

Same as GetSnapshot function, GetPIarchiveData could fetch the data for many PI points also.

PIWebService.PITimeSeriesClient client = new PIWebService.PITimeSeriesClient();
PIWebService.TimeRange timerange = new PIWebService.TimeRange();
timerange.Start = "*-1h";
timerange.End = "*";

 

PIWebService.PIArcDataRequest[] list = new PIWebService.PIArcDataRequest[1];   // create a PIArcDataRequest array to store all requests information. The details of the requests, please see the following.

 

PIWebService.PIArcDataRequest single = new PIWebService.PIArcDataRequest(); //  create one PIArcDataRequest for the PIArcDataRequest array above.

 

PIWebService.PIArcManner manner = new PIWebService.PIArcManner();  //  PIArcManner includes the following contains, which will be the conditions for fetching data:

 

manner.Boundaries = PIWebService.PIArcMannerBoundaries.Inside;
manner.RetrievalType = PIWebService.PIArcMannerRetrievalType.Compressed;
manner.Updates = false;

 

single.TimeRange = timerange;

 

single.PIArcManner = manner;    //  Put all the PIArcManner contains into the request list.

 

single.Path = @"pi:\\WIN-01ARJPPGTEJ\cdt158";

 

list[0] = new PIWebService.PIArcDataRequest();

 

list[0] = single;    //  To be easy for testing, this time, just one request in the request array

 

PIWebService.TimeSeries[] values = client.GetPIArchiveData(list);
foreach (PIWebService.TimedValue value in values[0].TimedValues)
Console.WriteLine("{0} --- {1}", value.Value, value.Time.ToLocalTime());
Console.Read();

 

 

GetPISummaryData (Total) from PI server:

GetPISummaryData includes Average, Count, Maximum, Minimum, PStdDev, Range, StdDev and Total function.  They will have the similar code.  Therefore, Total function will be as the example to show how they work.

GetPISummaryData function is similar with GetPIarchiveData to use an array to store the request conditions also.  The difference is the class name.

 

PIWebService.PITimeSeriesClient client = new PIWebService.PITimeSeriesClient();

PIWebService.PISummaryDataRequest[] list = new PIWebService.PISummaryDataRequest[1];  //  The class name of the request is changed to PISummaryDataRequest.

PIWebService.PISummaryDataRequest request = new PIWebService.PISummaryDataRequest();

PIWebService.PISummaryManner manner = new PIWebService.PISummaryManner();

manner.SummaryValue = PIWebService.PISummaryMannerSummaryValue.Total;  //  Here is the way to choose all different function, such as Average, Count, Maximum, Minimum, PStdDev, Range, StdDev and Total.

manner.WeightType = PIWebService.PISummaryMannerWeightType.EventWeighted;
manner.Updates = false;

manner.Intervals = 1;   //  Intervals is very important condition in the request list.

                                             This will determine how many results should be returned during the given time range.

                                              For example, if Intervals = 10, and the time range is from “*-1h” to “*”, there will be 10 results returned when using Average, Maximum and Minimum methods.

                                             This means the given time range will be average split into small time range, and the results will reflect the value of chosen method in these small time range.

// manner.TimeStep = "20m";  //  TimeStep is the new function for PI Web Services 2012.

                                                           This parameter could replace Interval to seperate the time range.

                                                           For example, it TimeStep = "40m", and the time range is from "*-1h" to "*".

                                                           There will be just 1 result returned, as there is only one "40 minutes" during 1 hour.

                                                           The priority of TimeStep is higher than Intervals.

                                                          This means if both of these 2 parameters are configued, Intervals will not work.

PIWebService.TimeRange timerange = new PIWebService.TimeRange();
timerange.Start = "*-1h";
timerange.End = "*";

request.Path = @"pi:\\WIN-01ARJPPGTEJ\cdt158";
request.TimeRange = timerange;
request.PISummaryManner = manner;

list[0] = new PIWebService.PISummaryDataRequest();
list[0] = request;

PIWebService.TimeSeries[] values = client.GetPISummaryData(list);
foreach (PIWebService.TimedValue value in values[0].TimedValues)
Console.WriteLine("{0} --- {1}", value.Value, value.Time.ToLocalTime());
Console.Read();

 

 

InsertPIData:

This is the method to write data into PI server.  Note: the account to run this method should have the write access to  the target PI Server.

The following code should be easy to understand is you understand the code above.

PI Web Services 2012 could use local PI Buffer Subsystem to buffer and fan data to PI Server or PI Collective.  The details, please see PI Web Services 2012 User Menu.

PIWebService.PITimeSeriesClient client = new PIWebService.PITimeSeriesClient();
PIWebService.TimeSeries[] input = new PIWebService.TimeSeries[1];
PIWebService.TimeSeries time_series = new PIWebService.TimeSeries();
PIWebService.TimedValue my_value = new PIWebService.TimedValue();

my_value.Path = @"pi:\\WIN-01ARJPPGTEJ\cdt158";
my_value.Time = DateTime.Now;
my_value.DataType = "dateTime";
my_value.Value = "300.00";
my_value.Status = null;

time_series.TimedValues = new PIWebServices.TimedValue[1];
time_series.TimedValues[0] = my_value;
input[0] = time_series;

PIWebService.TimeSeries my_result = new PIWebService.TimeSeries();
my_result = client.InsertPIData(input, PIWebService.InsertPIDataDuplicateSwitch.InsertDuplicate);

 

 

Conclusion:

PI Web Services is a very useful technology for network programming, and could work with many different platforms, like .net and JAVA.  PI Web Services is more security and managable than PI API.  Therefore, it could be the good technology to replace PI API on JAVA platform.

Filter Blog

By date: By tag: