10 Replies Latest reply on Nov 1, 2016 11:25 AM by gregor

    How to get List of PI Servers in Collective.

    Nagendra

      Why was that there is no difference between PICollectives and PIServers in the Object Model. From the Heirarchy standpoint it should be some thing like PIServers are member of PI Collective. When i try to get the list of PI Servers, i see the collective name also added into list and when i try to fetch a single PI Server using Guid it shows null even though there is a PI Server with the name and Guid.

       

      When i try to fetch using the member guid, as shown below it gives null always.

      PIServer piserver = PIServer.FindPIServer(server.ServerGuid);

       

      Can any one help?

        • Re: How to get List of PI Servers in Collective.
          gregor

          Hello Venkata,

           

          The client handles connections automatically. For PI Collectives, it decides about what member to connect to and handles a possible failover. For this reason you usually don't need to care if you are connecting to a single PI Data Archive node or a PI Collective consisting of x PI Data Archive nodes.

           

          Can you tell what you are trying to accomplish?

           

          For your reference, below code sample is one way to see if a Known Servers Table (KST) entry is a PI Collective or not and if it is a Collective, to list the belonging members.

           

          using OSIsoft.AF;
          using OSIsoft.AF.PI;
          namespace FindCollectiveMembers
          {
              class Program
              {
                  static void Main(string[] args)
                  {
                      PIServers knownServers = new PIServers();
                      foreach (PIServer server in knownServers)
                      {
                          if (server.Collective == null)
                          {
                              Console.WriteLine("PI Data Archive is '{0}'", server.Name);
                          }
                          else
                          {
                              Console.WriteLine("PI Collective '{0}' consists of {1} nodes", server.Name, server.Collective.Members.Count);
                              foreach (PICollectiveMember member in server.Collective.Members)
                              {
                                  Console.WriteLine("   Member '{0}'", member.Name);
                              }
                          }
                          Console.WriteLine();
                      }
                      Console.ReadKey();
                  }
              }
          }
          
          2 of 2 people found this helpful
            • Re: How to get List of PI Servers in Collective.
              Marcos Vainer Loeff

              Hello,

               

              I've run the code below:

               

               

                          PIServers myPIServers = new PIServers();
                          PIServer myPIServer = myPIServers["PICOLLECTIVENAME"];
                          bool r = myPIServer == PIServer.FindPIServer(myPIServer.ID) ? true : false;
              

               

               

              And the value of the variable r is equal to true.

               

              Therefore, use the property ID of the PIServer object as an input of the FindPIServer method.

               

              Hope it helps!

              2 of 2 people found this helpful
            • Re: How to get List of PI Servers in Collective.
              Rick Davin

              FindPIServers should not be used to connect directly to members.  You must first connect to the collective, which can be used with FindPIServers.  The collective instance is then used to connect to its member, either by a PICollective.SwitchMember or a PICollectiveMember.Connect  call.  The difference is that a SwitchMember will fail over to another member if it cannot directly connect to the requested member, whereas the Connect will thrown an exception if the member is unreachable.

               

              PIServer dataArchive = PIServer.FindPIServer("YourCollectiveName");
              PICollectiveMember member = dataArchive.Collective.Members["YourRequestedMember"];
              // EIther use:
              dataArchive.Collective.SwitchMember(member);  // may switch to different member rather than throw exception
              // OR
              member.Connect();  // may throw exception
              // and then you would continue to use dataArchive variable, which is now connected to the member
              Console.WriteLine(dataArchive.Collective.CurrentMember.ID);
              

               

              If you desire connecting to multiple members at the same time, you would want to use the PICollectiveMember.ConnectDirect  method.

              1 of 1 people found this helpful
              • Re: How to get List of PI Servers in Collective.
                Nagendra

                Hi All,

                 

                Thanks for your responses. I am actually developing self heal module for some of the assets using Object Model and also Power shell cmdlets. In the process, i need to monitor each and every server rather than a collective and get the status of each and every thing critical for us to monitor. In the process i need to monitor the state of both primary server and also secondary server and when some one queries for status of specific PI Server, it should provide status of PI Server rather than Collective as Collective is always virtual and PI Servers are physical.

                 

                Abstract of my code is provided below.

                 

                public class Server_Object
                    {
                        public string ServerName { get; set; }
                        public Guid ServerGuid { get; set; }
                    }
                public List<Server_Object> GetPIServers()
                        {
                            try
                            {
                                List<Server_Object> piservers = new List<Server_Object>();
                                PIServers servers = PIServers.GetPIServers();
                                foreach (PIServer pis in servers)
                                {
                                    if (pis.Collective != null)
                                    {
                                        PICollective collective = pis.Collective;
                                        PICollectiveMembers members = collective.Members;
                                        foreach (PICollectiveMember member in members)
                                        {
                                            if (!piservers.Contains(new Server_Object { ServerGuid=member.ID, ServerName=member.Name }))
                                            {
                                                piservers.Add(new Server_Object { ServerGuid = member.ID, ServerName = member.Name });
                                            }
                                        }
                
                
                                    }
                                    else
                                    {
                                        if (!piservers.Contains(new Server_Object { ServerGuid = pis.ID, ServerName = pis.Name }))
                                        {
                                            piservers.Add(new Server_Object { ServerGuid = pis.ID, ServerName = pis.Name });
                                        }
                                    }
                                }
                                return piservers;
                            }
                            catch(Exception exp)
                            {
                                throw exp;
                            }
                }
                private List<Server_Object> _servers;
                
                
                        public List<Server_Object> Servers
                        {
                            get {
                                if (_servers != null) {
                                    PIServerUtility util = new PIServerUtility();
                                    _servers = util.GetPIServers();
                                    return _servers;
                                }
                                else {
                                    return _servers;
                                }
                            }
                        }
                public AFValue GetPIPointValue(string piServer, string piTag)
                        {
                            try
                            {
                                Server_Object server = Servers.Where(a => a.ServerName.ToLower() == piServer.ToLower()).FirstOrDefault();
                                AFValue value = null;
                                if (!object.ReferenceEquals(server, null))
                                {
                                    PIServer piserver = PIServer.FindPIServer(server.ServerGuid);
                                    if (piserver != null)
                                    {
                                        piserver.Connect();
                                        PIPoint point = PIPoint.FindPIPoint(piserver, piTag);
                                        if (point != null)
                                        {
                                            value = point.CurrentValue();
                                            piserver.Disconnect();
                                        }
                                    }
                                }
                                return value;
                            }
                            catch(Exception exp)
                            {
                                throw exp;
                            }
                        }
                
                  • Re: How to get List of PI Servers in Collective.
                    gregor

                    Hi Venkata,

                     

                    I am kind of uncertain about your approach. Have you considered monitoring Performance Counters?

                    I suggest monitoring PI System Health by collecting % Processor Time, Private Bytes and Elapsed time for processes you consider critical.

                     

                    If you need more granularity, you can look at the Performance Counters exposed by the PI Data Archive subsystems e.g. PI Archive Subsystem.

                     

                    You can use PI Interface for Performance Monitor to collect the data into PI and use e.g. PI ProcessBook or PI Coresight for the monitoring.

                    Above mentioned interface is part of the MCN Health monitor package which to my knowledge is included with each PI Server these days.

                     

                    As far as your original question is concerned, does any of the provided replies serve as the [Correct Answer]?

                      • Re: How to get List of PI Servers in Collective.
                        Nagendra

                        Hi Gregor Beck,

                        I have created the performance counters tag using the same way you have mentioned. However consider a case where a collective has 2 servers one primary and other secondary, primary will have processor tag as \\primary\%processor time and secondary will have \\secondary\%processor time. i have faced the problem in this situation where when i say PIServer.Memebrs, it returned me collective and also when i tried fetching the Value of PI Perfmon point by PIPoint.FindPIPoints("secondaryserver", tagName) it always providing me the info of \\collective\%processortime which is always primary. In our case we are looking at monitoring the health of all servers and show the status on HTML5 canvas based display to the operator.

                         

                        Regards,

                        Nagendra.

                          • Re: How to get List of PI Servers in Collective.
                            gregor

                            Hello Venkata,

                             

                            I suggest to use n-way buffering (PI Buffer Subsystem) to fan all Performancew Counter data to all members in your Collective. This way there shouldn't be a big difference what member you are actually reading from. The Collective object will handle what member it connects to based on the preference and availability. If it is important for you to know, what member your client is actually using, you can still read this information from the Collective object.

                             

                            In general, I suggest you to start simple. If you are running into an issue or have doubts, let's discuss. That's what we are here for

                             

                            As Marcos Vainer Loeff said, the better we understand what you like to accomplish, the better we will be able to guide you.

                        • Re: How to get List of PI Servers in Collective.
                          Marcos Vainer Loeff

                          Hello,

                           

                          What exactly do you mean by monitoring "the state of both primary server and also secondary server and when some one queries for status of specific PI Server"?  According to your answer, Gregor's suggestion might work pretty well. Each server can save its own data in PI Points through PIPerfMon interface or you can save all PI Data Archives status data in a single PI Data Archive. But again, we need to know exactly what you want to monitor!