Click or drag to resize
OSIsoft, LLC

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: 2.10.6.195
Syntax
public class AFAnnotation : IEquatable<AFAnnotation>

The AFAnnotation type exposes the following members.

Constructors
  NameDescription
Public methodAFAnnotation
Initializes a new instance of the class with an owner.
Top
Properties
  NameDescription
Public propertyAttachment
An AFFile that is attached to the annotation.
Public propertyCreationDate
The time when the annotation was created.
Public propertyCreator
The user who created the annotation.
Public propertyDescription
A property that provides a more detailed description of the annotation.
Public propertyID
The unique identifier for the annotation.
Public propertyIsDeleted
This read-only property indicates whether the object has been deleted.
Public propertyModifier
The user who last modified the annotation.
Public propertyModifyDate
The time when the annotation was last modified.
Public propertyName
A property that provides the name for the annotation.
Public propertyOwner
The AFObject to which the AFAnnotation belongs.
Public propertyValue
The value of the annotation.
Top
Methods
  NameDescription
Public methodDelete
Immediately removes this AFAnnotation from the server.
Public methodEquals(Object)
Determines whether the specified Object is equal to the current object.
(Overrides ObjectEquals(Object).)
Public methodEquals(AFAnnotation)
Indicates whether the current object is equal to another object of the same type.
Public methodGetHashCode
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 methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodStatic memberLoadAnnotations
Retrieves the AFAnnotation objects belonging to the specified owning objects.
Public methodSave
Immediately commits this AFAnnotation to the server.
Public methodStatic memberSave(IListAFAnnotation)
Immediately commits the list of AFAnnotation objects to the server.
Public methodToString
Returns a String that represents the current object.
(Overrides ObjectToString.)
Top
Operators
  NameDescription
Public operatorStatic memberEquality
The equality operator (==) compares its operands to determine if they are equal.
Public operatorStatic memberInequality
The inequality operator (!=) compares its operands to determine if they are not equal.
Top
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 only available in the .NET 4 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);
/// <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);
        }
    }
}
// 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);
}
Version Information

AFSDK

Supported in: 2.10.5, 2.10, 2.9.5, 2.9, 2.8.5, 2.8, 2.7.5, 2.7, 2.6, 2.5
See Also
Enabling Operational Intelligence