20 Replies Latest reply on Aug 20, 2012 9:39 AM by Gregor

    Check If Tag Exists on Server Using PI-SDK

    rohanar

      What is the best way to determine if a tag exists on a pi server using the PI SDK? My clunky solution is below -- is there a better way than trying to retrieve the PIPoint object and catching the error if the tag does not exist? Is there function for this?   Thanks in advance.

      Dim MyPoint as PISDK.PIPoint  = GetPITag(MyTagName)

      Dim TagExists as Boolean = MyPoint IsNot Nothing

      Public Function GetPITag(ByVal TagName As String) As PISDK.PIPoint

              Dim PIPoint As PISDK.PIPoint = Nothing

              Try
                  PIPoint = PIServer.PIPoints(TagName)
              Catch ex As Exception
                  PIPoint = Nothing
              End Try

              Return PIPoint

      End Function

        • Re: Check If Tag Exists on Server Using PI-SDK

          An alternative (not saying it is better, I have not benchmarked it) would be:

          
          

          Dim MyPoint as PISDK.PIPoint  = GetPITag(MyTagName) 

          Public Function GetPITag(ByVal TagName As String) As PISDK.PIPoint

                  Dim PIPoint As PISDK.PIPoint = Nothing

                  If PIServer.GetPoints(String.Format("tag='{0}'",TagName)).Count = 1 Then
                        PIPoint = PIServer.PIPoints(TagName)
                  Else
                        PIPoint = Nothing
                  End If
                  Return PIPoint

           End Function

           

          Similar thread here: http://vcampus.osisoft.com/forums/p/438/1779.aspx#1779

            • Re: Check If Tag Exists on Server Using PI-SDK
              rohanar

              Thanks, that did actually shorten the time by about 25% when searching for tags that did exist.  When tags were not on the server, performance was roughly equivalent.

                • Re: Check If Tag Exists on Server Using PI-SDK
                  Rick Davin

                  One must be careful when benchmarking with the PISDK or Server objects as there may be caching involved which could skew results.  If you run 2 different methods back-to-back, you may try to change the order of things to see if the results differ.  Or rather than trying a benchmark of calls back-to-back, you may want to try totally separate runs one at a time.

                   

                  I did a quick test where I reset the PISDK and Server object before each call and my results are that Rosanne's method is much, much faster than Rhy's when the PI tag exists (about 75% faster), and about the same when it doesn't exist.  No offense to Rhys ... as he said he didn't benchmark it but rather just came up with an alternative method.

                   

                  If I had a wish list, I'd like to see a new PISDK method where you pass a tagname as a string and it returns the PointID as a long.  If the point isn't found, just return a 0 instead of an error.  I don't want a big object ... all I want is the PointID, which I can later use in optimized searches. 

                   

                   

                   

                   

                   

                   

                    • Re: Check If Tag Exists on Server Using PI-SDK

                      I remembered the GetPoints route because I think on vCampus (or another forum) that someone asked if it was possible to check if a PI tag exists without generating an exception.

                       

                      My PISDK wish list consists of a lot more functionality with PointLists.

                        • Re: Check If Tag Exists on Server Using PI-SDK
                          cjrancur

                          Rhys, I second your request. I'd rather avoid a try/catch block by doing a preliminary verification step to ensure that a called PI tagname exists on a server, before I try to set a server pipoint object for a particular tagname string on a particular PI server. I have a data transfer program that had been running well for a couple of years, but it stopped sending additional data when it reached an undefined PI tag, so this data processing to PI did not happen over a full weekend. That was not a good thing.  

                           

                          Including both functions would probably slow the program down quite a bit when all is OK. And, all had been OK for a long time until the data problem occurred. I wonder if I am better off just catching the error and handling it from the PIPoints(tagname) method, instead of adding a preliminary call to see if the point exists, and then assigning the point.

                           

                          This  vCampus conversation so far seems to show that both the PIPoint and the GetPoints methods can take similar processing times, so if I try to always do both, I could be roughly doubling the processing time in that case.

                           

                          Does an enhancement request to the PIPoint function need to go directly to tech support, or will a conversation on vCampus be enough to initiate a request or to "second the motion" on an existing request?

                            • Re: Check If Tag Exists on Server Using PI-SDK
                              mhamel

                              @Carrie: You need to contact our techsupport to open a ticket on this issue and an enhancement request will be created for PIPoint related methods. I invite you to share the link to this forum's thread within your ticket.

                                • Re: Check If Tag Exists on Server Using PI-SDK
                                  cjrancur

                                  Hello Mathieu,

                                   

                                  I just sent an enhancement request to techsupport.  I am hoping that I have worded it in a way that will encourage developers to generate a function that includes with the best features of the various ideas requested in this discussion, without having my request limit the OSIsoft developer's ideas.  I have grown to have a lot of faith in OSIsoft development, and I believe they could come up with ideas better than mine alone.

                                    • Re: Check If Tag Exists on Server Using PI-SDK
                                      Ahmad Fattahi

                                      Carrie,

                                       

                                      Your initiative is much appreciated. Rest assured that OSIsoft takes these enhancement requests to heart and tries to capture the sole of what users, customers, and developers like you need to have. We have a developers' team that is technically savvy and looks into the best ways to implement a feature once approved. Also, the Product Management captures, puts into perspective, and prioritizes all the enhancement requests to make sure we deliver in the most efficient way.

                                        • Re: Check If Tag Exists on Server Using PI-SDK
                                          Rick Davin

                                          Carrie,

                                           

                                          While I am loading AF 2.5 Beta 3 to a VM, I'm reading posts and dabbling with some code.  I have some VB samples that hopefully follow along the lines that you were thinking.  I see 2 main points to your posts in this thread.  (1) That you'd like a quick* way to see if a tag exist, and (2) that you've contacted tech support with a product feature request.  As for point (1), I know that I and others agree with you.  As for point (2), thanks from a fellow member of the vCampus community.

                                           

                                          * Quick means different things to different people.  To me, I want a way that doesn't send me an entire PIPoint object, or worse, a large PointList collection.  While some would say just send over a Boolean, my wish would be for a server-side method that return the PointID as an Integer, or collection of PointID's in an Integer array.

                                           

                                          I have some extension methods to simulate what I would like to see in these server-side methods.  Note there is a bug with posting VB extension methods to vCampus using Insert Code; the < and > symbols go haywire.

                                           

                                          <System.Runtime.CompilerServices.Extension()> _
                                          Public Function GetPointID(ByVal PIServer As PISDK.Server, ByVal TagName As String) As Integer
                                          ' This function searches for one point matching a name.
                                          ' It simulates what I would like to see in a server-side PISDK method.
                                          Dim PIPoint As PISDK.PIPoint = Nothing
                                          Try
                                              PIPoint = PIServer.PIPoints(TagName)
                                              Return PIPoint.PointAttributes.CommonAttribute(CommonAttributeConstants.cmnatrPointID).Value
                                          Catch ex As Exception
                                              ' No Operation needed
                                          End Try
                                          Return 0
                                          End Function

                                           

                                           

                                           

                                           <System.Runtime.CompilerServices.Extension()> _
                                          Public Function GetPointIDs(ByVal PIServer As PISDK.Server, ByVal NamePattern As String) As Integer()
                                          ' This function searches for 0-to-Many points matching a name pattern.
                                          ' It simulates what I would like to see in a server-side PISDK method.
                                          Dim OutList() As Integer = New Integer() {}
                                          Dim ptList As PISDK.PointList = Nothing
                                          Try
                                              ptList = PIServer.GetPoints("Tag='" & NamePattern & "'")
                                              If ptList.Count > 0 Then
                                                  ReDim OutList(ptList.Count - 1)
                                                  ' ptList is 1-based. OutList is 0-based.
                                                  
                                          For i As Integer = 1 To ptList.Count
                                                      OutList(i - 1) = ptList(i).PointAttributes.CommonAttribute(
                                          CommonAttributeConstants.cmnatrPointID).Value
                                                  Next
                                              End If
                                          Catch ex As Exception
                                              ' No Operation needed
                                          End Try
                                          Return OutList
                                          End Function

                                           

                                          Now here's a some snippets to show how I would hope to interact with those wishful methods:

                                           
                                                  ' Variable PIServer already set
                                                  ' Variable MyTagName already set
                                                  Dim MyPointID As Integer = PIServer.GetPointID(MyTagName)
                                                  Dim MyPoint As PISDK.PIPoint = Nothing
                                                  If MyPointID <> 0 Then MyPoint = PIServer.PIPoints("?" & MyPointID)
                                                  ' Further process MyPoint ...
                                          
                                          
                                                  ' an example using a collection of unknown size ...
                                                  Dim MyPointIDs() As Integer = PIServer.GetPointIDs("SINU*")
                                          
                                                  ' One way to check if there were any hits
                                                  If MyPointIDs.Count > 0 Then
                                                      ' Points were found.  Okay to process the list.
                                                      ' Works great to set up a progress bar with a known count.
                                                  End If
                                          
                                                  ' A way to quickly decide there were no hits
                                                  If MyPointIDs.Count = 0 Then
                                                      ' Take some appropriate action.
                                                  End If
                                          
                                                  ' Another way to check and process the list
                                                  For Each MyPointID In MyPointIDs
                                                      MyPoint = PIServer.PIPoints("?" & MyPointID)
                                                      ' Further process MyPoint ...
                                                  Next
                                          

                                           

                                           

                                          I don't recommend anyone actual use this in any of their code.  Since it's all client-side, it would be quite inefficient to send  a PIPoint to the client, grab only the PointID, throw away the PIPoint only to immediately request it a 2nd time from the PIServer.  But if those extension methods were executed server-side, I would be quite happy.  I could easily tell if a PIPoint exists, set up progress bar counts for a name pattern, use it in flow control, issue appropriate messages, etc.

                                            • Re: Check If Tag Exists on Server Using PI-SDK

                                              This thread raises many usage questions...

                                               

                                              I would like to know where you obtained the tagname passed to GetPointID(MyTagName)?  Have you looked at persistance strings as an alternative?

                                               

                                              Why is PointID useful to you instead the tag path?  PointID is not unique across servers.

                                               

                                              If you have tagname, why not just get the PIPoint with all the associated PointAttributes in one call (or Count=0)?  Getting the PointID, then getting the PIPoint later requires two network trips.

                                               

                                              Is it performance (usually boils down to minimum number of network trips), or is it client application memory which is the optimization target?

                                                • Re: Check If Tag Exists on Server Using PI-SDK
                                                  cjrancur

                                                  Charles,

                                                   

                                                  In my case, the project that generated this request involved integration of data between SQL and PI, with tagnames passed to the PI server from a SQL table.  When the SQL field had a mis-spelled PI tag field, then that mis-spelled string was assigned to a PI point, generating an error that stopped processing when the mis-spelled PI tag was encountered.  Remaining SQL rows following the one with the mis-spelled tag were not processed. I want to know if the PI tag string is right or wrong before I assign it to a PIPoint object, rather than requiring Try/Catch exception processing methods in vb.net code to handle this occasional issue.

                                                    • Re: Check If Tag Exists on Server Using PI-SDK

                                                      If the tag is not found (query='MyTypo'), trapping in an exception handler (inside the loop over rows) so it can be deleted from the list sounds useful.

                                                       

                                                      If the tag is found, some use is made, which will require a collection of PointAttributes such as point type.  I do not understand the request to check for existence, but not return a PIPoint object.  However, if I do want to use the PIPoint for some purpose, using IGetPoints2.GetPoints2 with a list of required attributes will return a usable PIPoint with only attributes used in the program.

                                                       

                                                      Am I missing something?

                                                      • Re: Check If Tag Exists on Server Using PI-SDK

                                                        Carrie Rancuret

                                                        In my case, the project that generated this request involved integration of data between SQL and PI, with tagnames passed to the PI server from a SQL table.
                                                        Just a quick thought... wouldn't it be best to use the PI RDBMS Interface (an off-the-shelf product) to do that, rather than develop your PI SDK based solution? It might turn out being even more efficient and it will certainly prove to require lower maintenance over time. Just a thought...

                                                          • Re: Check If Tag Exists on Server Using PI-SDK

                                                            @Rosanne, Rick, Carrie: I'm still trying to understand why the PI SDK Server.GetPoints method is not sufficient for your (and Rick Davin's and Rosanne Rohana's) needs. For instance, why wouldn't this work:

                                                             
                                                            Dim ptl As PISDK.PointList = srv.GetPoints("tag = '" & tagName & "'")
                                                            Dim pt As PISDK.PIPoint = If(ptl.Count > 0, ptl(1), Nothing) 
                                                            

                                                            Or something that allows you to control what attributes to load first, so that you have more control over the amount of data being transferred:

                                                             
                                                            Dim nvAttributes As New PISDKCommon.NamedValues()
                                                            nvAttributes.Add("descriptor", Nothing)
                                                            nvAttributes.Add("engunits", Nothing)
                                                             
                                                            ptl = DirectCast(srv, PISDK.IGetPoints2).GetPoints2("tag = '" & tagName & "'", nvAttributes,
                                                                                            PISDK.GetPointsRetrievalTypes.useGetPoints, Nothing, Nothing, Nothing)
                                                            pt = If(ptl.Count > 0, ptl(1), Nothing) 
                                                            

                                                            These seem like good ways to achieve what you want – without creating more work on our end, or wait time on yours. Agreed?

                                                             

                                                            Also, as you might have heard or read already, we encourage developers to transition to the AF SDK as soon as it is convenient. The AF SDK can be thought of as the PI System SDK in that it provides a much broader access to PI System objects – AF Elements and Attributes, Event Frames, Notifications, and the good old PI Points. This last part is made available via AF SDK 2012 which is currently available in Beta form on vCampus – see the webinar on the topic. Of course we encourage everybody to create their asset model and leverage the power of the PI Asset Framework, but it will still be possible to access classic PI Points without an asset model with the AF SDK – and often times in a more efficient way. With all this in mind, AF SDK is where we plan to focus most of our efforts – as compared to PI SDK – which is why I brought the previous points, i.e. trying to achieve what you want with existing tools.

                                                             

                                                            If you feel like you are ready to transition some of your PI SDK code over to AF SDK, note that functionality you requested is already available: these methods allow to look up for a PI Point and return an empty object rather than throw an exception:
                                                                   OSIsoft.AF.PI.PIPoint.FindPIPoint (String)
                                                                   OSIsoft.AF.PI.PIPoint.FindPIPoint (PIServer, Int32)
                                                                   OSIsoft.AF.PI.PIPoint.FindPIPoint (PIServer, String)

                                                             

                                                            Hope this helps!

                                                              • Re: Check If Tag Exists on Server Using PI-SDK

                                                                And for those programming in C#, the lines of code from the previous post would look as follows:

                                                                 
                                                                PISDK.PointList ptl = myServer.GetPoints("tag = '" + tagName + "'");
                                                                PISDK.PIPoint pt = ptl.Count > 0 ? ptl[1] : null;
                                                                

                                                                 And:

                                                                 
                                                                object o = null;
                                                                PISDKCommon.NamedValues nvAttributes = new PISDKCommon.NamedValuesClass();
                                                                nvAttributes.Add("descriptor", ref o);
                                                                nvAttributes.Add("engunits", ref o);
                                                                
                                                                ptl = ((PISDK.IGetPoints2)myServer).GetPoints2("tag = '" + tagName + "'", nvAttributes,
                                                                                                                            PISDK.GetPointsRetrievalTypes.useGetPoints, null, null, null);
                                                                pt = ptl.Count > 0 ? ptl[1] : null;
                                                                

                                                                 

                                                                • Re: Check If Tag Exists on Server Using PI-SDK

                                                                  Oh, one thing I forgot to mention: there's also a few versions of a FindPIPoints method (with an 's') available in the AF SDK.

                                                                    • Re: Check If Tag Exists on Server Using PI-SDK
                                                                      Rick Davin

                                                                      Sorry about delay in response.  Been super busy.  Hasn't helped that half the time my home internet was down, and the other half of the time my work internet was down too.

                                                                       

                                                                      It seems Charles and Steve put the burden on the us to justify why we need to simply know if a PI Point exists.  One thing to keep in mind is that while we talk about a single point, that when we scale it out to checking on tens of thousands of points that there are performance and memory issues that come to mind.  Checking the mere existence of tens of thousands of PI Points in AF is slow.  And its horribly slower the more PI Points that don't exist.  Let's look at actual use case of mine:

                                                                       

                                                                      I've got an AF database with lots of templates and the PI Point configuration will determine its name based on some constant string attribute values.  We then build out several hundred elements, each with dozens to hundreds of attributes.  Its not unreasonable to then scan the attributes to see which ones should be mapped to PI Points but aren't.  So a routine scans over 150,000 attributes just to identify the 35,000 that use the PI Point DR.  Next I can check the config strings of those 35,000 to see which ones are improperly configured for what should be referencing a server and a tag.  All that is quick enough and I've yet to touch the PI server.  Now I look at those that are properly configured and see if their %variable% name substitution actually resolved to a real PI Point, i.e. a PI Point that exists.  Or more to the heart: I want to know which ones did not resolve to an existing PI Point.  I don't give a damn about anything about the PI Point about whether it exists or not.  I don't need a sledgehammer to pound this nail.  I don't need the PI Point object (or 35,000 such objects) passed across the network to me.  All I need is something like a Boolean or an Int32 (more on that below).

                                                                       

                                                                      It was brutal how slow it was to query PI from AFSDK.  Considering I had about 2000 non-existent tags, it become painfully slow to fetch this.  The whole purpose of this application was to identify which ones did not exist in PI so that we could then create them.  Sadly it was faster for me to dump the attribute paths and expected PI Points to a text file, manually import that file into Excel, and then run DataLink to see if the PI Points were found.

                                                                       

                                                                      Let's pretend you buy into the notion that some developers feel they want to check simply for PI Point existence.  I know that's the hard sell but let's say you're open to the idea of something like a Boolean.  So why do I want an Int32?  Yes, Charles, I fully understand that a point ID is not unique across an enterprise.  But it is unique within a PI Server and all of my searches always limit their domain to a single PI Server.  I know that point ID 0 is invalid but any other value is ok.  I can use this to equally in place of a Boolean.  Plus, if I do later decide that I actually want to make the trip over for the PI Point that the retreival is better optimized if I request it by ?PointID rather than Tagname. Since I already made the trip to check for existence, I thought it would at least be a wee bit better to have the PointID at my fingertips rather than just the Boolean.

                                                                       

                                                                       

                                                                        • Re: Check If Tag Exists on Server Using PI-SDK
                                                                          cmanhard

                                                                          Rick - in regards to the "AFSDK being brutally slow" - my question is which AFSDK and what methods.  Are you using bulk resolution or calling methods one at a time?

                                                                           

                                                                          I ran a test a few minutes ago with AF SDK 2.5 (not fair, I know, as it is not released), and used 4 different methods for resolving a list of PI Points / Attributes.  Each list had 10,000 tag names - 1000 valid tag names, and 9000 invalid tag names.

                                                                           

                                                                          OSIsoft.AF.PI.PIPoint.FindPIPoints(PIServer, IEnumerable<string>): ~800 ms (only returns points found)

                                                                           

                                                                          OSIsoft.AF.PI.PIPoint.FindPIPointsByPath(IEnumerable<string>): ~200 ms (takes full path syntax)

                                                                           

                                                                          OSIsoft.AF.Asset.AFAttributeList.GetPIPoints(): ~1 second

                                                                           

                                                                          OSIsoft.AF.Asset.AFAttributeList.GetRawPIPoints() : ~1 second

                                                                           

                                                                          The only one of these methods that existed in earlier AF releases is AFAttributeList.GetRawPIPoints.  I ran this against an older AF release and it was slower - 15 seconds.   About 1.5 ms per tag.  The original algorithm had a mode where it go back and re-try the missing points one by one.

                                                                           

                                                                          The AF 2.5 methods which just return the PI Point object will not have much more than the point id.  They will have the name, pointid, pointtype, a reference to the open server connection, and not much else.  We are not trying to burden you with justifying your needs, but trying to understand the use case so that we can take input from many customers and combine them into a single, coherent SDK.  One issue of not having the pointid encapsulated in a PIPoint object is that it will be cumbersome to map the returned pointid from the bulk call back to the string which it is associated with.

                                                                            • Re: Check If Tag Exists on Server Using PI-SDK

                                                                              Hello,

                                                                               

                                                                              When reading through this thread, I understand the following:

                                                                               

                                                                              - a list of tag names exist

                                                                               

                                                                              - the tags may or may not exist on a PI Server

                                                                               

                                                                              - the tags shall be existent using same attributes on several PI Systems

                                                                               

                                                                              - if they do not exist they are supposed being created

                                                                               

                                                                              How about using PI-SMT tag builder add-in for Excel:

                                                                               

                                                                              - Load (Import) the list of tags from a PI Server (the template) where all tags have been created into an Excel spreadsheet.

                                                                               

                                                                              - Optionally save the spreadsheet for later use on another machine i.e. if other PI Servers belong to a different network.

                                                                               

                                                                              - Create the tags using option "Create or Edit"

                                                                               

                                                                              2677.Clipboard03.jpg

                                                                               

                                                                              The "Create or Edit" doesn't belong to my favorites because I prefer knowing / the need to think about my intentions before "Create" or "Edit" tags but for this case it appears reasonable. It is for sure an approach outside AF but creating tags in PI directly using existent tools must be considered a valid approach.

                                                                               

                                                                              To just check if tags exist on a PI System one can use a spreadsheet listing the names of tags to check for and just loading the configuration. The Tag Builder add-in will mark tags that were not found red.

                                                                               

                                                                              1526.Clipboard01.jpg

                                                                               

                                                                              4807.Clipboard02.jpg

                                                                               

                                                                              Gregor

                                                                • Re: Check If Tag Exists on Server Using PI-SDK
                                                                  cjrancur

                                                                  Rick, I like your ideas.  

                                                                   

                                                                  And like your signature says, "In the land of the blind, the one-eyed man is king".

                                                                   

                                                                  Maybe we will be able to put forward our best request to OSIsoft with ideas from many of us, a request from "many-eyes", if you will.

                                                                   

                                                                  Carrie