4 Replies Latest reply on Apr 20, 2017 3:02 PM by gregor

    FindPIPointsByPath with a given collective member




      by using a list of complete PIPoint paths, I want to identify the PIPoints and subscribe for snapshots.


      However, if I use the method




      where "paths" is a list of string of the format



      it correctly returns the PiPoints, but they are pointing to the primary collective member.


      tag.Server.Collective.CurrentMember.Name is the primary member.

      tag.GetPath() returns \\[CollectiveName]\[TagName]


      If I start subscribing for snapshots of these tags, the primary member's Update Manager will be stressed instead of the secondary.


      Is it possible to specify the path in a way that the server's name is correctly considered?


      AFSDK is version


      Thank you.

        • Re: FindPIPointsByPath with a given collective member

          Hello Martin,


          You would usually refer the name of the collective as specified in the Known Servers Table within the path string. However, to make sure you connect against the Secondary node, you would need to change the Priority for the connection. This can be done using PISDKUtility.exe. Under PI SDK -> Connections, right-click your Collective and chose Member Setup ..

          Within the Collective Member Setup dialog set the Priority by providing the smaller number to your preferred host.

          Please note that this modification will affect all connections from this client to your Collective. All applications will prefer connecting against the Secondary. In case the Secondary will become unavailable, AF SDK will failover to the Primary and not automatically switch back.


          Setting the Priority client side as described above is one option. I just had an idea for a programmatic approach. Working on it ..

          1 of 1 people found this helpful
            • Re: FindPIPointsByPath with a given collective member

              Hallo Gregor,


              thank you for the reply. In the AF SDK help, there are some hints about how to specify the server portion of a path:


              The server portion of the path should be in one of the following forms. The order of the serverName and serverID determines the preference (the first one has higher preference) when resolving the server by Name or ID.

              • serverName
              • {serverID}
              • serverName;{serverID}
              • {serverID};serverName
              • PIServers[serverName]
              • PIServers[{serverID}]
              • PIServers[{serverID};serverName]
              • PIServers[serverName;{serverID}]


              In my opinion, the server name should be considered by the path. So I was asking myself whether my notation was somehow wrong.


              However, if there is only a programmatic solution (or the host-wide setting via member priority), I could also isolate the server name for myself, connect to it directly and search the PIPoints by using FindPIPoint. It may only result in a lack of performance, but that should not be a problem.

                • Re: FindPIPointsByPath with a given collective member

                  Hello Martin,


                  You could use piartool -sys -close to close the listener on the Secondary and piartool -sys -open to open it again when testing the following sample. Please use these commands with caution because closing the listener on the Secondary will as well impact other clients connected against the Secondary. Probably best you test this with a Development PI System. The paid PI Developers Club membership includes access to setup kits and license file allowing you to install a PI System for personal development purpose.


                          static void Main(string[] args)
                              string piCollectiveName = "PICollective";
                              string piCollSecondaryName = "secondaryPI";
                              PIServer piSrv = new PIServers()[piCollectiveName];
                              PICollectiveMember secondaryPI = piSrv.Collective.Members[piCollSecondaryName];
                                      Console.ForegroundColor = ConsoleColor.Green;
                                      Console.WriteLine("Connected to {0}", piSrv.Collective.CurrentMember.Name);
                                  catch (Exception ex)
                                      Console.ForegroundColor = ConsoleColor.Gray;
                                      Console.WriteLine("{0:HH:mm:ss} Error connecting to {1}", DateTime.Now, piCollSecondaryName);
                                      Console.ForegroundColor = ConsoleColor.Red;
                                      Console.Write("Exception: ");
                                      Console.ForegroundColor = ConsoleColor.Gray;
                                      Console.WriteLine("Next connection attempt in ~2 seconds");
                              } while (!secondaryPI.IsConnected);
                              Console.ForegroundColor = ConsoleColor.White;
                              Console.WriteLine("Well this was it. There appears to be nothing more to do.");
                              Console.Write("Ready when you are. Press any key to quit .. ");


                  The sample assumes the initial connection goes against the Primary and that the attempt toswitch to the Secondary fails because of the Secondary being unavailable. As soon as you open the listener on the Secondary again, the next attempt will succeed and that's it.

              • Re: FindPIPointsByPath with a given collective member
                Rick Davin

                Hi Martin,


                You don't want to use the FindPIPointsByPath method to achieve what you desire.  Your code instead should:

                1. Simply connect to the PIServer, which happens to be a PICollective
                2. Set an object reference to the desired PICollectiveMember
                3. Either Connect to that member, or Switch to that member.
                4. Use FindPIPoints on the PIServer (the collective currently connected to your desired member)


                The difference between PICollectiveMember.Connect and PICollective.SwitchMember is that Connect will throw an exception if it fails to connect to the specific member, whereas SwitchMember will failover to the next available member.

                2 of 2 people found this helpful