9 Replies Latest reply on Oct 28, 2011 3:37 PM by andreas

    aPiPoint.Data.InterpolatedValues(t1,t2,ptcount,f1,f2,asynch) returns inconsistent results for different point counts

    gregorvilkner

      Hi there,

       

      we're running into some weird behavior of the InterpolatedValues function - using the function to retrieve points to toss into a custom windows.forms.chart control.

       

      Depending on how many samples we request (this example is data between 2/1 and 5/1, requesting between 100 and 2000 samples, note: the pi archive has a good 35k of happy points available for this time span) our charts start to flat-line at various points (image attached, point count is top right above the charts). We've used the function without the last three arguments and also tried to use the asynchronous way, simply using a Thread.Sleep and not going overboard with event handling yet.

       

      Any explaination or pointers to proper usage of the asynch usage would be greatly appreciated.

       

      Kind regards,

       

      Gregor

       

      code sample:

       

                       

       
        PISDKCommon.PIAsynchStatus mPIAsync = new PISDKCommon.PIAsynchStatus();
      
                          PIValues aPiPointValues = aPiPoint.Data.InterpolatedValues(dateStartDate.Value, dateEndDate.Value, int.Parse(txtPointCount.Text), "", FilteredViewConstants.fvRemoveFiltered, mPIAsync);
      
                          int counter = 0;
      
                          while (mPIAsync.ProgressPercent < 100)
      
                          {
      
                              System.Threading.Thread.Sleep(1);
      
                              counter++;
      
                          }
      
                          for (int piCounter = 1; piCounter <= aPiPointValues.Count; piCounter++)
      
                          {
      
                              PIValue aPiValue = aPiPointValues[piCounter];
      
                              PIValue aPiValue2 = ((PIValues)mPIAsync.Result)[piCounter];
      
                              if (aPiValue.IsGood())
      
                              {
      
                                  chartKpiHistory.Series[0].Points.AddXY(aPiValue.TimeStamp.LocalDate, aPiValue.Value);
      
                                  chartKpiHistory.Series[2].Points.AddXY(aPiValue2.TimeStamp.LocalDate, aPiValue.Value);
      
                              }
      
                          }
      

       

        • Re: aPiPoint.Data.InterpolatedValues(t1,t2,ptcount,f1,f2,asynch) returns inconsistent results for different point counts
          Ahmad Fattahi

          Here is an important question: does every single case translate into the same number of interpolated values? In other words, does the method return the exact same number of interpolated values before flatlining or that also changes from case to case?

            • Re: aPiPoint.Data.InterpolatedValues(t1,t2,ptcount,f1,f2,asynch) returns inconsistent results for different point counts
              gregorvilkner

              very good. yes - the results for a given ptCount are always the same. was wondering about that. i have this little "refresh" button that basically goes and gets the numbers for the set point count "again" and yes, the results are identical.

               

              also, i have two sets of results that i plot (they're identical. on top of each other) - aPiValue and aPiValue2, one of which is the asynch.result object. are those the same? what's the preferred method of usage here? i'm afraid this is poorly documented in the sdk help files.

               

              thanks for the fast response. hope to get this straightened out tomorrow. love that function - it's just that it's no good if it doesn't work reliably ;)

               

              any advise?

               

              kind regards,

               

              Gregor

                • Re: aPiPoint.Data.InterpolatedValues(t1,t2,ptcount,f1,f2,asynch) returns inconsistent results for different point counts
                  andreas

                  Gregor, first of all - for trending you might want to take a look into plotvalues.

                   

                  The purpose of the async call is to allow you to continue in your application after requuesting data from the PI Server. You could use this as well to send multiple async calls to the PI Server taking advantage of the multithreaded architecture of the PI Server and reducing the impact of network latency. In your case you simply wait until the call is finished so there is no difference between async and sync calling. One more point is that not all calls that expose the async parameter are really implemented asynchronous.
                  In any case the results of the calls should be identical - it is just that the sync call stops execution of your application unitl it has the data to present while the async call allows you to continue and you need to check when it has all the data.
                  To do some further research - what is the frequency of the raw data for yor tags?

                    • Re: aPiPoint.Data.InterpolatedValues(t1,t2,ptcount,f1,f2,asynch) returns inconsistent results for different point counts
                      andreas

                      o.k. some more thoughts on your code. You are not using sync calls at all. Here is a little sample for async:

                       
                                  long lStart, lStop;
                                  lStart = DateTime.Now.Ticks;
                      
                                  PISDKCommon.PIAsynchStatus[] mPIAsync = new PISDKCommon.PIAsynchStatus[mPoints.Length];
                                  System.Threading.WaitHandle[] mPISyncHndl = new System.Threading.AutoResetEvent[mPoints.Length];
                      
                                  // Innitialize the Async status and the waithandle
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      mPIAsync[ i ] = new PISDKCommon.PIAsynchStatus();
                                      mPISyncHndl[ i ] = new System.Threading.AutoResetEvent(false);
                                  }
                      
                                  // ask for data
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      mPIValues[ i ] = mPIPoints[ i ].Data.InterpolatedValues(mStartTime, 
                                                                                          mEndTime, 
                                                                                          500,
                                                                                          "",
                                                                                          PISDK.FilteredViewConstants.fvShowFilteredState,
                                                                                          mPIAsync[ i ]);
                                  }
                      
                                  // prepare the waithandle
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      PISDKCommon.IPIAsynchStatus2 asynch2 = (PISDKCommon.IPIAsynchStatus2)mPIAsync[ i ];
                                      mPISyncHndl[ i ].SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle((IntPtr)asynch2.CallCompleteEvent, false);
                                  }
                      
                                  // wait for data
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      mPISyncHndl[ i ].WaitOne();
                                  }
                      
                                  lStop = DateTime.Now.Ticks;
                                  textBox1.Text = (lStop - lStart).ToString("#,###");
                      
                                  // plot the data
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      if ((mPIAsync[ i ].Status & PISDKCommon.CallStatusConstants.csComplete)
                                          == PISDKCommon.CallStatusConstants.csComplete)
                                      {
                                          mCharts[ i ].Series.Clear();
                                          mCharts[ i ].Series.Add(mPoints[ i ]);
                                          mCharts[ i ].Series[mPoints[ i ]].ChartType =
                                              System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
                                          foreach (PISDK.PIValue mPV in mPIValues[ i ])
                                          {
                                              mCharts[ i ].Series[mPoints[ i ]].Points.AddXY(mPV.TimeStamp.LocalDate, mPV.Value);
                                          }
                                      }
                                  }
                      

                       
                      the same in sync:

                       
                                  long lStart, lStop;
                                  lStart = DateTime.Now.Ticks;
                      
                                  // ask for data
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      mPIValues[ i ] = mPIPoints[ i ].Data.InterpolatedValues(mStartTime,
                                                                                          mEndTime,
                                                                                          500,
                                                                                          "",
                                                                                          PISDK.FilteredViewConstants.fvShowFilteredState,
                                                                                          null);
                                  }
                      
                                  lStop = DateTime.Now.Ticks;
                                  textBox2.Text = (lStop - lStart).ToString("#,###");
                      
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      mCharts[ i ].Series.Clear();
                                      mCharts[ i ].Series.Add(mPoints[ i ]);
                                      mCharts[ i ].Series[mPoints[ i ]].ChartType =
                                          System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
                                      foreach (PISDK.PIValue mPV in mPIValues[ i ])
                                      {
                                          mCharts[ i ].Series[mPoints[ i ]].Points.AddXY(mPV.TimeStamp.LocalDate, mPV.Value);
                                      }
                                  }
                      

                       but I would suggest a sync plotvalues:

                       
                                  long lStart, lStop;
                                  lStart = DateTime.Now.Ticks;
                      
                                  // ask for data
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      mPIValues[ i ] = mPIPoints[ i ].Data.PlotValues(mStartTime,
                                                                                  mEndTime,
                                                                                  100);
                                  }
                      
                                  lStop = DateTime.Now.Ticks;
                                  textBox4.Text = (lStop - lStart).ToString("#,###");
                      
                                  for (int i = 0; i < mPoints.Length; i++)
                                  {
                                      mCharts[ i ].Series.Clear();
                                      mCharts[ i ].Series.Add(mPoints[ i ]);
                                      mCharts[ i ].Series[mPoints[ i ]].ChartType =
                                          System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
                                      foreach (PISDK.PIValue mPV in mPIValues[ i ])
                                      {
                                          mCharts[ i ].Series[mPoints[ i ]].Points.AddXY(mPV.TimeStamp.LocalDate, mPV.Value);
                                      }
                                  }
                      

                      Why? First of all the sync is much easier and with I think for a trending application is just fine. But more important is the plotvalues call. You noticed that I request 100 intervals? In fact that might return as well 500 values, but the real point here is that it allows you to draw a better representation of the data.

                       

                      Lets think of that - you are trending 5 days for a pipoint that has a 1s peak with interpolated values of 10 minutes (= ~700 values) - most likely your interpolation will miss that peak. By using plotvalues you will not miss that peak.

                       

                      PI SDK Help

                      The PlotValues method is designed to return a set of values over a time period that will produce the most accurate plot while minimizing the amount of data returned. The caller specifies a time range and a number of intervals. For each interval, the data available is examined and significant values are returned. Each interval can produce up to 5 values if they are unique, the value at the beginning of the interval, the value at the end of the interval, the highest value, the lowest value and at most one exceptional point (digital state)

                       

                      And as you can see the plotvalues is even faster.

                       

                      2818.PlotValues.jpg