Please ensure Javascript is enabled for purposes of website accessibility
Powered by Zoomin Software. For more details please contactZoomin

AF SDK Reference

AFAnnotation Class

  • Last UpdatedNov 18, 2025
  • 11 minute read
AFAnnotation Class
The structured AFAnnotation object is used to read and create annotations associated with historical data events of an AFAttribute as well as to read and create annotations associated with asset based objects such as an AFEventFrame or AFElement.

Inheritance Hierarchy

SystemObject
  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

  NameDescription
Public method
AFAnnotation
Initializes a new instance of the class with an owner.

Properties

  NameDescription
Public property
Attachment
An AFFile that is attached to the annotation.
Public property
CreationDate
The time when the annotation was created.
Public property
Creator
The user who created the annotation.
Public property
Description
A property that provides a more detailed description of the annotation.
Public property
ID
The unique identifier for the annotation.
Public property
IsDeleted
This read-only property indicates whether the object has been deleted.
Public property
Modifier
The user who last modified the annotation.
Public property
ModifyDate
The time when the annotation was last modified.
Public property
Name
A property that provides the name for the annotation.
Public property
Owner
The AFObject to which the AFAnnotation belongs.
Public property
Value
The value of the annotation.

Methods

  NameDescription
Public method
Delete
Immediately removes this AFAnnotation from the server.
Public method
Equals(Object)
Determines whether the specified Object is equal to the current object.
(Overrides ObjectEquals(Object).)
Public method
Equals(AFAnnotation)
Indicates whether the current object is equal to another object of the same type.
Public method
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.)
Public method
GetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodStatic member
LoadAnnotations
Retrieves the AFAnnotation objects belonging to the specified owning objects.
Public method
Save
Immediately commits this AFAnnotation to the server.
Public methodStatic member
Save(IListAFAnnotation)
Immediately commits the list of AFAnnotation objects to the server.
Public method
ToString
Returns a String that represents the current object.
(Overrides ObjectToString.)

Operators

  NameDescription
Public operatorStatic member
Equality
The equality operator (==) compares its operands to determine if they are equal.
Public operatorStatic member
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.

Important note Important
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.

Important note Important
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.
Caution note Caution
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.

Note Notes to Callers
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.

Version Information

AFSDK


See Also

TitleResults for “How to create a CRG?”Also Available in