![](dotnetdiagramimages/OpcLabs_EasyOpcClassicCore_OpcLabs_EasyOpc_DataAccess_OperationModel_EasyDAItemSubscriptionArguments.png)
'Declaration
<CLSCompliantAttribute(True)> <ComDefaultInterfaceAttribute(OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemSubscriptionArguments)> <ComVisibleAttribute(True)> <GuidAttribute("161ECAC9-5FE5-411B-92B6-C5A3F2AA2FC4")> <TypeConverterAttribute(System.ComponentModel.ExpandableObjectConverter)> <ValueControlAttribute("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.81.455.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", DefaultReadWrite=False, Export=True, PageId=10001)> <SerializableAttribute()> Public Class EasyDAItemSubscriptionArguments Inherits DAItemGroupArguments Implements LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.BaseLib.OperationModel.ComTypes._OperationArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAItemArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAItemGroupArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemSubscriptionArguments, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable
'Usage
Dim instance As EasyDAItemSubscriptionArguments
[CLSCompliant(true)] [ComDefaultInterface(OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemSubscriptionArguments)] [ComVisible(true)] [Guid("161ECAC9-5FE5-411B-92B6-C5A3F2AA2FC4")] [TypeConverter(System.ComponentModel.ExpandableObjectConverter)] [ValueControl("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.81.455.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", DefaultReadWrite=false, Export=true, PageId=10001)] [Serializable()] public class EasyDAItemSubscriptionArguments : DAItemGroupArguments, LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.BaseLib.OperationModel.ComTypes._OperationArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAItemArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAItemGroupArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemSubscriptionArguments, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable
[CLSCompliant(true)] [ComDefaultInterface(OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemSubscriptionArguments)] [ComVisible(true)] [Guid("161ECAC9-5FE5-411B-92B6-C5A3F2AA2FC4")] [TypeConverter(System.ComponentModel.ExpandableObjectConverter)] [ValueControl("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.81.455.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", DefaultReadWrite=false, Export=true, PageId=10001)] [Serializable()] public ref class EasyDAItemSubscriptionArguments : public DAItemGroupArguments, LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.BaseLib.OperationModel.ComTypes._OperationArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAItemArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAItemGroupArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._EasyDAItemSubscriptionArguments, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable
Subscription is initiated by calling either SubscribeItem or SubscribeMultipleItems method. For any change in the subscribed item’s value, your application will receive the ItemChanged event notification, described further below. Obviously, you first need to hook up event handler for that event, and in order to prevent event loss, you should do it before subscribing. Alternatively, you can pass a callback method into the SubscribeItem or SubscribeMultipleItems call.
Values of some items may be changing quite frequently, and receiving all changes that are generated is not desirable for performance reasons; there are also physical limitations to the event throughput in the system. Your application needs to specify the requested update rate, which effectively tells the OPC server that you do not need to receive event notifications any faster than that. For OPC items that support it, you can optionally specify a percent deadband; only changes that exceed the deadband will generate an event notification.
In QuickOPC.NET, the requested update rate, percent deadband, and data type are all contained in a DAGroupParameters object.
If you want to subscribe to a specific OPC item, call the SubscribeItem method. You can pass in individual arguments for machine name, server class, ItemID, data type, requested update rate, and an optional percent deadband. Usually, you also pass in a State argument of type Object (in QuickOPC.NET) or VARIANT (in QuickOPC-COM). When the item’s value changes, the State argument is then passed to the ItemChanged event handler in the EasyDAItemChangedEventArgs.Arguments.State property. The SubscribeItem method returns a subscription handle that you can later use to change the subscription parameters, or unsubscribe.
In QuickOPC.NET, you can also pass in a combination of ServerDescriptor, DAItemDescriptor and DAGroupParameters objects, in place of individual arguments.
The State argument is typically used to provide some sort of correlation between objects in your application, and the event notifications. For example, if you are programming an HMI application and you want the event handler to update the control that displays the item’s value, you may want to set the State argument to the control object itself. When the event notification arrives, you simply update the control indicated by the State property of EasyDAItemChangedEventArgs, without having to look it up by ItemId or so. See Use the state instead of handles to identify subscribed entities.
To subscribe to multiple items simultaneously in an efficient manner, call the SubscribeMultipleItems method (instead of multiple SubscribeItem calls in a loop). You receive back an array of integers, which are the subscription handles.
You pass in an array of DAItemGroupArguments objects (each containing information for a single subscription to be made), to the SubscribeMultipleItems method.
Note: It is NOT an error to subscribe to the same item twice (or more times), even with precisely the same parameters. You will receive separate subscription handles, and with regard to your application, this situation will look no different from subscribing to different items. Internally, however, the subscription made to the OPC server will be optimized (merged together) if possible.
You can specify percent deadband when subscribing to an OPC item.
You can also specify the percent deadband when subscribing to multiple OPC items, and the percent deadband can be different for each item.
The example below logs OPC Data Access item changes into an XML file.
The main program:
// This example shows how subscribe to changes of multiple items and display each change, identifying the different // subscriptions by an integer. // // Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html . // OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp . // Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own // a commercial license in order to use Online Forums, and we reply to every post. using System; using System.Threading; using OpcLabs.EasyOpc.DataAccess; using OpcLabs.EasyOpc.DataAccess.OperationModel; namespace DocExamples.DataAccess._EasyDAClient { partial class SubscribeMultipleItems { public static void StateAsInteger() { // Instantiate the client object. using (var client = new EasyDAClient()) { // Hook events client.ItemChanged += client_StateAsInteger_ItemChanged; Console.WriteLine("Subscribing..."); int[] handleArray = client.SubscribeMultipleItems(new[] { new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, state: 1), // An integer we have chosen to identify the subscription new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 1000, state: 2), // An integer we have chosen to identify the subscription new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Sine (1 min)", 1000, state: 3), // An integer we have chosen to identify the subscription new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Register_I4", 1000, state: 4) // An integer we have chosen to identify the subscription }); for (int i = 0; i < handleArray.Length; i++) Console.WriteLine($"handleArray[{i}]: {handleArray[i]}"); Console.WriteLine("Processing item changed events for 10 seconds..."); Thread.Sleep(10 * 1000); Console.WriteLine("Unsubscribing..."); } Console.WriteLine("Waiting for 5 seconds..."); Thread.Sleep(5 * 1000); Console.WriteLine("Finished."); } // Item changed event handler static void client_StateAsInteger_ItemChanged(object sender, EasyDAItemChangedEventArgs eventArgs) { // Obtain the integer state we have passed in. var stateAsInteger = (int)eventArgs.Arguments.State; // Display the data if (eventArgs.Succeeded) Console.WriteLine($"{stateAsInteger}: {eventArgs.Vtq}"); else Console.WriteLine($"{stateAsInteger} *** Failure: {eventArgs.ErrorMessageBrief}"); } } }
' This example shows how subscribe to changes of multiple items and display each change, identifying the different ' subscriptions by an integer. ' ' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html . ' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET . ' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own ' a commercial license in order to use Online Forums, and we reply to every post. Imports System.Threading Imports OpcLabs.EasyOpc.DataAccess Imports OpcLabs.EasyOpc.DataAccess.OperationModel Namespace DataAccess._EasyDAClient Partial Friend Class SubscribeMultipleItems Public Shared Sub StateAsInteger() ' Instantiate the client object. Using client = New EasyDAClient() AddHandler client.ItemChanged, AddressOf client_StateAsInteger_ItemChanged Console.WriteLine("Subscribing...") Dim handleArray() As Integer = client.SubscribeMultipleItems(New DAItemGroupArguments() { New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, state:=1), ' An integer we have chosen to identify the subscription New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 1000, state:=2), ' An integer we have chosen to identify the subscription New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Sine (1 min)", 1000, state:=3), ' An integer we have chosen to identify the subscription New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Register_I4", 1000, state:=4) ' An integer we have chosen to identify the subscription }) For i As Integer = 0 To handleArray.Length - 1 Console.WriteLine($"handleArray[{i}]: {handleArray(i)}") Next i Console.WriteLine("Processing item changed events for 10 seconds...") Thread.Sleep(10 * 1000) Console.WriteLine("Unsubscribing...") End Using Console.WriteLine("Waiting for 5 seconds...") Thread.Sleep(5 * 1000) Console.WriteLine("Finished.") End Sub ' Item changed event handler Private Shared Sub client_StateAsInteger_ItemChanged(ByVal sender As Object, ByVal eventArgs As EasyDAItemChangedEventArgs) ' Obtain the integer state we have passed in. Dim stateAsInteger As Integer = CInt(eventArgs.Arguments.State) If eventArgs.Succeeded Then Console.WriteLine($"{stateAsInteger}: {eventArgs.Vtq}") Else Console.WriteLine($"{stateAsInteger} *** Failure: {eventArgs.ErrorMessageBrief}") End If End Sub End Class End Namespace
# This example shows how subscribe to changes of multiple items and display each change, identifying the different # subscriptions by an integer. # # 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 . # Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own # a commercial license in order to use Online Forums, and we reply to every post. # 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 * from OpcLabs.EasyOpc.DataAccess.OperationModel import * # Item changed event handler. def itemChanged(sender, eventArgs): # Obtain the integer state we have passed in. stateAsInteger = int(eventArgs.Arguments.State) if eventArgs.Succeeded: print(stateAsInteger, ': ', eventArgs.Vtq, sep='') else: print(stateAsInteger, ' *** Failure: ', eventArgs.ErrorMessageBrief, sep='') # Instantiate the client object. client = EasyDAClient() # Hook events. client.ItemChanged += itemChanged print('Subscribing item changes...') handleArray = IEasyDAClientExtension.SubscribeMultipleItems(client, [ DAItemGroupArguments('', 'OPCLabs.KitServer.2', 'Simulation.Random', 1000, 1), # an integer we have chosen to identify the subscription DAItemGroupArguments('', 'OPCLabs.KitServer.2', 'Trends.Ramp (1 min)', 1000, 2), # an integer we have chosen to identify the subscription DAItemGroupArguments('', 'OPCLabs.KitServer.2', 'Trends.Sine (1 min)', 1000, 3), # an integer we have chosen to identify the subscription DAItemGroupArguments('', 'OPCLabs.KitServer.2', 'Simulation.Register_I4', 1000, 4), # an integer we have chosen to identify the subscription ]) for i in range(len(handleArray)): print('handleArray[', i, ']: ', handleArray[i], sep='') print('Processing item change notifications for 1 minute...') time.sleep(60) print('Unsubscribing all items...') client.UnsubscribeAllItems() client.ItemChanged -= itemChanged print('Finished.')
// This example shows how subscribe to changes of multiple items and display each change, identifying the different // subscriptions by an object. // // Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html . // OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp . // Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own // a commercial license in order to use Online Forums, and we reply to every post. using System; using System.Threading; using OpcLabs.EasyOpc.DataAccess; using OpcLabs.EasyOpc.DataAccess.OperationModel; namespace DocExamples.DataAccess._EasyDAClient { partial class SubscribeMultipleItems { class CustomObject { public CustomObject(string name) { Name = name; } public string Name { get; } } public static void StateAsObject() { // Instantiate the client object. using (var client = new EasyDAClient()) { // Hook events client.ItemChanged += client_StateAsObject_ItemChanged; Console.WriteLine("Subscribing..."); int[] handleArray = client.SubscribeMultipleItems(new[] { new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, new CustomObject("First")), // A custom object that corresponds to the subscription new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 1000, new CustomObject("Second")), // A custom object that corresponds to the subscription new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Sine (1 min)", 1000, new CustomObject("Third")), // A custom object that corresponds to the subscription new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Register_I4", 1000, new CustomObject("Fourth")) // A custom object that corresponds to the subscription }); for (int i = 0; i < handleArray.Length; i++) Console.WriteLine($"handleArray[{i}]: {handleArray[i]}"); Console.WriteLine("Processing item changed events for 10 seconds..."); Thread.Sleep(10 * 1000); Console.WriteLine("Unsubscribing..."); } Console.WriteLine("Waiting for 5 seconds..."); Thread.Sleep(5 * 1000); Console.WriteLine("Finished."); } // Item changed event handler static void client_StateAsObject_ItemChanged(object sender, EasyDAItemChangedEventArgs eventArgs) { // Obtain the custom object we have passed in. var stateAsObject = (CustomObject)eventArgs.Arguments.State; // Display the data if (eventArgs.Succeeded) Console.WriteLine($"{stateAsObject.Name}: {eventArgs.Vtq}"); else Console.WriteLine($"{stateAsObject.Name} *** Failure: {eventArgs.ErrorMessageBrief}"); } } }
' This example shows how subscribe to changes of multiple items and display each change, identifying the different ' subscriptions by an object. ' ' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html . ' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET . ' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own ' a commercial license in order to use Online Forums, and we reply to every post. Imports System.Threading Imports OpcLabs.EasyOpc.DataAccess Imports OpcLabs.EasyOpc.DataAccess.OperationModel Namespace DataAccess._EasyDAClient Partial Friend Class SubscribeMultipleItems Private Class CustomObject Sub New(name As String) Me.Name = name End Sub Public ReadOnly Property Name As String End Class Public Shared Sub StateAsObject() ' Instantiate the client object. Using client = New EasyDAClient() AddHandler client.ItemChanged, AddressOf client_StateAsObject_ItemChanged Console.WriteLine("Subscribing...") Dim handleArray() As Integer = client.SubscribeMultipleItems(New DAItemGroupArguments() { New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, New CustomObject("First")), ' A custom object that corresponds to the subscription New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 1000, New CustomObject("Second")), ' A custom object that corresponds to the subscription New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Sine (1 min)", 1000, New CustomObject("Third")), ' A custom object that corresponds to the subscription New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Register_I4", 1000, New CustomObject("Fourth")) ' A custom object that corresponds to the subscription }) For i As Integer = 0 To handleArray.Length - 1 Console.WriteLine($"handleArray[{i}]: {handleArray(i)}") Next i Console.WriteLine("Processing item changed events for 10 seconds...") Thread.Sleep(10 * 1000) Console.WriteLine("Unsubscribing...") End Using Console.WriteLine("Waiting for 5 seconds...") Thread.Sleep(5 * 1000) Console.WriteLine("Finished.") End Sub ' Item changed event handler Private Shared Sub client_StateAsObject_ItemChanged(ByVal sender As Object, ByVal eventArgs As EasyDAItemChangedEventArgs) ' Obtain the custom object we have passed in. Dim stateAsObject As CustomObject = CType(eventArgs.Arguments.State, CustomObject) If eventArgs.Succeeded Then Console.WriteLine($"{stateAsObject.Name}: {eventArgs.Vtq}") Else Console.WriteLine($"{stateAsObject.Name} *** Failure: {eventArgs.ErrorMessageBrief}") End If End Sub End Class End Namespace
# This example shows how subscribe to changes of multiple items and display each change, identifying the different # subscriptions by an object. # # 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 . # Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own # a commercial license in order to use Online Forums, and we reply to every post. # 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 * from OpcLabs.EasyOpc.DataAccess.OperationModel import * class CustomObject(object): def __init__(self, name): self.name = name # Item changed event handler. def itemChanged(sender, eventArgs): # Obtain the custom object we have passed in. stateAsObject = eventArgs.Arguments.State if eventArgs.Succeeded: print(stateAsObject.name, ': ', eventArgs.Vtq, sep='') else: print(stateAsObject.name, ' *** Failure: ', eventArgs.ErrorMessageBrief, sep='') # Instantiate the client object. client = EasyDAClient() # Hook events. client.ItemChanged += itemChanged print('Subscribing item changes...') handleArray = IEasyDAClientExtension.SubscribeMultipleItems(client, [ DAItemGroupArguments('', 'OPCLabs.KitServer.2', 'Simulation.Random', 1000, CustomObject('First')), # a custom object that corresponds to the subscription DAItemGroupArguments('', 'OPCLabs.KitServer.2', 'Trends.Ramp (1 min)', 1000, CustomObject('Second')), # a custom object that corresponds to the subscription DAItemGroupArguments('', 'OPCLabs.KitServer.2', 'Trends.Sine (1 min)', 1000, CustomObject('Third')), # a custom object that corresponds to the subscription DAItemGroupArguments('', 'OPCLabs.KitServer.2', 'Simulation.Register_I4', 1000, CustomObject('Fourth')), # a custom object that corresponds to the subscription ]) for i in range(len(handleArray)): print('handleArray[', i, ']: ', handleArray[i], sep='') print('Processing item change notifications for 1 minute...') time.sleep(60) print('Unsubscribing all items...') client.UnsubscribeAllItems() client.ItemChanged -= itemChanged print('Finished.')
System.Object
OpcLabs.BaseLib.Object2
OpcLabs.BaseLib.Info
OpcLabs.BaseLib.OperationModel.OperationArguments
OpcLabs.EasyOpc.DataAccess.OperationModel.DAItemArguments
OpcLabs.EasyOpc.DataAccess.OperationModel.DAItemGroupArguments
OpcLabs.EasyOpc.DataAccess.OperationModel.EasyDAItemSubscriptionArguments
OpcLabs.EasyOpc.DataAccess.Generic.EasyDAItemSubscriptionArguments<T>