17 Replies Latest reply on Sep 13, 2018 5:59 PM by Rick Davin

    How to verify on a collective that the primary member is available

    Noga

      I am using AF-SDK in my c# application that connects to a PI Collective.

      Since PI Points can be created or edited only on the primary member of a PI Collective, my goal is to verify that the primary member of the collective is available and connected before creating new Tags using the method PIServer.CreatePIPoint.

      And in case the primary is unavailable, the application will store these tags in a list until the primary is available again.

       

      When simulating a primary server disconnection using the standalone command:

      piartool -sys -standalone on

      and debugging the following condition in my code that checks if primary is connected

      PIServer.Collective.ConnectedMemberType == AFServerRole.Primary

      I revealed that the ConnectedMemberType flag is not set to the correct state, since it was still set to ConnectedMemberType.primary, even though the primary was unavailable.

      Since I want to prevent a state where new tags or edited tags are not updated on the collective and are lost because the primary is unavailable, I would like to know:

       

      What is the best and reliable way to confirm that the primary member is connected/available for updating tags editing\adding\deleting?

      Would it be a good approach to use PICollectiveMember.Connect Method with 'RequirePrimary' parameter:

      myPIServer.Connect(true, null, AFConnectionPreference.RequirePrimary);
      If yes, then how can I verify that a connection to the primary is indeed established?
        • Re: How to verify on a collective that the primary member is available
          Lal_Babu_Shaik

          Hi Noga

           

          You can can try with below method. If you are unable to connect to Primary then it will not write create any PI Points.

          myPIServer.Connect(true, null, AFConnectionPreference.RequirePrimary);

          myPIServer.Disconnect();

           

          For checking the status you can also use below property : https://techsupport.osisoft.com/Documentation/PI-AF-SDK/html/P_OSIsoft_AF_PI_PICollectiveMember_IsConnectedToPrimary.htm

           

          PICollectiveMember.IsConnectedToPrimary Property

           

          Thank you,

          Lal

          1 of 1 people found this helpful
          • Re: How to verify on a collective that the primary member is available
            Rick Davin

            Hi Noga,

             

            You are on the right path by using a Connect overload with AFConnectionPreference as one of the arguments.  If you looked up help on AFConnectionPreference and read what it says specifically about RequirePrimary, then you would see this:

             

            Only the Primary server is acceptable for a connection. If the primary server is not available, the connection fails.

             

            This should tell you that if you RequirePrimary and it is unavailable that the attempt to Connect should throw an exception. 

             

            Additionally, you may also check the PIServer.ConnectionInfo.IsConnected property.

            1 of 1 people found this helpful
            • Re: How to verify on a collective that the primary member is available
              Noga

              When continuing examining the AFConnectionPreferance options:

               

              I also tried connecting in the following ways:

              PIServer.Connect(NetworkCredential, AFConnectionPreferance.PreferPrimary)

              PIServer.Connect(NetworkCredential, AFConnectionPreferance.Any)

               

              and still get the same error: Cannot connect to the PI Data Archive.

               

               

                • Re: How to verify on a collective that the primary member is available
                  Rick Davin

                  Hi Noga,

                   

                  Let me get some clarification about your application. 

                   

                  1. Explicitly connects with PIServer.Connect(NetworkCredential)
                  2. Does some stuff
                  3. Explicitly disconnects
                  4. Attempts to explicitly connect once again using PIServer.Connect(NetworkCredential, AFConnectionPreference.RequirePrimary)

                   

                  If that is the case, I would ask if you can skip the first connection (and subsequent disconnect) and have your app attempt to only connect with  PIServer.Connect(NetworkCredential, AFConnectionPreference.RequirePrimary).

                   

                  It would also help if you would share the relevant portions of code.

                  • Re: How to verify on a collective that the primary member is available
                    gregor

                    Hello Noga,

                     

                    I like to share the following snippet which we could use to continue the discussion.

                    I have successfully tested this sample by passing the name of my PI Data Archive Collective and the NetworkCredentials of a Windows domain account. Please note that the code assumes Windows Authentication.

                     

                            static bool IsPrimaryAvailable1(string CollectiveName, NetworkCredential netCredential)
                            {
                                PIServer piSrv = new PIServers()[CollectiveName];
                                // Fail if the server is not a Collective
                                if (piSrv.Collective == null)
                                {
                                    Console.WriteLine("Server {0} is not a Collective.", piSrv.Name);
                                    return false;
                                }
                                else
                                {
                                    try
                                    {
                                        string primaryName = piSrv.Collective.FindPrimary().Name;
                                        piSrv.Connect(netCredential, AFConnectionPreference.RequirePrimary, PIAuthenticationMode.WindowsAuthentication);
                                        if (piSrv.ConnectionInfo.IsConnected)
                                        {
                                            Console.Write("Succesfully connected ");
                                            string connectedMember = piSrv.Collective.CurrentMember.Name;
                                            if (primaryName == connectedMember)
                                            {
                                                Console.WriteLine("Primary: {0}", connectedMember);
                                                piSrv.Disconnect();
                                                return true;
                                            }
                                            else
                                            {
                                                Console.WriteLine("but the member ({0}) is not the Primary ({1}).", connectedMember, primaryName);
                                                piSrv.Disconnect();
                                                return false;
                                            }
                                        }
                                        else
                                        {
                                            Console.WriteLine("Connection attempt failed for no obvious reason.");
                                            return false;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine("Failed to connect to {0}.", piSrv.Name);
                                        Console.WriteLine("Exception: {0} - {1}", ex.HResult, ex.Message);
                                        return false;
                                    }
                                }
                            }
                    
                    3 of 3 people found this helpful
                      • Re: How to verify on a collective that the primary member is available
                        Noga

                        Gregor ,

                        Thank you very much for the snippet code, I will definitely try it.

                        Meanwhile, since my goal is to check in a collective that the primary member is available for points update (delete, add and edit),

                        I wrote the following method that sends a 'dummy' request to the pi server to get points count, in order to check the availability of the primary server.

                        When testing it it seems to work fine -when the primary is unavailable, it throws the exception which indicates the server is unavailable.

                         

                        public bool CheckConnectionToPrimary()

                        {

                             try

                             {

                                  myServer.GetPointCount();

                                  return true;

                             }

                             catch(Exception)

                             {

                                  return false;

                             }

                        }

                         

                        Do you think this solution is good enough?

                    • Re: How to verify on a collective that the primary member is available
                      Rick Davin

                      More than that, if myServer is connected to a Secondary, then CheckConnectionToPrimary() will still return true.