7 Replies Latest reply on Jul 15, 2014 9:41 AM by Rhys Kirk

    Is it possible to create a test/ demo PIPoint which changes its value in less than 50ms?

    dstorey

      We want to test that we can rapidly read values from the PIServer quickly and so want to create a test PIPoint which changes value every 40ms for example :-)

       

       

       

      Thanks for your help,

       

      Dom

        • Re: Is it possible to create a test/ demo PIPoint which changes its value in less than 50ms?
          Rick Davin

          Yes.  The PI server supports sub-seconds in multiples of 1/65536 of a second, or approximately 0.0000152587890625 seconds.  However, many interfaces only support whole second timestamps, or what I like to think of as only where sub-seconds is exactly equal to 0.0.  With your own code, you may populate values to your test point.

            • Re: Is it possible to create a test/ demo PIPoint which changes its value in less than 50ms?
              dstorey

              Thanks for the fast reply Rick :-) Can you create this out of the box with the PI SDK Utility or can you provide me with a snippet of code to achieve this?

               

              Thanks again,

               

              Dom

                • Re: Is it possible to create a test/ demo PIPoint which changes its value in less than 50ms?
                  Rick Davin

                  Any particular language?  C#, VB.NET, VBA, or other?  Preferably either C# or VB.NET.

                   

                  Also do you want to populate one value at a time (slow) or bulk values (faster).

                    • Re: Is it possible to create a test/ demo PIPoint which changes its value in less than 50ms?
                      Rick Davin

                      This code has not been tested:

                       

                       

                       
                              // assuming input tag is a Float32
                              // actually values saved in archive depend upon tag's compression specs.
                              private static void PopulateSubseconds(PIPoint tag, PITime startTime, PITime endTime)
                              {
                                  PITime timestamp = startTime;
                                  Single value = 0.0f;
                                  Single offset = 1.0f;
                                  const double PISubSecond = 1.0 / 65536.0;
                      
                                  while (timestamp.UTCSeconds <= endTime.UTCSeconds)
                                  {
                                      // make-up a value that should pass tag's compression specs.
                                      // here I simply increment by 1 until I hit a limit, and then 
                                      // I begin decrementing by 1.
                                      value += offset;
                                      if (value >= 10000.0f)
                                          offset = -1.0f;
                                      else if (value <= 0.0f)
                                          offset = 1.0f;
                      
                                      // update value slowly one at a time
                                      tag.Data.UpdateValue(value, timestamp, DataMergeConstants.dmReplaceDuplicates);
                      
                                      timestamp.UTCSeconds += PISubSecond;
                                  }
                              }
                      
                              // assuming input tag is a Float32
                              // actually values saved in archive depend upon tag's compression specs.
                              private static void BulkPopulateSubseconds(PIPoint tag, PITime startTime, PITime endTime)
                              {
                                  PITime timestamp = startTime;
                                  Single value = 0.0f;
                                  Single offset = 1.0f;
                                  const double PISubSecond = 1.0 / 65536.0;
                      
                                  const int BulkSize = 1000;
                                  PIValues values = new PIValues();
                      
                                  while (timestamp.UTCSeconds <= endTime.UTCSeconds)
                                  {
                                      // make-up a value that should pass tag's compression specs.
                                      // here I simply increment by 1 until I hit a limit, and then 
                                      // I begin decrementing by 1.
                                      value += offset;
                                      if (value >= 10000.0f)
                                          offset = -1.0f;
                                      else if (value <= 0.0f)
                                          offset = 1.0f;
                      
                                      // add to values collection.
                                      values.Add(timestamp, value, null);
                      
                                      // periodically send over a bulk of values to be updated.
                                      if (values.Count >= BulkSize)
                                      {
                                          // Warning: has no exception checking!
                                          tag.Data.UpdateValues(values, DataMergeConstants.dmReplaceDuplicates);
                                          values = new PIValues();
                                      }
                      
                                      timestamp.UTCSeconds += PISubSecond;
                                  }
                      
                                  // in case we have any lingering values that haven't been flushed.
                                  if (values.Count > 0)
                                  {
                                      // Warning: has no exception checking!
                                      tag.Data.UpdateValues(values, DataMergeConstants.dmReplaceDuplicates);
                                  }
                      
                              }