AFAnnotation Class
- Last UpdatedNov 18, 2025
- 11 minute read
- PI System
- AF SDK 2024 R2
- Developer

Inheritance Hierarchy
OSIsoft.AF.DataAFAnnotation
Namespace: OSIsoft.AF.Data
Assembly: OSIsoft.AFSDK (in OSIsoft.AFSDK.dll) Version: 3.1.1.1182
Syntax
public class AFAnnotation : IEquatable<AFAnnotation>
Public Class AFAnnotation Implements IEquatable(Of AFAnnotation) Dim instance As AFAnnotation
public ref class AFAnnotation : IEquatable<AFAnnotation^>
type AFAnnotation = class interface IEquatable<AFAnnotation> end
The AFAnnotation type exposes the following members.
Constructors
| Name | Description | |
|---|---|---|
| AFAnnotation |
Initializes a new instance of the class with an owner.
|
Properties
| Name | Description | |
|---|---|---|
| Attachment |
An AFFile that is attached to the annotation.
| |
| CreationDate |
The time when the annotation was created.
| |
| Creator |
The user who created the annotation.
| |
| Description |
A property that provides a more detailed description of the annotation.
| |
| ID |
The unique identifier for the annotation.
| |
| IsDeleted |
This read-only property indicates whether the object has been deleted.
| |
| Modifier |
The user who last modified the annotation.
| |
| ModifyDate |
The time when the annotation was last modified.
| |
| Name |
A property that provides the name for the annotation.
| |
| Owner |
The AFObject to which the AFAnnotation belongs.
| |
| Value |
The value of the annotation.
|
Methods
| Name | Description | |
|---|---|---|
| Delete |
Immediately removes this AFAnnotation from the server.
| |
| Equals(Object) |
Determines whether the specified Object is equal to the current object.
(Overrides ObjectEquals(Object).) | |
| Equals(AFAnnotation) |
Indicates whether the current object is equal to another object of the same type.
| |
| GetHashCode |
Gets the hash code for this instance of the object which is suitable for use in hashing
algorithms and data structures like a hash table.
(Overrides ObjectGetHashCode.) | |
| GetType | Gets the Type of the current instance. (Inherited from Object.) | |
| LoadAnnotations |
Retrieves the AFAnnotation objects belonging to the specified owning objects.
| |
| Save |
Immediately commits this AFAnnotation to the server.
| |
| Save(IListAFAnnotation) |
Immediately commits the list of AFAnnotation objects to the server.
| |
| ToString |
Returns a String that represents the current object.
(Overrides ObjectToString.) |
Operators
| Name | Description | |
|---|---|---|
| Equality |
The equality operator (==) compares its operands to determine if they are equal.
| |
| Inequality |
The inequality operator (!=) compares its operands to determine if they are not equal.
|
Remarks
Annotations may be associated with historical data events or asset based objects, such as AFEventFrame or AFElement. While the mechanism and fields for retrieving and updating these two different types of annotations differ, the annotations for both can be represented by this AFAnnotation object.
Annotations associated with historical data events may be of two forms: simple or structured. Simple annotations are typically a single string, but may also be any basic type. The AFAnnotation object is not used to represent simple annotations for historical data events. Simple annotations are created or updated by passing the value to the AFValue.SetAnnotation method and then writing the AFValue to the attribute. Both simple and structured historical event annotations are returned from the AFValue.GetAnnotation method.
Historical structured annotations are returned as an AFAnnotations collection from the AFValue.GetAnnotation method. This collection allows for multiple annotations on a single event. The AFAnnotation object provides data fields for capturing the user, time stamp, and other information for each annotation in the collection. Annotations associated with historical values should be created using the Add(String, Object) method of AFAnnotations. The AFAnnotations collection is then written back to the value via AFValue.SetAnnotation and then persisted using one of the attribute update methods. Typically, only attributes with an associated PIPoint can read or write historical annotations.
| Support for PIProperties in a structured annotations created by the PI SDK has been removed. Any existing PIProperties will not be read and will be lost after updating the annotation. |
Annotations can also be associated with any AFBaseElement, such as an AFEventFrame or AFElement. The EventFrameAcknowledgement feature can be checked to determine if the server supports annotations on elements. These annotations are accessed via the GetAnnotations method of AFBaseElement. Asset-based annotations are always structured. They are saved to storage via one of the Save Overload methods (this method does not apply to historical event based annotations). The Delete method can be used to delete an asset-based annotation.
| Annotations are not loaded with the value, event frame, or element they decorate and thus they should not be used by applications which may need to access them in bulk. Annotations should not be used to maintain long running histories as they are not designed for this purpose. |
| The Value property of an asset-based annotation will only accept a string data type. The following properties can never be set for asset-based annotations: ID, ModifyDate, Modifier. The following properties can only be set for asset-based annotations that are for new objects that have not been saved to the server: CreationDate, Creator. All properties can be set for a PIPoint annotation except for the Attachment property. |
| This method, property, or class is not available in the legacy .NET 3.5 version of the SDK. |
Examples
// This example demonstrates how to create an attribute for an // element and retrieve and set annotations on values. // Get the Database PISystems myPISystems = new PISystems(); PISystem myPISystem = myPISystems.DefaultPISystem; AFDatabase myDB = myPISystem.Databases.DefaultDatabase; // Create an Element AFElement myElement = myDB.Elements.Add("MyElement"); // Create an Attribute AFAttribute myAttribute = myElement.Attributes.Add("MyAttribute"); myAttribute.DefaultUOM = myPISystem.UOMDatabase.UOMs["kelvin"]; myAttribute.DataReferencePlugIn = AFDataReference.GetPIPointDataReference(myPISystem); myAttribute.ConfigString = @"\\%Server%\sinusoid;ReadOnly=False"; // Create New Simple Annotation AFValue myValue1 = new AFValue(155.432, AFTime.Now); myValue1.SetAnnotation("New Event with Simple Annotation"); myAttribute.Data.UpdateValue(myValue1, AFUpdateOption.InsertNoCompression); // Update an Existing Annotation myValue1.SetAnnotation(100); myAttribute.Data.UpdateValue(myValue1, AFUpdateOption.Replace); // Create an AFFile to be used as an Annotation value string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "TestFile.txt"); using (System.IO.File.Create(path)) { } AFFile myFile = new AFFile(); myFile.Upload(path); // Create New Structured Annotation AFAnnotations myAnnotations = new AFAnnotations(); AFValue myValue2 = new AFValue(255.543); AFAnnotation myAnnotation = myAnnotations.Add("Annotation#1", 400.456); myAnnotation.Description = "1st Annotation is a Double."; myAnnotation = myAnnotations.Add("Annotation#2", "My Annotation Value"); myAnnotation.Description = "2nd Annotation is a String."; myAnnotation = myAnnotations.Add("Annotation#3", myFile); myAnnotation.Description = "3rd Annotation is an AFFile."; myValue2.SetAnnotation(myAnnotations); myAttribute.Data.UpdateValue(myValue2, AFUpdateOption.InsertNoCompression); // Read Annotations object theAnnotation = myValue1.GetAnnotation(); DisplayAnnotation(myValue1, theAnnotation); theAnnotation = myValue2.GetAnnotation(); DisplayAnnotation(myValue2, theAnnotation); AFValue myValue = myAttribute.GetValue(); theAnnotation = myValue.GetAnnotation(); DisplayAnnotation(myValue, theAnnotation);
' This example demonstrates how to create an attribute for an ' element and retrieve and set annotations on values. ' Get the Database Dim myPISystems As New PISystems Dim myPISystem As PISystem = myPISystems.DefaultPISystem Dim myDB As AFDatabase = myPISystem.Databases.DefaultDatabase ' Create An Element Dim myElement As AFElement = myDB.Elements.Add("MyElement") ' Create an Attribute Dim myAttribute As AFAttribute = myElement.Attributes.Add("MyAttribute") myAttribute.DefaultUOM = myPISystem.UOMDatabase.UOMs("Kelvin") myAttribute.DataReferencePlugIn = AFDataReference.GetPIPointDataReference(myPISystem) myAttribute.ConfigString = "\\%Server%\sinusoid;ReadOnly=False" ' Create New Simple Annotation Dim myValue1 As AFValue = New AFValue(155.432, AFTime.Now) myValue1.SetAnnotation("New Event with Simple Annotation") myAttribute.Data.UpdateValue(myValue1, AFUpdateOption.InsertNoCompression) ' Update an Existing Annotation myValue1.SetAnnotation(100) myAttribute.Data.UpdateValue(myValue1, AFUpdateOption.Replace) ' Create an AFFile to be used as an Annotation value Dim path As String = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "TestFile.txt") Dim fs As FileStream = System.IO.File.Create(path) fs.Close() Dim myFile As AFFile = New AFFile myFile.Upload(path) ' Create New Structured Annotation Dim myAnnotations As AFAnnotations = New AFAnnotations Dim myValue2 As AFValue = New AFValue(255.543) Dim myAnnotation As AFAnnotation = myAnnotations.Add("Annotation#1", 400.456) myAnnotation.Description = "1st Annotation is a Double." myAnnotation = myAnnotations.Add("Annotation#2", "My Annotation Value") myAnnotation.Description = "2nd Annotation is a String." myAnnotation = myAnnotations.Add("Annotation#3", myFile) myAnnotation.Description = "3rd Annotation is an AFFile." myValue2.SetAnnotation(myAnnotations) myAttribute.Data.UpdateValue(myValue2, AFUpdateOption.InsertNoCompression) ' Read Annotations Dim theAnnotation As Object = myValue1.GetAnnotation DisplayAnnotation(myValue1, theAnnotation) theAnnotation = myValue2.GetAnnotation DisplayAnnotation(myValue2, theAnnotation) Dim myValue As AFValue = myAttribute.GetValue theAnnotation = myValue.GetAnnotation DisplayAnnotation(myValue, theAnnotation)
No code example is currently available or this language may not be supported.
No code example is currently available or this language may not be supported.
/// <summary> /// Display information about the annotated value. /// </summary> /// <param name="theValue"> /// The AFValue associated with the specified annotation value. /// </param> /// <param name="theAnnotation"> /// The annotation value associated with the specified AFValue. /// </param> static private void DisplayAnnotation(AFValue theValue, object theAnnotation) { AFAnnotations theAnnotations = theAnnotation as AFAnnotations; if (theAnnotations == null) { Console.WriteLine("Simple Annotation for Value '{0}' = '{1}'", theValue, theAnnotation); } else { Console.WriteLine("Structured Annotation for Value '{0}':", theValue); foreach (AFAnnotation item in theAnnotations) { Console.WriteLine(" Value = '{0}', Description = '{1}', Creator = '{2}'", item.Value, item.Description, item.Creator); } } }
''' <summary> ''' Display information about the annotated value. ''' </summary> ''' <param name="theValue"> ''' The AFValue associated with the specified annotation value. ''' </param> ''' <param name="theAnnotation"> ''' The annotation value associated with the specified AFValue. ''' </param> Private Shared Sub DisplayAnnotation(ByVal theValue As AFValue, ByVal theAnnotation As Object) Dim theAnnotations As AFAnnotations = TryCast(theAnnotation, AFAnnotations) If (theAnnotations Is Nothing) Then Console.WriteLine("Simple Annotation for Value '{0}' = '{1}'", theValue, theAnnotation) Else Console.WriteLine("Structured Annotation for Value '{0}':", theValue) For Each item As AFAnnotation In theAnnotations Console.WriteLine(" Value = '{0}', Description = '{1}', Creator = '{2}'", item.Value, item.Description, item.Creator) Next End If End Sub
No code example is currently available or this language may not be supported.
No code example is currently available or this language may not be supported.
// This example demonstrates how to create an annotation // for an Event Frame. // Get the Database. PISystems myPISystems = new PISystems(); PISystem myPISystem = myPISystems.DefaultPISystem; AFDatabase myDB = myPISystem.Databases.DefaultDatabase; // Create an Event Frame and check it in. AFEventFrame myEventFrame = new AFEventFrame(myDB, "MyEventFrame"); myEventFrame.CheckIn(); // Create New Annotation. AFAnnotation myAnnotation = new AFAnnotation(myEventFrame); myAnnotation.Name = "My Annotation"; myAnnotation.Value = "Initial Comment"; myAnnotation.Save(); // Update an Existing Annotation. myAnnotation.Value = "Updated Comment"; myAnnotation.Save(); // Attach an AFFile to the annotation. string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "TestFile.txt"); using (System.IO.File.Create(path)) { } AFFile myFile = new AFFile(); myFile.Upload(path); myAnnotation.Attachment = myFile; myAnnotation.Save(); // Add Another Annotation. AFAnnotation myAdditionalAnnotation = new AFAnnotation(myEventFrame); myAdditionalAnnotation.Name = "My Annotation"; myAdditionalAnnotation.Value = "Addition Comment"; myAdditionalAnnotation.Save(); // Read Annotations IList<AFAnnotation> theAnnotationCollection = myEventFrame.GetAnnotations(); foreach (AFAnnotation theAnnotation in theAnnotationCollection) { Console.WriteLine("Annotation for Event Frame '{0}' = '{1}'", myEventFrame.Name, theAnnotation.Value); }
' This example demonstrates how to create an annotation ' for an Event Frame. ' Get the Database Dim myPISystems As New PISystems Dim myPISystem As PISystem = myPISystems.DefaultPISystem Dim myDB As AFDatabase = myPISystem.Databases.DefaultDatabase ' Create an Event Frame and check it in. Dim myEventFrame As New AFEventFrame(myDB, "MyEventFrame") ' Create New Annotation Dim myAnnotation As New AFAnnotation(myEventFrame) myAnnotation.Name = "My Annotation" myAnnotation.Value = "Initial Comment" myAnnotation.Save() ' Update an Existing Annotation myAnnotation.Value = "Updated Comment" myAnnotation.Save() ' Create an AFFile to be used as an Annotation value Dim path As String = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "TestFile.txt") Dim fs As FileStream = System.IO.File.Create(path) fs.Close() Dim myFile As AFFile = New AFFile myFile.Upload(path) myAnnotation.Attachment = myFile myAnnotation.Save() ' Add Another Annotation myAnnotation = New AFAnnotation(myEventFrame) myAnnotation.Name = "My Annotation" myAnnotation.Value = "Additional Comment" myAnnotation.Save() ' Read Annotations Dim theAnnotationCollection As IList(Of AFAnnotation) = myEventFrame.GetAnnotations() For Each theAnnotation As AFAnnotation In theAnnotationCollection Console.WriteLine("Annotation for Event Frame '{0}' = '{1}'", myEventFrame.Name, theAnnotation.Value) Next
No code example is currently available or this language may not be supported.
No code example is currently available or this language may not be supported.