5 Replies Latest reply on Feb 17, 2017 2:03 PM by gregor

    PIPoint isResolved when using FindPIPoint

    langfom

      Hi There

      I have written an application to insert data into PI from two sources.

      The first source provides the Tag name so I am doing the following to retrieve the PI Point: -

      PIPoint p = PIPoint.FindPIPoint(server, "my tag name");
      if (p.IsResolved) {
           ...... process data ......
      }
      
      

       

      When using this method, isResolved returns true, so I can process my data into the PI Point.

       

      My second source provides the PI ID so I am doing the following to retrieve the PI Point: -

      PIPoint p = PIPoint.FindPIPoint(server, 1);
      if (p.IsResolved) {
           ........ process data  ......
      }
      
      

       

      I have discovered during testing that the property isResolved doesn't return "true" when using the method

      PIPoint.findPIPoint(PIServer, Int32)

       

      Is this the intended behavior or a bug.  The documentation for the isResolved property of the PIPoint class says: -

       

      IsResolved

      This property is used to determine if the PIPoint's Name has been resolved.

      Should my understanding of this be: -

      1. when finding the point by the point's name, yes the name supplied into the method has been resolved to a PI Point.

      2. when using a PI ID to find the point, a name is not being used to resolve the point so there is no need to set the isResolved property.

      OR

      Irrespective of which method is used, if a PI Point is returned, the isResolved property should be set and this is a bug?

       

      My AFSDK assembly is v4.0.30319.

       

      Here's a small test program to illustrate the behavior

       

      using System;
      using OSIsoft.AF.PI;
      
      namespace PITest
      {
          class Program
          {
              public void run()
              {
                  var piServer = "MyServerHostName";
      
                  PIServer server = PIServer.FindPIServer(piServer);
                  PIPoint p1 = PIPoint.FindPIPoint(server, "sinusoid");
                  Console.WriteLine("PIPoint by tagname Resolved?: " + p1.IsResolved);
                  if (p1.IsResolved)
                  {
                      Console.WriteLine("\tPoint ID: " + p1.ID);
                  }
      
      
                  PIPoint p2 = PIPoint.FindPIPoint(server, 1);
                  Console.WriteLine("PIPoint by PointNumber Resolved?: " + p2.IsResolved);
                  Console.WriteLine("\tPoint Name is: " + p2.Name);
              }
      
              static void Main(string[] args)
              {
                  Program p = new Program();
                  p.run();
                  Console.WriteLine("\n\nPress key to exit....");
                  Console.ReadKey();
              }
          }
      }
      

       

      On my system, p2.isResolved returns false but ps.Name displays "SINUSOID".

       

      Thanks

        • Re: PIPoint isResolved when using FindPIPoint
          gregor

          Hello Mark,

           

          If the name of the PI Point could be resolved, IsResolved property should return true.

           

          I have PI AF Client 2016 R2 SP1 installed and it works exactly like that for me. It does not matter if I use a PI Points name or it's Point ID. The version you specify for AF SDK assembly appears to be wrong. Can you please lookup the PI AF Client version through Add or Remove Programs or output AFGlobalSettings.SDKVersion?

           

          The question is what you are trying to accomplish with the IsResolved property. Do you like to be certain the point was found / exists? If so, you may want to use PIPoint.TryFindPIPoint instead.

          1 of 1 people found this helpful
            • Re: PIPoint isResolved when using FindPIPoint
              langfom

              Hi Gregor

               

              My mistake, I listed the .NET version.  My AF SDK version is currently 2.8.0.7444.  I have just updated my AF Client to 2016 R2 SP1 which shows version 2.8.6.7801.  I've also added into the code a display of the AFGlobalSettings.SDKVersion.  I've cleaned and rebuilt the above test application in Visual Studio 2015, updated the project's .NET version to 4.5.2, rebuilt again and ran the program

               

              AF SDK Version: 2.8.6.7801

              PIPoint by tagname Resolved?: True

                      Point ID: 1

              PIPoint by PointNumber Resolved?: False

                      Point Name is: SINUSOID

               

              The isResolved is still False.

               

              I went to add the TryFindPoint method but unfortunately there is no point ID overload method just a "string pointName".

               

              Yes, you are correct.  I am just wanting to ensure the PI point exists.  Each data message we receive from our SCADA system includes the PI point ID.  This Point ID is assigned when the SCADA point is commissioned in our PI System.  If the point ID is not found I can log the error and investigate why their system is sending an incorrect ID.

               

              The strangest thing I find is when I debug the above application and put a breakpoint on the p2.Name Console.WriteLine is the p2.isResolved is shown as "true" but the screen output is "false".  This is with the Visual Studio Debug Option setting "Enable property evaluation and other implicit function calls" checkbox ticked.  If I uncheck this checkbox the breakpoint shows "false" for p2.isResolved.

               

              I can put a try/catch PIPointInvalidException block around the code as the PIPoint "should" be resolved all of time but you never know in the real world as we have ~200,000 SCADA points (using Point ID) and ~800,000 points (using Tag name) from other monitoring devices in our PI system.

               

              Thanks

                • Re: PIPoint isResolved when using FindPIPoint
                  gregor

                  Hi Mark,

                   

                  I agree to what you are saying but can you try using the point name before checking the IsResolved property to see if this has an impact.

                   

                      string piPointName = p2.Name;
                      bool piPointNameResolved = p2.IsResolved;
                  

                   

                  A more elegant approach compared to catching the exception in case a PI Point with the given Point ID does not exist could be using this overload of the PIPoint.FindPIPoints method using a PIPointQuery with the Point ID. If this method returns a empty, the point does not exist.

                    • Re: PIPoint isResolved when using FindPIPoint
                      langfom

                      Hi Gregor

                       

                      Yes, that works.

                       

                      PIPoint ps = PIPoint.FindPIPoint(server, 1);
                      Console.WriteLine("PIPoint by PointNumber Resolved Before?: " + ps.IsResolved);
                      Console.WriteLine("\tPoint Name is: " + ps.Name);
                      Console.WriteLine("PIPoint by PointNumber Resolved After?: " + ps.IsResolved);
                      

                       

                      The above code prints out

                       

                      PIPoint by PointNumber Resolved Before?: False

                              Point Name is: SINUSOID

                      PIPoint by PointNumber Resolved After?: True

                       

                      Do you think there would be any performance difference between FindPIPoint and FindPIPoints?

                        • Re: PIPoint isResolved when using FindPIPoint
                          gregor

                          Hello Mark,

                           

                          According to the tests within my environment just FindPIPoint is ~ 100x faster compared to FindPIPoints but with ensuring the point name IsResolved it's only ~ 10x faster.

                          The methods I've used for testing are:

                                  static IEnumerable<PIPoint> FindPointByID(int pointID)
                                  {
                                      string attributeName = "PointID";
                                      List<PIPointQuery> qList = new List<PIPointQuery>();
                                      PIPointQuery ptQuery = new PIPointQuery(attributeName, AFSearchOperator.Equal, pointID.ToString());
                                      qList.Add(ptQuery);
                                      IEnumerable<PIPoint> pts = PIPoint.FindPIPoints(piSrv, qList, null);
                                      return pts;
                                  }
                          

                                

                                  static PIPoint SelectPointByID(int pointID)
                                  {
                                      try
                                      {
                                          PIPoint pt = PIPoint.FindPIPoint(piSrv, pointID);
                                          return pt;
                                      }
                                      catch
                                      {
                                          return null;
                                      }
                                  }
                          

                           

                                  static PIPoint ResolvePointByID(int pointID)
                                  {
                                      try
                                      {
                                          PIPoint pt = PIPoint.FindPIPoint(piSrv, pointID);
                                          string ptName = pt.Name;
                                          bool ptNameResolved = pt.IsResolved;
                                          return pt;
                                      }
                                      catch
                                      {
                                          return null;
                                      }
                                  }