VtrinLib Code Examples

Code snippets for VtrinLib methods usages.

1. How to connect History using VtrinLib

While passing password to this method please make sure it's passed with all the safety guidelines. Ex: User can read from the windows vaults or any other secure password storage vaults.

/// <summary>
        /// Connect to the RTDB Data source using VtrinLib API.
        /// </summary>
        /// <param name="connectionString">WSS connection string ex: wss://locahost/history</param>
        /// <param name="username">RTDB username</param>
        /// <param name="password">RTDB user password</param>
        /// <returns></returns>
        public static cMiaClient ConnectToTheDriver(string connectionString, string username, string password)
        {
            cDataLoader dataLoader = new()
            {
                ConnectOptions = cDataLoader.cConnectOptions.AcceptServerKeyChanges
            };

            var securePassword = GetPasswordString(password);
            cMiaClient mDriver = (cMiaClient)dataLoader.Connect(connectionString,
                       username,
                       securePassword,
                       cDataLoader.cConnectOptions.AcceptNewServerKeys);
            if (mDriver != null)
            {
                Logger.Log($"Vtrin connected successfully to {connectionString}");
            }
            else
            {
                var message = "Failed to connect to Vtrin with the current credentials";
                Logger.Log(message);
            }
            return mDriver;
        }

2. Add new Equipment to the Equipment Class

This method will add a new Equipment Model to the Equipment table. And the similar logic can be used to add a new instance to other classes as well. On successful addition of a new instance, returns the newly added instance object. The Equipment model is created with Path_XYZ in the Equipment classes.

/// <summary>
        /// Create a new Equipment Model with the specified name
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="equipmentName">Equipment Name</param>
        /// <returns>Returns the Equipment Model Instance object</returns>
        public static cDbClassInstance CreateANewEquipment(cDriverSkeleton driver, string equipmentName)
        {
            cDbClassInstance equipment = driver.Classes["Equipment"].Instances.Add();
            equipment.SetRawPropertyValue("Name", equipmentName);
            equipment.SetRawPropertyValue("Abstract", false);
            var instance = equipment.CommitChanges();
            return instance;
        }

3. Create a new Equipment Property in the Equipment Model

The below method helps to create a new Equipment Property with the required data type and other attributes in an existing Equipment model. Added few of the required parameters while creating Equipment Property, additional parameters can be added based on the requirement.

/// <summary>
        /// Creates a new Equipment Property in the Equipment Model
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="equipmentModel">Equipment Model</param>
        /// <param name="displayName">Property Display Name</param>
        /// <param name="description">Property Description</param>
        /// <param name="unit">Property Unit</param>
        /// <param name="type">Property Type. Ex: Double, Float, etc.</param>
        /// <param name="compressionMethod">Compression Method</param>
        /// <param name="isHistorized">To make the property historized</param>
        /// <param name="isArrayType">Set to make the property of array type</param>
        /// <param name="maxArrayLength">Max array length</param>
        /// <returns>Returns the Equipment Property GUID</returns>
        public static Guid CreateEquipmentProperty(cDriverSkeleton driver,
            cDbClassInstance equipmentModel,
            string displayName,
            string description,
            string unit,
            int type,
            CompressionMethod compressionMethod,
            bool isHistorized,
            bool isArrayType,
            int maxArrayLength = 50)
        {
            cDbClassInstance property = driver.Classes["EquipmentPropertyInfo"].Instances.Add();
            property.SetRawPropertyValue("DisplayName", displayName);
            property.SetRawPropertyValue("Description", description);
            property.SetRawPropertyValue("Unit", unit);
            property.SetRawPropertyValue("Approved", true);
            if (isHistorized)
            {
                property.SetRawPropertyValue("Historized", true);
            }
            else
            {
                property.SetRawPropertyValue("Historized", false);
            }
            if (isArrayType)
            {
                property.SetRawPropertyValue("MaxArrayLength", maxArrayLength);
            }
            property.SetRawPropertyValue("CompressionMethod", compressionMethod);
            property.SetRawPropertyValue("Equipment", equipmentModel.GetRawPropertyValue("Id"));
            property.SetRawPropertyValue("Type", type); //Example : Float = 13, Doule = 14
            property = property.CommitChanges();
            return ConvertToGuid(property.Id.ToString());
        }

4. Create a new instance of an equipment model

This method helps to create a new equipment instance of an existing equipment model. We need to specify the Equipment Model class and the parent item in the tree node where the equipment instance can be created.

/// <summary>
        /// Creates an instance of an existing equipment model
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="equipment">Equipment Model Instance</param>
        /// <param name="parentGuid">Parent GUID from the tree structure in which the instance can be created</param>
        /// <param name="instanceName">Equipment Instance name to be created</param>
        /// <returns>Returns the Equipment Instance object</returns>
        public static cDbClassInstance CreateEquipmentInstance(cDriverSkeleton driver,
            cDbClassInstance equipment,
            Guid parentGuid,
            string instanceName)
        {
            var clsnme = equipment.GetRawPropertyValue("Classname");
            cDbClassInstance instance = driver.Classes[clsnme].Instances.Add();
            instance.SetRawPropertyValue("Name", instanceName);
            instance.SetRawPropertyValue("DisplayName", instanceName);
            instance.SetRawPropertyValue("Parent", parentGuid);
            instance = instance.CommitChanges(true, true);
            return instance;
        }

5. Delete an Equipment from Equipment Class

This method removes an Equipment Model from the History if it's available.

/// <summary>
        /// Deletes an Equipment Model from History
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="equipmentModelName">Equipment Model Name to be deleted</param>
        public static void DeleteEquipmentModel(cDriverSkeleton driver, string equipmentModelName)
        {
            cDbClassInstance equipment = driver.Classes["Equipment"].Instances.GetInstanceByName(equipmentModelName);
            if (equipment != null)
            {
                equipment.BeginUpdate(true);
                equipment.Remove();
            }
            else
            {
                Logger.Log($"The Equipment Model {equipmentModelName} is not available in the History");
            }
        }

6. How to add a new Tree Item

The below method helps to add a new Tree item in the 'Equipment Model' parent tree item and returns the GUID of the tree item.

/// <summary>
        /// Adds a new Tree Item
        /// </summary>
        /// <param name="parentName">Parent Item Name</param>
        /// <param name="pathClass">DB Path Class</param>
        /// <returns></returns>
        public static Guid AddANewParentTreeItem(string parentName, cDbClass pathClass)
        {
            Guid guid;
            var newInstance = pathClass.Instances.Add();
            newInstance.SetRawPropertyValue("Id", ConvertToGuid(parentName));
            newInstance.SetRawPropertyValue("Name", parentName);
            newInstance.SetRawPropertyValue("DisplayName", parentName);
            pathClass.Instances.CommitChanges(new[] { newInstance });
            guid = (Guid)newInstance.Id;
            return guid;
        }

7. Delete a tree item from the root node

Below method helps to delete an item from the tree.

/// <summary>
        /// Deletes a Tree item
        /// </summary>
        /// <param name="driver"></param>
        /// <param name="parentName"></param>
        public static void DeleteEquipmentModelTreeItem(cDriverSkeleton driver,string parentName)
        {
            var pathClass = driver.Classes["Path"];
            var parentInstance = pathClass.Instances.GetInstanceByName(parentName);
            pathClass.Instances.Remove(parentInstance);
        }

8. Write values to a Variable History using the Graph Data iterator

Below example explains how to write values to Process History using the Graph Data Iterator. In this example we will write one value at a time for a specified Date Time. We will pass the list of values and list of date times to write values to the history. We make sure that list of dates are passed in the chronological order.

/// <summary>
        /// Write values to process history (variable) using the Graph Data iterator.
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="variableName">Variable Name</param>
        /// <param name="historyType">History type. Ex: Stream History or Current History</param>
        /// <param name="dateTimesList">Date Time range in which the values needs to be written</param>
        /// <param name="valuesList">Values list to be written in the Date Time duration</param>
        public static void WriteValuesToProcessHistoryWithGraphDataIterator(cDriverSkeleton driver,
            string variableName,
            string historyType,
            List<object> dateTimesList,
            List<object> valuesList)
        {
            var param = cGraphFetchParameters.CreateRawFetch(driver.Classes["ProcessHistory"],
                driver.MinTimeInUTC,
                driver.MaxTimeInUTC,
                int.MaxValue - 1,
                "Variable = ?  AND History = ?",
                variableName,
                historyType
                );
            var iterator = driver.GetGraphDataIterator(param);
            for (int i = 0; i < dateTimesList.Count; i++)
            {
                iterator.Write(dateTimesList[i], valuesList[i], cValueStatus.OK);
            }
            iterator1.Close();
            iterator1.Dispose();
        }

9 Write values to equipment history using the Graph Data iterator

Below example explains how to write values to Equipment History using the Graph Data Iterator. In this example we will write one value at a time for a specified Date Time. We make sure that list of dates are passed in the chronological order.

/// <summary>
        /// Write values to equipment history using the Graph Data iterator.
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="instanceName">Equipment Instance Name</param>
        /// <param name="property">Equipment Property Name</param>
        /// <param name="historyType">History type. Ex: Stream History or Current History</param>
        /// <param name="dateTimesList">Date Time range in which the values needs to be written</param>
        /// <param name="valuesList">Values list to be written in the Date Time duration</param>
        public static void WriteValuesToEquipmentHistoryWithGraphDataIterator(cDriverSkeleton driver,
            string instanceName,
            string property,
            string historyType,
            List<object> dateTimesList,
            List<object> valuesList)
        {
            var param = cGraphFetchParameters.CreateRawFetch(driver.Classes["EquipmentHistory"],
                driver.MinTimeInUTC,
                driver.MaxTimeInUTC,
                int.MaxValue - 1,
                "Path = ? AND Property = ? AND History = ?",
                instanceName,
                property,
                historyType
                );

            var iterator1 = driver.GetGraphDataIterator(param);
            for (int i = 0; i < dateTimesList.Count; i++)
            {
                iterator1.Write(dateTimesList[i], valuesList[i], cValueStatus.OK);
            }
            iterator1.Close();
            iterator1.Dispose();
        }

Below example will write values to history from a specified time period with specified period length.

/// <summary>
        /// Write values to equipment history using the Graph Data iterator.
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="instanceName">Equipment Instance Name</param>
        /// <param name="property">Equipment Property Name</param>
        /// <param name="historyType">History type. Ex: Stream History or Current History</param>
        /// <param name="dateTime">Date Time to which the values needs to be written</param>
        /// <param name="valuesList">Values list to be written in the Date Time duration</param>
        /// <param name="periodLength">X-Step between the values.</param>
        public static void WriteValuesToHistoryWithGraphDataIterator(cDriverSkeleton driver,
            string instanceName,
            string property,
            string historyType,
            object dateTime,
            Array valuesList,
            cAdvancedTimeSpan periodType)
        {
            var param = cGraphFetchParameters.CreateRawFetch(driver.Classes["EquipmentHistory"],
                driver.MinTimeInUTC,
                driver.MaxTimeInUTC,
                int.MaxValue - 1,
                "Path = ? AND Property = ? AND History = ?",
                instanceName,
                property,
                historyType);
            var iterator1 = driver.GetGraphDataIterator(param);
            iterator1.Write(dateTime, valuesList, cValueStatus.OK, periodType);
            iterator1.Close();
            iterator1.Dispose();
        }

10. Read data from Equipment history using the Graph Data iterator

Below example helps to ready values from Equipment History using the GetGraphDataIterator.

/// <summary>
        /// Read Values from Equipment history using the Graph Data iterator
        /// </summary>
        /// <param name="driver">Driver instance</param>
        /// <param name="startDateTime">Graph Start Time</param>
        /// <param name="endDateTime">Graph End Time</param>
        /// <param name="instanceName">Equipment Instance Name</param>
        /// <param name="property">Equipment Property Name</param>
        /// <param name="historyType">History Type, ex: StreamHistory or CurrentHistory</param>
        public static void ReadValuesFromEquipmentHistoryWithGraphDataIterator(cDriverSkeleton driver,
            DateTime startDateTime,
            DateTime endDateTime,
            string instanceName,
            string property,
            string historyType)
        {
            var param = cGraphFetchParameters.CreateRawFetch(driver.Classes["EquipmentHistory"],
                startDateTime,
                endDateTime,
                int.MaxValue - 1,
                "Path = ? AND Property = ? AND History = ?",
                instanceName,
                property,
                historyType);
            var iterator = driver.GetGraphDataIterator(param);
            try
            {
                //Print all the rows of data
                while (iterator.MoveNext())
                {
                    Logger.Log(iterator.XValue + ": " + iterator.YValue + ": " + iterator.Status);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }
            iterator.Close();
            iterator.Dispose();
        }

11. Fetch Graph Data (Equipment Property) with Filter

/// <summary>
/// Read Graph Data with Filter ex: MAX, AVG, AVG1MINUTE, etc
/// </summary>
/// <param name="driver">Driver instance</param>
/// <param name="filter">Filter ex: AVG, AVG1MINUTE, etc.</param>
/// <param name="startDateTime">Graph Start Time</param>
/// <param name="endDateTime">Graph End Time</param>
/// <param name="instanceName">Equipment Instance Name</param>
/// <param name="property">Equipment Property Name</param>
/// <param name="historyType">History Type, ex: StreamHistory or CurrentHistory</param>
public static void ReadValuesFromEquipmentHistoryWithGraphDataIteratorWithFilter(cDriverSkeleton driver,
    string filter,
    DateTime startDateTime,
    DateTime endDateTime,
    string instanceName,
    string property,
    string historyType)
{
    var param = cGraphFetchParameters.CreateRawFetch(driver.Classes["EquipmentHistory"],
        filter,
        startDateTime,
        endDateTime,
        int.MaxValue - 1,
        "Path = ? AND Property = ? AND History = ?",
        instanceName,
        property,
        historyType);
    var iterator = driver.GetGraphDataIterator(param);
    try
    {
        //Print all the rows of data
        while (iterator.MoveNext())
        {
            Logger.Log(iterator.XValue + ": " + iterator.YValue + ": " + iterator.Status);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.StackTrace);
    }
    iterator.Close();
    iterator.Dispose();
}

12. Fetch Graph Data (Variable) with Filter

/// <summary>
/// Read Graph Data with Filter ex: MAX, AVG, AVG1MINUTE, etc
/// </summary>
/// <param name="driver">Driver instance</param>
/// <param name="filter">Filter ex: AVG, AVG1MINUTE, etc.</param>
/// <param name="startDateTime">Graph Start Time</param>
/// <param name="endDateTime">Graph End Time</param>
/// <param name="variableName">Variable Name</param>
/// <param name="historyType">History Type, ex: StreamHistory or CurrentHistory</param>
public static void FetchGraphDataOfAVariableWithFilter(cDriverSkeleton driver,
    string filter,
    DateTime startDateTime,
    DateTime endDateTime,
    string variableName,
    string historyType)
{
    var param = cGraphFetchParameters.CreateRawFetch(driver.Classes["ProcessHistory"],
        filter,
        startDateTime,
        endDateTime,
        int.MaxValue - 1,
        "Name = ? AND History = ?",
        variableName,
        historyType);
    var iterator = driver.GetGraphDataIterator(param);
    try
    {
        //Print all the rows of data
        while (iterator.MoveNext())
        {
            Logger.Log(iterator.XValue + ": " + iterator.YValue + ": " + iterator.Status);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.StackTrace);
    }
    iterator.Close();
    iterator.Dispose();
}

13. Fetch Graph Data (Equipment Property) with Plot Filter

				/// <summary>
        /// Read Graph Data using PLOT Filter
        /// </summary>
        /// <param name="driver">Driver instance</param>
        /// <param name="startDateTime">Graph Start Time</param>
        /// <param name="endDateTime">Graph End Time</param>
				/// <param name="plotFilter">Plot Filter ex: PLOT(300,200), PLOT(400,300)</param>
        /// <param name="instanceName">Equipment Instance Name</param>
        /// <param name="property">Equipment Property Name</param>
        /// <param name="historyType">History Type, ex: StreamHistory or CurrentHistory</param>
        public static void FetchGraphDataWithPlotSizeFilter(cDriverSkeleton driver,
            DateTime startDateTime,
            DateTime endDateTime,
            string plotFilter,
            string instanceName,
            string property,
            string historyType)
        {
            var param = cGraphFetchParameters.CreateRawFetch(driver.Classes["EquipmentHistory"],
                plotFilter,
                startDateTime, 
                endDateTime, 
                int.MaxValue - 1, 
                "Path = ? AND Property = ? AND History = ?", 
                instanceName, property, historyType);
            var data = driver.FetchGraphData(param);
            foreach (cValueRecord record in data)
            {
                Console.WriteLine(record.XValue + ": " + record.Value + ": " + record.StatusResolved);
            }
        }

14. Fetch Graph Data (Variable) with Plot Filter

				/// <summary>
				/// Read Graph Data using PLOT Filter
				/// </summary>
				/// <param name="driver">Driver instance</param>
				/// <param name="startDateTime">Graph Start Time</param>
				/// <param name="endDateTime">Graph End Time</param>
				/// <param name="plotFilter">Plot Filter ex: PLOT(300,200), PLOT(400,300)</param
				/// <param name="variableName">Variable Name</param>
				/// <param name="historyType">History Type, ex: StreamHistory or CurrentHistory</param>
        public static void FetchGraphDataWithPlotFilter(cDriverSkeleton driver,
            DateTime startDateTime,
            DateTime endDateTime,
            string plotFilter,
            string variableName,
            string historyType)
        {
            var param = cGraphFetchParameters.CreateRawFetch(driver.Classes["ProcessHistory"],
                plotFilter,
                startDateTime, 
                endDateTime, 
                int.MaxValue - 1, 
                "Name = ? AND History = ?", 
                variableName, historyType);
            var data = driver.FetchGraphData(param);
            foreach (cValueRecord record in data)
            {
                Console.WriteLine(record.XValue + ": " + record.Value + ": " + record.StatusResolved);
            }
        }

15. Get the IDN of a variable

This method helps to get the unique IDN of the specified Variable. And this IDN can be used to write values to Current Value.

/// <summary>
        /// Get the IDN of the specified variable
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="variableName">Variable Name</param>
        /// <returns>Returns IDN of the variable</returns>
        public static object GetVariableIDN(cDriverSkeleton driver, string variableName)
        {
            var requiredVariable = driver.Classes["Variable"].Instances.GetInstanceSet($"Name={variableName}").First();
            var tagID = requiredVariable["ID"];
            return tagID;
        }

16.Get the IDN of an equipment property

The below method helps to get the IDN of an equipment property of a specified Equipment.

/// <summary>
        /// Get the IDN of the specified equipment property
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="equipmentName">Equipment Name</param>
        /// <param name="equipmentInstanceName">Equipment Instance Name</param>
        /// <param name="property">Property Name</param>
        /// <returns>Returns IDN of the equipment property</returns>
        public static object GetEquipmentPropertyIDN(cDriverSkeleton driver, string equipmentName, string equipmentInstanceName, string propertyName)
        {
            var instanceSetList = driver.Classes["Path" + "_" + equipmentName].Instances.GetInstanceSet().ToList();
            var instance = (from item in instanceSetList
                            where item.Name.Contains(equipmentInstanceName)
                            select item).First();
            var propertyIDN = driver.Classes[instance.Class].GetProperty(propertyName).GetLowLevelValue(instance);
            Logger.Log($"IDN is : {propertyIDN}");
            return propertyIDN;
        }

17. Write to the Current Value of Variable or Equipment property with their IDN

Below method helps to write current value to either Variable or Equipment property, IDN is the unique ID assigned by History to every Variable or Equipment property. IDN needs to be passed to FastCommitCurrentValues method as a parameter.

// 10590 - IDN of Variable or Equipment Property
// 10 - Value to be written
// DateTime - Current Time in UTC
// cValueStatus.Bad - Status Enum ex: OK, Bad,NoStatus, etc..
driver.FastCommitCurrentValues(10590, 10, DateTime.UtcNow, cValueStatus.Bad);

18. Write Array of values (Chronological order) using FastCommitCurrentValues.

Below example inserts values into the current value table, make sure that Date Times are in chronological order.

/// <summary>
        /// Write using FastCommitCurrentValues. Inserts values into the current value table, make sure that Date Times are in chronological order. 
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="IDN">Variable or Equipment Property IDN</param>
        /// <param name="values">Values list to be updated</param>
        /// <param name="dateTimes">List of dates and should be in the chronological order</param>
        /// <param name="cValueStatuses">Value Status</param>
        public static void UpdateCurrentValueToAVariableOrEquipmentProperty(cDriverSkeleton driver, object IDN, List<object> values, List<DateTime> dateTimes, List<cValueStatus> cValueStatuses)
        {
            int i = 0;
            foreach(var dateTime in dateTimes)
            {
                driver.FastCommitCurrentValues(IDN, values[i], dateTime, cValueStatuses[i]);
                i++;
            }
        }

19. Get Current Value of an equipment property based on equipment instance name

Below method helps to get the current value of an equipment property from an equipment instance. Pass the equipment process path completely to get the current value.

/// <summary>
        /// Get current value of the specified equipment property
        /// </summary>
        /// <param name="driver">Driver</param>
        /// <param name="equipmentName">Equipment Name</param>
        /// <param name="equipmentInstanceName">Equipment Instance Name</param>
        /// <param name="property">Property Name</param>
        /// <returns>Returns IDN of the equipment property</returns>
        public static object GetCurrentValue(cDriverSkeleton driver, string equipmentInstanceName, string propertyName)
        {
            var currentvalue = driver.Classes["Path"].Instances.GetInstanceByName(equipmentInstanceName)[propertyName];
            return currentvalue;
        }

20. Get current value of equipment property based on IDN

Below example will get Current Value of an Equipment property based on IDN. Please refer the example Example 15 - To get the IDN of Equipment Property

var idn = 10719; //This is the Equipment Property IDN
var cv1 = (cDbCurrentValue)driver.Classes["CurrentValue"].Instances[idn];
Console.WriteLine(cv1.StatusResolved + ":: " + "Formatted Status :: "+cv1.FormattedStatus + ":: " + cv1.StatusReasonResolved);
Console.WriteLine(cv1.FormattedTime);
Console.WriteLine(cv1.FormattedValue);

21. Write Events to RTDB OPCEvent Table

The below code example writes Events to RTDB OpcEvent Table with attributes. The attributes are also generated from the code.

private static string CreateOPCEvents(cDriverSkeleton driver, string baseName)
        {
            // Generate a unique identifier (timestamp or GUID)
            string uniqueId = Guid.NewGuid().ToString(); 

            // Combine base name and unique ID
            string uniqueName = $"{baseName}_{uniqueId}";
            var eventAttributes = GenerateAttributes();
            var pathClass = driver.Classes["OpcEvent"];
            var newInstance = pathClass.Instances.Add();
            newInstance.SetRawPropertyValue("EventTime", DateTime.UtcNow);
            newInstance.SetRawPropertyValue("Source", "Automation Test");
            newInstance.SetRawPropertyValue("Message", uniqueName);
            newInstance.SetRawPropertyValue("Attributes", eventAttributes);
            pathClass.Instances.CommitChanges(new[] { newInstance });

            // Return the unique name for further use
            return uniqueName;
        }

//Generate Attributes dictionary with random values.
private static Dictionary<string, object> GenerateAttributes()
        {
            // Method to generate a random alphanumeric string
            string GenerateRandomString(int length)
            {
                const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
                var random1 = new Random();
                char[] buffer = new char[length];
                for (int i = 0; i < length; i++)
                {
                    buffer[i] = chars[random1.Next(chars.Length)];
                }
                return new string(buffer);
            }

            // Method to generate a GUID
            string GenerateGUID() => Guid.NewGuid().ToString();

            // Generate random values
            var random = new Random();

            // Initialize and return the dictionary
            return new Dictionary<string, object>
        {
            { "Class", "Class:0" },
            { "ActionDate",DateTime.UtcNow},
            { "Hidden", false },
            { "SourceName", $"SourceName:{GenerateGUID()}" },
            { "SourceServer", $"SourceServer:{GenerateRandomString(16)}" },
            { "ChangeMask", $"ChangeMask:{random.Next(1, 100)}" },
            { "NewState", 1 },
            { "Message", "Alarm inactivated" },
            { "CategoryId",  random.Next(100, 200)},
            { "EventType", 4 },
            { "EventCategory", 2888472444 },
            { "Severity", 1 },
            { "ConditionName", "condition-Alarm Expression" },
            { "SubConditionName", "Subcondition" },
            { "Quality", 192 },
            { "AckRequired", true },
            { "ActiveTime", DateTime.Now.AddMinutes(-random.Next(0, 1000)) },
            { "Cookie", 9 },
            { "Comment", "Test Comment" },
            { "BlockedRepetitive", false },
            { "ObjectDescription", "Test Description" },
            { "AutoDisabled", false },
            { "ActiveChangeTime", DateTime.Now.AddMinutes(-random.Next(0, 1000)) },
            { "HidingMaskName", "" },
            { "AckLowTime", 0 },
            { "GroupAlarm", false },
            { "GroupAlarmIds", new int[1,2,3] },
            { "HidingMaskId", GenerateGUID() },
            { "ResponsibilitySection", "TEST" },
            { "GroupAlarmNames", "Names" },
            { "HidingMaskCondition", null },
            { "Responsibility", "Operation" },
            { "ResponsibleNode", "ResponsibleNode:" },
            { "AlarmState", "AlarmState:RTN" },
            { "AckHighTime", DateTime.Now.AddMinutes(-random.Next(0, 1000)) },
            { "ResponsibleUser", "ResponsibleUser:" },
            { "ShelvingReason", "ShelvingReason:" },
            { "Shelved", false },
            { "ResponsibleUserId", 10 },
            { "Flags", 0 },
            { "ServiceGroupId", $"ServiceGroupId:{GenerateGUID()}" },
            { "PriorityLevel", "PriorityLevel:4" },
            { "ResponsibilityId", GenerateGUID() },
            { "HidingRuleCondition", "10" },
            { "ShelvingMode", 2 },
            { "ObjectName", "SIGNAL0001" },
            { "AlarmChange", "Inactive" },
            { "HidingRuleId", 122},
            { "SourceGUID", GenerateGUID()}
        };
        }

22. How to update 'UpdateHistory' table

Below example explains how to update 'UpdateHistory' table so that data in all the higher level tables will be updated.

var timestamp = DateTime.Now;
var uh = Driver.Classes["UpdateHistory"].Instances.Add();
//Updates the AVG1Month history table
uh["History"] = Driver.Classes["History"].Instances.GetInstanceByName("CurrentHistory"); 
//10590 - is the IDN of a variable
uh.SetRawPropertyValue("Variable", 10590);
uh.SetRawPropertyValue("StartValue", 190);
uh.SetRawPropertyValue("EndValue", 200);
uh.SetRawPropertyValue("CallMode", 1);
uh.SetRawPropertyValue("Function", 2);
uh.SetRawPropertyValue("ItemType", 9);
uh.SetRawPropertyValue("StartTime", timestamp.AddMinutes(-30)); //Make update around the normal write range
uh.SetRawPropertyValue("EndTime", timestamp.AddMinutes(0));
uh.SetRawPropertyValue("Comment", "Update from Automated simulation"); //Default is System.String.Empty  
uh.SetRawPropertyValue("AllowOverwriting", true);
uh.CommitChanges();

23. Fetch OPC Events from the OPC Event table

Below example explains how a user can fetch OPC Events from the Database and print them to the console. If user wanted to filter the OPC Events based on Vendor specific attributes can refer to the example here

DateTime time1 = DateTime.UTCNow.AddMinutes(-60);
DateTime time2 = DateTime.UTCNow.AddMinutes(0);

//1. Get OPC Events Based on the Time Range
string whereStringOPCEvents = "EventTime >= ? AND EventTime <= ?";
var opcEvents = Driver.Classes["OPCEvent"].Instances.GetInstanceSet(whereStringOPCEvents, time1, time2);

foreach (var opcEvent in opcEvents)
{
    foreach (var attribute in opcEvent["Attributes"] as Dictionary<string, object>)
    {
        var attName = Driver.Classes["OPCEvent"].GetProperty(attribute.ToString()).DisplayName;
        var attValue = attribute.Value;
        Console.WriteLine(attName + "::" + attValue);
    }
}