6 Replies Latest reply on Apr 28, 2014 7:19 PM by Marcos Vainer Loeff

    PISDK.PISDKClass.Refresh(Object TargetObject)

    jdouglas
      The following error has happened the last two Fridays. Program runs every minute and hasn't had any problems, but got this error the last two Fridays. Program checks if there's a connection to the PI server, then calls Function GetDigitalStateDictionary Message: The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT)) Assembly Version: 1.0.0.0 Stack Trace: at PISDK.PISDKClass.Refresh(Object TargetObject) PC running program is at SDK version 1.3.6.36 PI version is 3.4.380.36 Any ideas what this error means or how to avoid it? Here's the function. It came from the SDK help file. The refresh method updates the states incase they. I'm thinking about just removing it, because the digital states aren't changing for this tag.         Public Function GetDigitalStateDictionary(tagname As String) As Dictionary(Of Integer, String)             Dim tmpList As New Dictionary(Of Integer, String)             Dim stateSet = GetTagAttribute(tagname, "digitalset")             piSDK.Refresh(m_LocalServer.StateSets)             If stateSet <> "" Then                 For Each setSet As DigitalState In m_LocalServer.StateSets(stateSet)                     tmpList.Add(setSet.Code, setSet.Name)                 Next             End If             Return tmpList         End Function
        • Re: PISDK.PISDKClass.Refresh(Object TargetObject)
          jdouglas

          OSI needs to work on the formatting on the site. That isn't what I submitted. I'll try again.

           

          The following error has happened the last two Fridays. Program runs every minute and hasn't had any problems, but got this error the last two Fridays. Program checks if there's a connection to the PI server, then calls Function GetDigitalStateDictionary

           

          Message: The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT)) Assembly Version: 1.0.0.0 Stack Trace: at PISDK.PISDKClass.Refresh(Object TargetObject) PC running program is at SDK version

           

          1.3.6.36 PI version is 3.4.380.36 Any ideas what this error means or how to avoid it?

           

          Here's the function. It came from the SDK help file. The refresh method updates the states incase they. I'm thinking about just removing it, because the digital states aren't changing for this tag.

           

          Public Function GetDigitalStateDictionary(tagname As String) As Dictionary(Of Integer, String)

           

          Dim tmpList As New Dictionary(Of Integer, String)

           

          Dim stateSet = GetTagAttribute(tagname, "digitalset") piSDK.Refresh(m_LocalServer.StateSets)

           

          If stateSet <> "" Then

           

          For Each setSet As DigitalState In m_LocalServer.StateSets(stateSet)

           

          tmpList.Add(setSet.Code, setSet.Name)

           

          Next

           

          End If

           

          Return tmpList End Function

            • Re: PISDK.PISDKClass.Refresh(Object TargetObject)
              Marcos Vainer Loeff

              Hello James,

               

              Could you run the following code snippet on the same machine you are facing the issue? Tell if you have any issue translating it to VB.NET. Also, do you have any issue accessing the digital sets with PI SMT?

               

               

               
                          PISDK.PISDK sdkroot = new PISDK.PISDK();
                          Server myPIServer = sdkroot.Servers["SERVERNAME"];
                          myPIServer.Open();
                          StateSets myStateSets = myPIServer.StateSets;
                          foreach (StateSet myStateSet in myStateSets)
                          {
                              foreach (DigitalState currentDigitalState in myStateSet)
                              {
                                  Console.WriteLine(myStateSet.Name + "\t" + currentDigitalState.Name + "\t" + currentDigitalState.Code);
                              }
                          }
                          myPIServer.Close();
              

               Let me know if it works properly,

              • Re: PISDK.PISDKClass.Refresh(Object TargetObject)

                Hello James,

                 

                James Douglas

                OSI needs to work on the formatting on the site. That isn't what I submitted. I'll try again.

                 

                You may want to use "Use Rich Formatting". This gives you advanced formatting options and you can easily paste code snippets into your reply.

                  • Re: PISDK.PISDKClass.Refresh(Object TargetObject)
                    Marcos Vainer Loeff

                    Hello James,

                     

                    Besides testing the code snippet from my previous post , I found out that RPC_ESERVERFAULT error message refers to the fact that the connection to the PI Server is lost at some point. If you take a look at the PI SDK manual, you will find:

                     


                    1. Using the PI-SDK with Microsoft .Net
                    Important 
                    You should keep a reference to this top-level object while you need to use PI-SDK objects in your program and release it when your program is terminating or when you no longer need access to PI-SDK objects. This was handled automatically for you when using VB6. 
                    What may not be obvious is that .NET can make variables declared on the stack available for release as soon they are no longer referenced in your code, even if they are still 'in-scope'. Thus, the PISDK object can be destroyed before the routine it is in completes. This may cause your program to fail. This optimization only occurs in release builds, so the problem may not be evident to the developer for some time. Below is an example of code that causes this problem. The code is a simple routine for posting message to the PI Message Log. Without modification, this routine would fail after a short period of time because the PISDK object will be destroyed by .NET. 
                    .
                    GC.KeepAlive(piSDK);   

                    Please advise if this post helps you solve the problem,

                      • Re: PISDK.PISDKClass.Refresh(Object TargetObject)
                        jdouglas

                        The error occurs ramdonly, last two Fridays.

                         

                        I'm checking if the connection is valid before calling function GetDigitalStateDictionary

                         

                        Your code ran. I'm getting the states for a tag.

                         

                        I'll add the GC.KeelAlive and ping the pi server from that PC. I think it is losing connection, but think I'm reconnecting before trying to read the states for the past tag. Is it possible that this can return true even if the connection is lost?

                         

                        Private Sub ConnectIfNecessary()

                         

                        If m_LocalServer Is Nothing Then

                         

                             m_LocalServer = piSDK.Servers.Item(m_ServerName)

                         

                        End If

                         

                        If m_LocalServer.Connected Then Exit Sub

                         

                        If m_UserID = "" Then

                         

                           m_LocalServer.Open()

                         

                        Else

                         

                           m_LocalServer.Open("UID=" & m_UserID & "; pwd=" & m_Password)

                         

                        End If

                         

                        End Sub

                         

                        Calling routine is like this

                         

                        ConnectIfNecessary

                         

                        GetDigitalStates(tagname)

                          • Re: PISDK.PISDKClass.Refresh(Object TargetObject)
                            Marcos Vainer Loeff

                            Hi,

                             

                            I guess this is possible since it is not possible to know when the connection is lost. I have found out a code snippet to get the annotations of a PI Point that uses the GC.KeepAlive() method. I believe it will be useful for you:

                             

                             

                             
                                        PISDK.PISDK sdkroot = new PISDK.PISDK();
                                        //Server myServer = sdkroot.Servers.DefaultServer;
                                        Server myServer = sdkroot.Servers["MARC-PI2010"];
                                        PIPoint myPIPoint = myServer.PIPoints["sinusoid"];
                                        //PIPoint myPIPoint = myServer.PIPoints["PIC_Truck_069.Fuel_Consumption.PV"];
                            
                                        NamedValues nvAttributes = new NamedValues();
                                        nvAttributes.Add("annotated", 1);
                                        nvAttributes.Add("annotations", 1);
                                        myPIPoint.Data.RetrievalAttributes = nvAttributes;
                                        
                                        PIValues myValues = myPIPoint.Data.RecordedValues("*-1d", "*", BoundaryTypeConstants.btAuto, "", FilteredViewConstants.fvRemoveFiltered);
                                        foreach (PIValue myVal in myValues)
                                        {
                                            NamedValues myValueAttributes = new NamedValues();
                                            if (Convert.ToBoolean(myVal.ValueAttributes["Annotated"].Value) == true)
                                            {
                                                NamedValue nvAnnotations = myVal.ValueAttributes["annotations"] as NamedValue;
                                                if (nvAnnotations.Value is PISDK.PIAnnotations)
                                                {
                                                    PISDK.PIAnnotations retAnns = (PISDK.PIAnnotations)nvAnnotations.Value;
                                                    foreach (PISDK.PIAnnotation curAnn in retAnns)
                                                    {
                                                        string annValue = curAnn.Value.ToString();
                                                        string annName = curAnn.Name.ToString();
                                                        string annDescription = curAnn.Description.ToString();
                                                        Console.WriteLine(annValue +"," + annName + "," + annDescription);
                                                    }
                                                }
                                   
                                                Console.WriteLine("true");
                                            }
                                            else
                                            {
                                                Console.WriteLine("false");
                                            }
                                        }
                            
                                        GC.KeepAlive(sdkroot);