3 Replies Latest reply on Jul 29, 2016 12:27 PM by gregor

    Getting Notification Instances from a target element


      I can't seem to get my code to retrieve instance(s) of a Notification that I may display the results.  I've isolated an element with notifications historized as can be seen using PI-Explorer.

      With the code below I get an Exception fault on the line "GetLastInstance" or previously "GetInstances" (line 28, 30) .  Same exception for either method (see below code).  Any pointers or comments greatly appreciated.


      1.       private void SearchNotifications3()
      2.         {
      3.             AFDatabase myAFDB;
      4.             AFElement tmpElement;
      5.             AFFindElement AFfecntr;
      6.             AFNamedCollection<AFNotification> myNots;
      7.             OSIsoft.AF.Time.AFTime StartTime = new OSIsoft.AF.Time.AFTime("*");
      8.             OSIsoft.AF.Time.AFTime EndTime = new OSIsoft.AF.Time.AFTime("*-7d");
      9.             // Example AFNotification.FindNotificationsByElement
      10.             // Get an AFElement where we know we have notifications
      11.             AFfecntr = new AFFindElement(); // new helper form with find control
      12.             myAFDB = afDatabasePicker1.AFDatabase;
      13.             AFfecntr.afFE.Database = myAFDB;
      14.             tmpElement = AFfecntr.afFE.GetElement("HMRoot\\PIL1");
      15.             ANNotificationList notificationList = new ANNotificationList
      16.                      (tmpElement.GetNotifications(AFSortField.StartTime, AFSortOrder.Ascending, 32));
      17.             myNots = tmpElement.GetNotifications(AFSortField.StartTime, AFSortOrder.Ascending, 32);
      18.             foreach (AFNotification myNot in myNots)
      19.             {
      20.                 // transmute the AFNotification to an ANNotification object
      21.                 ANNotification myAnNotification = new ANNotification(myNot);
      22.                 ANInstance myinstance = myAnNotification.GetLastInstance();
      23.                 // now we should be able to GetInstances
      24.                 ANInstances instances = myAnNotification.GetInstances(StartTime, EndTime);
      25.                 foreach (ANInstance myInstance in instances)
      26.                 {
      27.                     LogMsg(myNot.Target.ToString() + " " +
      28.                             myInstance.StartTime.LocalTime.ToString() + "  " +
      29.                             myInstance.EndTime.LocalTime.ToString() + "  " +
      30.                             myInstance.State.Name );
      31.                 }
      32.             }
      33.         }

      Exception information: 

      System.TypeInitializationException was unhandled


        Message=The type initializer for 'OSIsoft.AN.Notification.ANNotificationHistoryManager' threw an exception.




             at OSIsoft.AN.Notification.ANNotificationHistoryManager.GetLastInstance(AFNotification notification, ANGetInstanceMode activeInstance, ANGetInstanceMode nonActiveInstance)

             at OSIsoft.AN.Notification.ANNotification.GetLastInstance() in c:\Builds\152\PIANO\Notifications 1.2.1205 Nightly\Sources\1.2.1205\Library\ANSDK\Notification\ANNotification.cs:line 454

             at MdbInterfaceAF.MDBImport.SearchNotifications3() in C:\Projects\MdbInterfaceImportAF\MdbInterfaceAF\MdbInterfaceAF\MDBImport.cs:line 127

             at MdbInterfaceAF.MDBImport.ImportBtn_Click(Object sender, EventArgs e) in C:\Projects\MdbInterfaceImportAF\MdbInterfaceAF\MdbInterfaceAF\MDBImport.cs:line 84

             at System.Windows.Forms.Control.OnClick(EventArgs e)

             at System.Windows.Forms.Button.OnClick(EventArgs e)

             at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)

             at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)

             at System.Windows.Forms.Control.WndProc(Message& m)

             at System.Windows.Forms.ButtonBase.WndProc(Message& m)

             at System.Windows.Forms.Button.WndProc(Message& m)

             at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

             at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

             at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

             at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)

             at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)

             at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)

             at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)

             at System.Windows.Forms.Application.Run(Form mainForm)

             at MdbInterfaceAF.Program.Main() in C:\Projects\MdbInterfaceImportAF\MdbInterfaceAF\MdbInterfaceAF\Program.cs:line 19

             at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)

             at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)

             at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

             at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

             at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)

             at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)

             at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

             at System.Threading.ThreadHelper.ThreadStart()



             Message=Unable to cast object of type 'System.__ComObject' to type 'PISDK.PISDKClass'.



                  at OSIsoft.AN.Notification.ANNotificationHistoryManager..cctor() in c:\Builds\152\PIANO\Notifications 1.2.1205 Nightly\Sources\1.2.1205\Library\ANSDK\Notification\ANNotificationHistoryManager.cs:line 60


        • Re: Getting Notification Instances from a target element
          Mike Zboray

          It sounds like you don't have PISDK installed given that the inner exception says "Unable to cast object of type 'System.__ComObject' to type 'PISDK.PISDKClass'."

          One other comment is don't use the instance methods on ANNotification in your code. Use the static methods ANNotification.GetInstances or GetLastInstance to find instances. The instance methods are the implementations that the Notifications service uses to handle the corresponding calls.

            • Re: Getting Notification Instances from a target element

              Thanks Mike... Not the correct answer but got me thinking.  I made some changes to the Assembly reference  and got the following warning:


              SeverityCodeDescriptionProjectFileLineSuppression State
              WarningThere was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "OSIsoft.PISDK, Version=, Culture=neutral, PublicKeyToken=c3309f0734ba2805, processorArchitecture=x86", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.MdbInterfaceAF


              I'm curious what Processor, target framework and assembly versions I should be using for this query.

                • Re: Getting Notification Instances from a target element

                  Hello John,


                  With the AF Client installation, there are 2 different AF SDK assemblies installed. A legacy one and a pure .NET library that we also refer to as Rich Data Access (RDA). The legacy version uses PI SDK to communicate to the PI Data Archive while the RDA version doesn't even require PI SDK being installed.

                  PI SDK itself comes with a 32-bit and a 64-bit library. The Warning you see is just a warning e.g. because your project is targeting "Any CPU".


                  I suggest you verify if you have the RDA version of AF SDK referenced. When you verify the existing Visual Studio project references, you should see If you instead see,, please remove that reference and browse for the RDA version in %PIHOME%\AF\PublicAssemblies\4.0