12 Replies Latest reply on Jun 20, 2018 11:00 PM by John Messinger

    What is the AF SDK equivalent for PI API Snapshot functions


      I am quite new to the AF-SDK, and I have few questions I would very much like to be clarified of.

      First, I would like to know ,what are the AF-SDK options for getting a continuous flow of data from pi-archive server through the events/notifications mechanism-

      To be more precise, I would like to understand:

      What is the AF SDK equivalent for the PI API snapshot functions: pisn_evmestablish() and pisn_evmexceptions()?  Is it the AFDataPipe class?


      Concerning the AFDataPipe class, as described in the OsiSoft Tech Support documentation: 

      “ There are two ways to get the data change events:

      a) direct GetUpdateEvents method to get events;

      b) through IObserver of AFDataPipeEvent. The IObserver pattern provides significant performance improvement over direct GetUpdateEvents method for high throughput scenario.

      Application will have to implement the IObserver and register the IObserver with the data pipe via the Subscribe(IObserver<AFDataPipeEvent> ) method.”


      What I am not clear about is: What exactly is the difference between AFDataPipeEvent()  vs GetObserverEvents() methods?


      Also, I see this class have the properties: AFDataPipeType.Snapshot and AFDataPipeType.TimeSeries.

      What is the difference between these two properties?





        • Re: What is the AF SDK equivalent for PI API Snapshot functions
          John Messinger

          Hi Noga Avr,


          The AFDataPipe and PIDataPipe classes will give you the same basic functionality as the PI-API pisn_evmestablish() and pisn_evmexceptions() functions. As you have already noted, there are two different methods of retrieving data pipe events - a direct method using GetUpdateEvents, and an IObserver pattern based method. Which you choose to use would depend on a couple of factors, and throughput performance requirements of your application will be one of those. The simplest method is using the GetUpdateEvents() method. Using the IObserver pattern is a little more complex, but there are a few examples of its usage here in the forums.


          AFDataPipeEvent is a class, not a method, so there is a world of difference between this and the GetObserverEvents() method. This method is used to trigger a retrieval of AFDataPipeEvents from the data pipe to the registered IObserver when using the IObserver pattern.


          As to the difference between the AFDataPipeType.Snapshot and AFDataPipeType.TimeSeries enumerations, I would refer you to the description of AFDataPipeType. In short, the first generates snapshot change events only, and the latter generates change events for both snapshots and non-current values (out of order data).

          2 of 2 people found this helpful
            • Re: What is the AF SDK equivalent for PI API Snapshot functions

              Hi John,

              Concerning my question on What exactly is the difference between AFDataPipeEvent()  vs GetObserverEvents() methods, I got this question wrong, what I meant to ask is:

              What exactly is the difference between  GotUpdateEvents() vs GetObserverEvents() methods?

                • Re: What is the AF SDK equivalent for PI API Snapshot functions
                  John Messinger

                  Hi Noga,


                  The main difference between these two methods is that GetUpdateEvents() is used without an IObserver, whereas GetObserverEvents() is used with an IObserver. As mentioned earlier, I would choose the IObserver pattern for applications that require better throughput performance.


                  Note that the .NET IObserver and IObservable interfaces are typically used to implement push based subscriptions using the GoF Observer pattern. I did read somewhere that there is a limitation in the PI system that does not fully support push based subscriptions in the IObserver implementation of data pipes, but I can't quite seem to find that reference now.

                    • Re: What is the AF SDK equivalent for PI API Snapshot functions
                      Eugene Lee

                      John is right. The PI Data Archive has no mechanisms to push events in the PI Update Manager automatically to clients. So with both methods, you still have to do polling.

                        • Re: What is the AF SDK equivalent for PI API Snapshot functions

                          Hi Eugene,

                          Can you please clarify to me what do you mean when you say "you still have to do polling"?

                          Isn't the purpose of the AfDataPipe class is to prevent polling and instead register to events?

                          As I understand, the OnNext(T) method of the .NETFramework's System.IObserver<T> interface, is the one to provide the observer with new data, as suggested from the code example snapped here:

                          1.   /// <summary> 
                          2.     /// This class receives data from a PI Data Pipe 
                          3.     /// </summary> 
                          4.     public class PIConsoleDataReceiver : IObserver<AFDataPipeEvent> 
                          5.     { 
                          7.         private AFDataPipeType _dataPipeType; 
                          9.         public PIConsoleDataReceiver(AFDataPipeType afDataPipeType) 
                          10.         { 
                          11.             _dataPipeType = afDataPipeType; 
                          12.         } 
                          14.         /// <summary> 
                          15.         /// Provides the observer with new data. 
                          16.         /// </summary> 
                          17.         /// <param name="value"></param> 
                          18.         public void OnNext(AFDataPipeEvent value) 
                          19.         { 
                          20.            Console.WriteLine("PIDataPipe event - {4} - Tag Name: {0}, Action Type: {1}, Value {2}, TimeStamp: {3}", value.Value.PIPoint.Name, value.Action.ToString(), value.Value.Value, value.Value.Timestamp.ToString(), _dataPipeType); 
                          21.         } 
                          23.         /// <summary> 
                          24.         /// An error has occured 
                          25.         /// </summary> 
                          26.         /// <param name="error"></param> 
                          27.         public void OnError(Exception error) 
                          28.         { 
                          29.             Console.WriteLine("Provider has sent an error"); 
                          30.             Console.WriteLine(error.Message); 
                          31.             Console.WriteLine(error.StackTrace); 
                          32.         } 
                          34.         /// <summary> 
                          35.         /// Notifies the observer that the provider has finished sending push-based notifications. 
                          36.         /// </summary> 
                          37.         public void OnCompleted() 
                          38.         { 
                          39.             Console.WriteLine("Provider has terminated sending data"); 
                          40.         } 
                          41.     } 
                  • Re: What is the AF SDK equivalent for PI API Snapshot functions

                    Hi Noga,


                    A good explanation is already provided here so I just wanted to add a resource on how to implement AFDatapipe. Perhaps a sample code can illustrate the difference in your confusion.

                    This PDF attached to PI Dev Club Webinar Series: AF SDK AMA (Ask me Anything) provides insights into using various AFSDK ideas.

                    For example, a sample code is provided on page 15 as:


                    Uonng the PIDataPipe

                    IList<PIPoint> pointList = GetPointList();
                    IObserver<AFDataPipeEvent> observer = GetObserver();
                    using(PIDataPipe dataPipe = new PIDataPipe(AFDataPipeType.TimeSeries))
                              bool hasMoreEvents;
                              AFErrors<PIPoint> errors = dataPipe.GetObserverEvents(
                                   maxEventCountPerServer: 50000,
                                   hasMoreEvents: out hasMoreEvents);
                              if (errors != null)
                              if (!hasMoreEvents)


                    I hope this helps!