OPC Studio User's Guide and Reference
EasyDAItemChangedEventArgs Class
Members  Example 



OpcLabs.EasyOpcClassicCore Assembly > OpcLabs.EasyOpc.DataAccess.OperationModel Namespace : EasyDAItemChangedEventArgs Class
Provides data for the EasyDAClient.ItemChanged event.
Object Model
EasyDAItemChangedEventArgs ClassEasyDAItemSubscriptionArguments ClassEasyDAItemSubscriptionArguments ClassExceptionCollection ClassNormalizedExceptionCollection ClassNormalizedException ClassNormalizedException ClassDAVtq Class
Syntax
'Declaration
 
<CLSCompliantAttribute(True)>
<ComDefaultInterfaceAttribute(OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemChangedEventArgs)>
<ComVisibleAttribute(True)>
<GuidAttribute("B93B886F-19E6-4049-9731-2E1DEEC5E0CD")>
<TypeConverterAttribute(System.ComponentModel.ExpandableObjectConverter)>
<SerializableAttribute()>
Public Class EasyDAItemChangedEventArgs 
   Inherits OpcLabs.BaseLib.OperationModel.OperationEventArgs
   Implements OpcLabs.BaseLib.OperationModel.ComTypes._OperationEventArgs, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemChangedEventArgs, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable 
'Usage
 
Dim instance As EasyDAItemChangedEventArgs
[CLSCompliant(true)]
[ComDefaultInterface(OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemChangedEventArgs)]
[ComVisible(true)]
[Guid("B93B886F-19E6-4049-9731-2E1DEEC5E0CD")]
[TypeConverter(System.ComponentModel.ExpandableObjectConverter)]
[Serializable()]
public class EasyDAItemChangedEventArgs : OpcLabs.BaseLib.OperationModel.OperationEventArgs, OpcLabs.BaseLib.OperationModel.ComTypes._OperationEventArgs, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemChangedEventArgs, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable  
[CLSCompliant(true)]
[ComDefaultInterface(OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemChangedEventArgs)]
[ComVisible(true)]
[Guid("B93B886F-19E6-4049-9731-2E1DEEC5E0CD")]
[TypeConverter(System.ComponentModel.ExpandableObjectConverter)]
[Serializable()]
public ref class EasyDAItemChangedEventArgs : public OpcLabs.BaseLib.OperationModel.OperationEventArgs, OpcLabs.BaseLib.OperationModel.ComTypes._OperationEventArgs, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemChangedEventArgs, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable  
Remarks

 

When there is a change in a value of an OPC item you have subscribed to, the EasyDAClient object generates an  ItemChanged event. For subscription mechanism to be useful, you should hook one or more event handlers to this event.

To be more precise, the ItemChanged event is actually generated in other cases, too.

First of all, you always receive at least one ItemChanged event notification after you make a subscription; this notification either contains the initial data for the item, or an indication that data is not currently available. This behavior allows your application to rely on the component to provide at least some information for each subscribed item.

Secondly, the ItemChanged event is generated every time the component loses connection to the item, and when it reestablishes the connection. This way, your application is informed about any problems related to the item, and can process them accordingly if needed.

You will also receive the ItemChanged notification if the quality of the item changes (not just its actual data value).

The ItemChanged event notification contains an EasyDAItemChangedEventArgs argument. You will find all kind of relevant data in this object. Some properties in this object contain valid information no matter what kind of change the notification is about. These properties are inside the Arguments property.

For further processing, your code should always inspect the value of  Exception property of the event arguments. If this property is set to a null reference, the notification carries an actual change in item’s data, and the Vtq property has the new value, timestamp and quality of the item, in form of DAVtq object. If the Exception property is not a null reference, there has been an error related to the item, and the Vtq property is not valid. In such case, the Exception property contains information about the problem.

The ItemChanged event handler is called on a thread determined by the EasyDAClient component. For details, please refer to “Multithreading and Synchronization” chapter under “Advanced Topics”.

In short, however, we can say that if you are writing e.g. Windows Forms application, the component takes care of calling the event handler on the user interface thread of the form, making it safe for your code to update controls on the form, or do other form-related actions, from the event handler.

 

Example

.NET

COM

// This example subscribes to changes of 2 items separately, and displays rich information available with each item changed
// event notification.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using System.Diagnostics;
using System.Threading;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.OperationModel;

namespace DocExamples.DataAccess._EasyDAItemChangedEventArgs
{
    class General
    {
        public static void Main1()
        {
            // Instantiate the client object.
            using (var client = new EasyDAClient())
            {
                var eventHandler = new EasyDAItemChangedEventHandler(client_ItemChanged);
                client.ItemChanged += eventHandler;

                Console.WriteLine("Subscribing items...");
                client.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 5 * 1000);
                client.SubscribeItem("", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 5 * 1000);

                Console.WriteLine("Processing item changed events for 1 minute...");
                Thread.Sleep(60 * 1000);
            }
        }

        static void client_ItemChanged(object sender, EasyDAItemChangedEventArgs e)
        {
            Console.WriteLine();
            Console.WriteLine($"e.Arguments.State: {e.Arguments.State}");
            Console.WriteLine($"e.Arguments.ServerDescriptor.MachineName: {e.Arguments.ServerDescriptor.MachineName}");
            Console.WriteLine($"e.Arguments.ServerDescriptor.ServerClass: {e.Arguments.ServerDescriptor.ServerClass}");
            Console.WriteLine($"e.Arguments.ItemDescriptor.ItemId: {e.Arguments.ItemDescriptor.ItemId}");
            Console.WriteLine($"e.Arguments.ItemDescriptor.AccessPath: {e.Arguments.ItemDescriptor.AccessPath}");
            Console.WriteLine($"e.Arguments.ItemDescriptor.RequestedDataType: {e.Arguments.ItemDescriptor.RequestedDataType}");
            Console.WriteLine($"e.Arguments.GroupParameters.Locale: {e.Arguments.GroupParameters.Locale}");
            Console.WriteLine($"e.Arguments.GroupParameters.RequestedUpdateRate: {e.Arguments.GroupParameters.RequestedUpdateRate}");
            Console.WriteLine($"e.Arguments.GroupParameters.PercentDeadband: {e.Arguments.GroupParameters.PercentDeadband}");
            if (e.Succeeded)
            {
                Debug.Assert(!(e.Vtq is null));
                Console.WriteLine($"e.Vtq.Value: {e.Vtq.Value}");
                Console.WriteLine($"e.Vtq.Timestamp: {e.Vtq.Timestamp}");
                Console.WriteLine($"e.Vtq.TimestampLocal: {e.Vtq.TimestampLocal}");
                Console.WriteLine($"e.Vtq.Quality: {e.Vtq.Quality}");
            }
            else
            {
                Debug.Assert(!(e.Exception is null));
                Console.WriteLine($"e.Exception.Message: {e.Exception.Message}");
                Console.WriteLine($"e.Exception.Source: {e.Exception.Source}");
            }
        }


        // Example output:
        //
        //Processing item changed events for 1 minute...
        //
        //e.Arguments.State: 
        //e.Arguments.ServerDescriptor.MachineName: 
        //e.Arguments.ServerDescriptor.ServerClass: OPCLabs.KitServer.2
        //e.Arguments.ItemDescriptor.ItemId: Simulation.Random
        //e.Arguments.ItemDescriptor.AccessPath: 
        //e.Arguments.ItemDescriptor.RequestedDataType: Empty
        //e.Arguments.GroupParameters.Locale: 0
        //e.Arguments.GroupParameters.RequestedUpdateRate: 5000
        //e.Arguments.GroupParameters.PercentDeadband: 0
        //e.Vtq.Value: 0.00125125888851588
        //e.Vtq.Timestamp: 4/10/2020 4:35:25 PM
        //e.Vtq.TimestampLocal: 4/10/2020 6:35:25 PM
        //e.Vtq.Quality: GoodNonspecific (192)
        //
        //e.Arguments.State: 
        //e.Arguments.ServerDescriptor.MachineName: 
        //e.Arguments.ServerDescriptor.ServerClass: OPCLabs.KitServer.2
        //e.Arguments.ItemDescriptor.ItemId: Trends.Ramp(1 min)
        //e.Arguments.ItemDescriptor.AccessPath: 
        //e.Arguments.ItemDescriptor.RequestedDataType: Empty
        //e.Arguments.GroupParameters.Locale: 0
        //e.Arguments.GroupParameters.RequestedUpdateRate: 5000
        //e.Arguments.GroupParameters.PercentDeadband: 0
        //e.Vtq.Value: 0.431881904602051
        //e.Vtq.Timestamp: 4/10/2020 4:35:25 PM
        //e.Vtq.TimestampLocal: 4/10/2020 6:35:25 PM
        //e.Vtq.Quality: GoodNonspecific (192)
        //
        //...
    }
}
# This example subscribes to changes of 2 items separately, and displays rich information available with each item
# changed event notification.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.DataAccess import *


# Item changed event handler.
def itemChanged(sender, e):
    assert e is not None
    print()
    print('e.Arguments.State: ', e.Arguments.State, sep='')
    print('e.Arguments.ServerDescriptor.MachineName: ', e.Arguments.ServerDescriptor.MachineName, sep='')
    print('e.Arguments.ServerDescriptor.ServerClass: ', e.Arguments.ServerDescriptor.ServerClass, sep='')
    print('e.Arguments.ItemDescriptor.ItemId: ', e.Arguments.ItemDescriptor.ItemId, sep='')
    print('e.Arguments.ItemDescriptor.AccessPath: ', e.Arguments.ItemDescriptor.AccessPath, sep='')
    print('e.Arguments.ItemDescriptor.RequestedDataType: ', e.Arguments.ItemDescriptor.RequestedDataType, sep='')
    print('e.Arguments.GroupParameters.Locale: ', e.Arguments.GroupParameters.Locale, sep='')
    print('e.Arguments.GroupParameters.RequestedUpdateRate: ', e.Arguments.GroupParameters.RequestedUpdateRate, sep='')
    print('e.Arguments.GroupParameters.PercentDeadband: ', e.Arguments.GroupParameters.PercentDeadband, sep='')
    if e.Succeeded:
        assert e.Vtq is not None
        print('e.Vtq.Value: ', e.Vtq.Value, sep='')
        print('e.Vtq.Timestamp: ', e.Vtq.Timestamp, sep='')
        print('e.Vtq.TimestampLocal: ', e.Vtq.TimestampLocal, sep='')
        print('e.Vtq.Quality: ', e.Vtq.Quality, sep='')
    else:
        assert e.Exception is not None
        print('e.Exception.Message: ', e.Exception.Message, sep='')
        print('e.Exception.Source: ', e.Exception.Source, sep='')


# Instantiate the client object.
client = EasyDAClient()

client.ItemChanged += itemChanged

print('Subscribing item changes for 2 items...')
IEasyDAClientExtension.SubscribeItem(client, '', 'OPCLabs.KitServer.2', 'Simulation.Random', 5*1000)
IEasyDAClientExtension.SubscribeItem(client, '', 'OPCLabs.KitServer.2', 'Trends.Ramp (1 min)', 5*1000)

print('Processing item change notifications for 1 minute...')
time.sleep(60)

print('Unsubscribing all items...')
client.UnsubscribeAllItems()

client.ItemChanged -= itemChanged

print('Finished.')
' This example subscribes to changes of 2 items separately, and displays rich information available with each item changed
' event notification.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Imports System.Threading
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.OperationModel

Namespace DataAccess._EasyDAItemChangedEventArgs
    Partial Friend Class General
        Shared Sub Main1()
            ' Instantiate the client object.
            Using client = New EasyDAClient()
                Dim eventHandler = New EasyDAItemChangedEventHandler(AddressOf client_ItemChanged)
                AddHandler client.ItemChanged, eventHandler

                Console.WriteLine("Subscribing items...")
                client.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 5 * 1000)
                client.SubscribeItem("", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 5 * 1000)

                Console.WriteLine("Processing item changed events for 1 minute...")
                Thread.Sleep(60 * 1000)
            End Using
        End Sub

        Private Shared Sub client_ItemChanged(sender As Object, e As EasyDAItemChangedEventArgs)
            Console.WriteLine()
            Console.WriteLine($"e.Arguments.State: {e.Arguments.State}")
            Console.WriteLine($"e.Arguments.ServerDescriptor.MachineName: {e.Arguments.ServerDescriptor.MachineName}")
            Console.WriteLine($"e.Arguments.ServerDescriptor.ServerClass: {e.Arguments.ServerDescriptor.ServerClass}")
            Console.WriteLine($"e.Arguments.ItemDescriptor.ItemId: {e.Arguments.ItemDescriptor.ItemId}")
            Console.WriteLine($"e.Arguments.ItemDescriptor.AccessPath: {e.Arguments.ItemDescriptor.AccessPath}")
            Console.WriteLine($"e.Arguments.ItemDescriptor.RequestedDataType: {e.Arguments.ItemDescriptor.RequestedDataType}")
            Console.WriteLine($"e.Arguments.GroupParameters.Locale: {e.Arguments.GroupParameters.Locale}")
            Console.WriteLine($"e.Arguments.GroupParameters.RequestedUpdateRate: {e.Arguments.GroupParameters.RequestedUpdateRate}")
            Console.WriteLine($"e.Arguments.GroupParameters.PercentDeadband: {e.Arguments.GroupParameters.PercentDeadband}")
            If e.Succeeded Then
                Debug.Assert(e.Vtq IsNot Nothing)
                Console.WriteLine($"e.Vtq.Value: {e.Vtq.Value}")
                Console.WriteLine($"e.Vtq.Timestamp: {e.Vtq.Timestamp}")
                Console.WriteLine($"e.Vtq.TimestampLocal: {e.Vtq.TimestampLocal}")
                Console.WriteLine($"e.Vtq.Quality: {e.Vtq.Quality}")
            Else
                Debug.Assert(e.Exception IsNot Nothing)
                Console.WriteLine($"e.Exception.Message: {e.Exception.Message}")
                Console.WriteLine($"e.Exception.Source: {e.Exception.Source}")
            End If
        End Sub

        ' Example output
        '
        'Processing item changed events for 1 minute...
        '
        'e.Arguments.State: 
        'e.Arguments.ServerDescriptor.MachineName 
        'e.Arguments.ServerDescriptor.ServerClass OPCLabs.KitServer.2
        'e.Arguments.ItemDescriptor.ItemId: Simulation.Random
        'e.Arguments.ItemDescriptor.AccessPath: 
        'e.Arguments.ItemDescriptor.RequestedDataType Empty
        'e.Arguments.GroupParameters.Locale: 0
        'e.Arguments.GroupParameters.RequestedUpdateRate: 5000
        'e.Arguments.GroupParameters.PercentDeadband: 0
        'e.Vtq.Value: 0.00125125888851588
        'e.Vtq.Timestamp: 4/10/2020 4:35:25 PM
        'e.Vtq.TimestampLocal: 4/10/2020 6:35:25 PM
        'e.Vtq.Quality: GoodNonspecific (192)
        '
        'e.Arguments.State: 
        'e.Arguments.ServerDescriptor.MachineName 
        'e.Arguments.ServerDescriptor.ServerClass OPCLabs.KitServer.2
        'e.Arguments.ItemDescriptor.ItemId: Trends.Ramp(1 min)
        'e.Arguments.ItemDescriptor.AccessPath: 
        'e.Arguments.ItemDescriptor.RequestedDataType Empty
        'e.Arguments.GroupParameters.Locale: 0
        'e.Arguments.GroupParameters.RequestedUpdateRate: 5000
        'e.Arguments.GroupParameters.PercentDeadband: 0
        'e.Vtq.Value: 0.431881904602051
        'e.Vtq.Timestamp: 4/10/2020 4:35:25 PM
        'e.Vtq.TimestampLocal: 4/10/2020 6:35:25 PM
        'e.Vtq.Quality: GoodNonspecific (192)
        '
        '...
    End Class
End Namespace
Rem This example subscribes to changes of 2 items separately, and displays rich information available with each item changed
Rem event notification.
Rem
Rem Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Option Explicit

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
WScript.ConnectObject Client, "Client_"

Client.SubscribeItem "", "OPCLabs.KitServer.2", "Simulation.Random", 5*1000
Client.SubscribeItem "", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 5*1000

WScript.Echo "Processing item changed events for 1 minute..."
WScript.Sleep 60*1000



Sub Client_ItemChanged(Sender, e)
    On Error Resume Next
    WScript.Echo
    WScript.Echo "e.Arguments.State: " & e.Arguments.State
    WScript.Echo "e.Arguments.ServerDescriptor.MachineName: " & e.Arguments.ServerDescriptor.MachineName
    WScript.Echo "e.Arguments.ServerDescriptor.ServerClass: " & e.Arguments.ServerDescriptor.ServerClass
    WScript.Echo "e.Arguments.ItemDescriptor.ItemId: " & e.Arguments.ItemDescriptor.ItemId
    WScript.Echo "e.Arguments.ItemDescriptor.AccessPath: " & e.Arguments.ItemDescriptor.AccessPath
    WScript.Echo "e.Arguments.ItemDescriptor.RequestedDataType: " & e.Arguments.ItemDescriptor.RequestedDataType
    WScript.Echo "e.Arguments.GroupParameters.Locale: " & e.Arguments.GroupParameters.Locale
    WScript.Echo "e.Arguments.GroupParameters.RequestedUpdateRate: " & e.Arguments.GroupParameters.RequestedUpdateRate
    WScript.Echo "e.Arguments.GroupParameters.PercentDeadband: " & e.Arguments.GroupParameters.PercentDeadband
    WScript.Echo "e.Exception.Message: " & e.Exception.Message
    WScript.Echo "e.Exception.Source: " & e.Exception.Source
    WScript.Echo "e.Exception.ErrorCode: " & e.Exception.ErrorCode
    WScript.Echo "e.Vtq.Value: " & e.Vtq.Value
    WScript.Echo "e.Vtq.Timestamp: " & e.Vtq.Timestamp
    WScript.Echo "e.Vtq.TimestampLocal: " & e.Vtq.TimestampLocal
    WScript.Echo "e.Vtq.Quality: " & e.Vtq.Quality
End Sub
Inheritance Hierarchy

System.Object
   System.EventArgs
      OpcLabs.BaseLib.OperationModel.OperationEventArgs
         OpcLabs.EasyOpc.DataAccess.OperationModel.EasyDAItemChangedEventArgs
            OpcLabs.EasyOpc.DataAccess.Generic.EasyDAItemChangedEventArgs<TValue>

Requirements

Target Platforms: .NET Framework: Windows 10 (selected versions), Windows 11 (selected versions), Windows Server 2016, Windows Server 2022; .NET: Linux, macOS, Microsoft Windows

See Also