Development Models > Imperative Programming Model > Imperative Programming Model for OPC Data (Classic and UA) > Subscribing to Information (OPC Data) > Changing Existing Subscription (OPC Data) |
It is not necessary to unsubscribe and then subscribe again if you want to change parameters of existing subscription, such as its update rate (OPC Classic) or sampling interval (OPC UA).
Instead of unsubscribing and subscribing again, change the parameters by calling the ChangeItemSubscription (OPC Classic) or ChangeDataChangeSubscription or ChangeMonitoredItemSubscription (OPC UA) method, passing it the subscription handle, and the new parameters in form of DAGroupParameters object (in QuickOPC.NET), EasyUASubscriptionChangeArguments (in QuickOPC-UA) or individually a requested update rate or sampling interval, and optionally a deadband value (this is the only way in QuickOPC-COM).
// This example shows how change the update rate of an existing subscription. using System; using System.Threading; using OpcLabs.EasyOpc.DataAccess; using OpcLabs.EasyOpc.DataAccess.OperationModel; namespace DocExamples.DataAccess._EasyDAClient { partial class ChangeItemSubscription { public static void Main1() { // Instantiate the client object. using (var client = new EasyDAClient()) { client.ItemChanged += client_ItemChanged; Console.WriteLine("Subscribing..."); int handle = client.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 1000); Console.WriteLine("Waiting for 10 seconds..."); Thread.Sleep(10 * 1000); Console.WriteLine("Changing subscription..."); client.ChangeItemSubscription(handle, new DAGroupParameters(100)); Console.WriteLine("Waiting for 10 seconds..."); Thread.Sleep(10 * 1000); Console.WriteLine("Unsubscribing..."); client.UnsubscribeAllItems(); Console.WriteLine("Waiting for 10 seconds..."); Thread.Sleep(10 * 1000); } } // Item changed event handler static void client_ItemChanged(object sender, EasyDAItemChangedEventArgs e) { if (e.Succeeded) Console.WriteLine(e.Vtq); else Console.WriteLine("*** Failure: {0}", e.ErrorMessageBrief); } } }
# This example shows how change the update rate of an existing subscription. # 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): if e.Succeeded: print(e.Vtq) else: print('*** Failure: ', e.ErrorMessageBrief, sep='') # Instantiate the client object. client = EasyDAClient() client.ItemChanged += itemChanged print('Subscribing item...') handle = IEasyDAClientExtension.SubscribeItem(client, '', 'OPCLabs.KitServer.2', 'Simulation.Random', 1000) print('Processing item change notifications for 10 seconds...') time.sleep(10) print('Changing item subscription...') IEasyDAClientExtension.ChangeItemSubscription(client, handle, DAGroupParameters(100)) print('Processing item change notifications for 10 seconds...') time.sleep(10) print('Unsubscribing item...') IEasyDAClientExtension.UnsubscribeItem(client, handle) print('Waiting for 10 seconds...') time.sleep(10) client.ItemChanged -= itemChanged print('Finished.')
' This example shows how change the update rate of an existing subscription. Imports System.Threading Imports OpcLabs.EasyOpc.DataAccess Imports OpcLabs.EasyOpc.DataAccess.OperationModel Namespace DataAccess._EasyDAClient Partial Friend Class ChangeItemSubscription Public Shared Sub Main1() Using client = New EasyDAClient() AddHandler client.ItemChanged, AddressOf client_ItemChanged Console.WriteLine("Subscribing...") Dim handle As Integer = client.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 1000) Console.WriteLine("Waiting for 10 seconds...") Thread.Sleep(10 * 1000) Console.WriteLine("Changing subscription...") client.ChangeItemSubscription(handle, New DAGroupParameters(100)) Console.WriteLine("Waiting for 10 seconds...") Thread.Sleep(10 * 1000) Console.WriteLine("Unsubscribing...") client.UnsubscribeAllItems() Console.WriteLine("Waiting for 10 seconds...") Thread.Sleep(10 * 1000) End Using End Sub ' Item changed event handler Private Shared Sub client_ItemChanged(ByVal sender As Object, ByVal e As EasyDAItemChangedEventArgs) If e.Succeeded Then Console.WriteLine(e.Vtq) Else Console.WriteLine("*** Failure: {0}", e.ErrorMessageBrief) End If End Sub End Class End Namespace
Rem This example shows how change the update rate of an existing subscription. Option Explicit Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient") WScript.ConnectObject Client, "Client_" WScript.Echo "Subscribing..." Dim handle: handle = Client.SubscribeItem("", "OPCLabs.KitServer.2", "Simulation.Random", 1000) WScript.Echo "Waiting for 10 seconds..." WScript.Sleep 10*1000 WScript.Echo "Changing subscription..." Client.ChangeItemSubscription handle, 100 WScript.Echo "Waiting for 10 seconds..." WScript.Sleep 10*1000 WScript.Echo "Unsubscribing..." Client.UnsubscribeAllItems WScript.Echo "Waiting for 10 seconds..." WScript.Sleep 10*1000 WScript.DisconnectObject Client Set Client = Nothing Sub Client_ItemChanged(Sender, e) If Not (e.Succeeded) Then WScript.Echo "*** Failure: " & e.ErrorMessageBrief Exit Sub End If WScript.Echo e.Vtq End Sub
// This example shows how change the update rate of an existing OPC XML-DA subscription. using System; using System.Threading; using OpcLabs.EasyOpc.DataAccess; using OpcLabs.EasyOpc.DataAccess.OperationModel; namespace DocExamples.DataAccess.Xml { class ChangeItemSubscription { public static void Main1Xml() { // Instantiate the client object. using (var client = new EasyDAClient()) { client.ItemChanged += client_ItemChanged; Console.WriteLine("Subscribing..."); int handle = client.SubscribeItem( "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx", "Dynamic/Analog Types/Int", 2000, state: null); Console.WriteLine("Waiting for 20 seconds..."); Thread.Sleep(20 * 1000); Console.WriteLine("Changing subscription..."); client.ChangeItemSubscription(handle, new DAGroupParameters(500)); Console.WriteLine("Waiting for 10 seconds..."); Thread.Sleep(10 * 1000); Console.WriteLine("Unsubscribing..."); client.UnsubscribeAllItems(); Console.WriteLine("Waiting for 10 seconds..."); Thread.Sleep(10 * 1000); } } // Item changed event handler static void client_ItemChanged(object sender, EasyDAItemChangedEventArgs e) { if (e.Succeeded) Console.WriteLine(e.Vtq); else Console.WriteLine("*** Failure: {0}", e.ErrorMessageBrief); } } }
# This example shows how change the update rate of an existing OPC XML-DA subscription. # The QuickOPC package is needed. Install it using "pip install opclabs_quickopc". import opclabs_quickopc import time # Import .NET namespaces. from OpcLabs.EasyOpc import * from OpcLabs.EasyOpc.DataAccess import * # Item changed event handler def itemChanged(sender, e): if e.Succeeded: print(e.Vtq) else: print('*** Failure: ', e.ErrorMessageBrief, sep='') # Instantiate the client object. client = EasyDAClient() client.ItemChanged += itemChanged print('Subscribing item...') handle = IEasyDAClientExtension.SubscribeItem(client, ServerDescriptor('http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx'), DAItemDescriptor('Dynamic/Analog Types/Int'), DAGroupParameters(2000), None) # state print('Processing item change notifications for 20 seconds...') time.sleep(20) print('Changing item subscription...') IEasyDAClientExtension.ChangeItemSubscription(client, handle, DAGroupParameters(500)) print('Processing item change notifications for 10 seconds...') time.sleep(10) print('Unsubscribing item...') IEasyDAClientExtension.UnsubscribeItem(client, handle) print('Waiting for 10 seconds...') time.sleep(10) client.ItemChanged -= itemChanged print('Finished.')
' This example shows how change the update rate of an existing OPC XML-DA subscription. Imports System.Threading Imports OpcLabs.EasyOpc.DataAccess Imports OpcLabs.EasyOpc.DataAccess.OperationModel Namespace DataAccess.Xml Partial Friend Class ChangeItemSubscription Public Shared Sub Main1Xml() Using client = New EasyDAClient() AddHandler client.ItemChanged, AddressOf client_ItemChanged Console.WriteLine("Subscribing...") Dim handle As Integer = client.SubscribeItem( "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx", "Dynamic/Analog Types/Int", 2000, state:=Nothing) Console.WriteLine("Waiting for 20 seconds...") Thread.Sleep(20 * 1000) Console.WriteLine("Changing subscription...") client.ChangeItemSubscription(handle, New DAGroupParameters(500)) Console.WriteLine("Waiting for 10 seconds...") Thread.Sleep(10 * 1000) Console.WriteLine("Unsubscribing...") client.UnsubscribeAllItems() Console.WriteLine("Waiting for 10 seconds...") Thread.Sleep(10 * 1000) End Using End Sub ' Item changed event handler Private Shared Sub client_ItemChanged(ByVal sender As Object, ByVal e As EasyDAItemChangedEventArgs) If e.Succeeded Then Console.WriteLine(e.Vtq) Else Console.WriteLine("*** Failure: {0}", e.ErrorMessageBrief) End If End Sub End Class End Namespace
// This example shows how to change the sampling rate of an existing monitored item subscription. using System; using OpcLabs.EasyOpc.UA; using OpcLabs.EasyOpc.UA.OperationModel; namespace UADocExamples._EasyUAClient { class ChangeMonitoredItemSubscription { public static void Overload1() { UAEndpointDescriptor endpointDescriptor = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"; // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported) // or "https://opcua.demo-this.com:51212/UA/SampleServer/" // Instantiate the client object. var client = new EasyUAClient(); client.DataChangeNotification += client_DataChangeNotification; Console.WriteLine("Subscribing..."); int handle = client.SubscribeDataChange(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000); Console.WriteLine("Processing monitored item changed events for 10 seconds..."); System.Threading.Thread.Sleep(10 * 1000); Console.WriteLine("Changing subscription..."); client.ChangeMonitoredItemSubscription(handle, 100); Console.WriteLine("Processing monitored item changed events for 10 seconds..."); System.Threading.Thread.Sleep(10 * 1000); Console.WriteLine("Unsubscribing..."); client.UnsubscribeAllMonitoredItems(); Console.WriteLine("Waiting for 5 seconds..."); System.Threading.Thread.Sleep(5 * 1000); Console.WriteLine("Finished."); } static void client_DataChangeNotification(object sender, EasyUADataChangeNotificationEventArgs e) { if (e.Succeeded) Console.WriteLine(e.AttributeData.Value); else Console.WriteLine($"*** Failure: {e.ErrorMessageBrief}"); } } }
# This example shows how to change the sampling rate of an existing monitored item subscription. #requires -Version 5.1 using namespace OpcLabs.EasyOpc.UA using namespace OpcLabs.EasyOpc.UA.OperationModel # The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows . Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUA.dll" Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUAComponents.dll" [UAEndpointDescriptor]$endpointDescriptor = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer" # or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported) # or "https://opcua.demo-this.com:51212/UA/SampleServer/" # Instantiate the client object. $client = New-Object EasyUAClient # Data change notification handler Register-ObjectEvent -InputObject $client -EventName DataChangeNotification -Action { if ($EventArgs.Succeeded) { Write-Host "Value: $($EventArgs.AttributeData.Value)" } else { Write-Host "*** Failure: $($EventArgs.ErrorMessageBrief)" } } Write-Host "Subscribing..." $handle = $client.SubscribeDataChange($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000) Write-Host "Processing data change events for 10 seconds..." $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() while ($stopwatch.Elapsed.TotalSeconds -lt 10) { Start-Sleep -Seconds 1 } Write-Host "Changing subscription..." $client.ChangeMonitoredItemSubscription($handle, 100) Write-Host "Processing data change events for 10 seconds..." $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() while ($stopwatch.Elapsed.TotalSeconds -lt 10) { Start-Sleep -Seconds 1 } Write-Host "Unsubscribing..." $client.UnsubscribeAllMonitoredItems() Write-Host "Waiting for 5 seconds..." Start-Sleep -Seconds 5 Write-Host "Finished."
# This example shows how to change the sampling rate of an existing monitored item subscription. # The QuickOPC package is needed. Install it using "pip install opclabs_quickopc". import opclabs_quickopc import time # Import .NET namespaces. from OpcLabs.EasyOpc.UA import * from OpcLabs.EasyOpc.UA.OperationModel import * def dataChangeNotification(sender, e): # Display value if e.Succeeded: print('Value: ', e.AttributeData.Value, sep='') else: print('*** Failure: ', e.ErrorMessageBrief, sep='') endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer') # or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported) # or 'https://opcua.demo-this.com:51212/UA/SampleServer/' # Instantiate the client object and hook events. client = EasyUAClient() client.DataChangeNotification += dataChangeNotification print('Subscribing...') handle = IEasyUAClientExtension.SubscribeDataChange(client, endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'), 1000) print('Processing data change events for 10 seconds...') time.sleep(10) print('Changing subscription...') IEasyUAClientExtension.ChangeMonitoredItemSubscription(client, handle, 100) print('Processing data change events for 10 seconds...') time.sleep(10) print('Unsubscribing...') client.UnsubscribeAllMonitoredItems() print('Waiting for 5 seconds...') time.sleep(5) print('Finished.')
' This example shows how to change the sampling rate of an existing monitored item subscription. Imports OpcLabs.EasyOpc.UA Imports OpcLabs.EasyOpc.UA.OperationModel Namespace _EasyUAClient Friend Class ChangeMonitoredItemSubscription Public Shared Sub Overload1() ' Define which server we will work with. Dim endpointDescriptor As UAEndpointDescriptor = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer" ' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported) ' or "https://opcua.demo-this.com:51212/UA/SampleServer/" Dim client = New EasyUAClient() AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification Console.WriteLine("Subscribing...") Dim handle As Integer = _ client.SubscribeDataChange(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000) Console.WriteLine("Processing monitored item changed events for 10 seconds...") Threading.Thread.Sleep(10 * 1000) Console.WriteLine("Changing subscription...") client.ChangeMonitoredItemSubscription(handle, 100) Console.WriteLine("Processing monitored item changed events for 10 seconds...") Threading.Thread.Sleep(10 * 1000) Console.WriteLine("Unsubscribing...") client.UnsubscribeAllMonitoredItems() Console.WriteLine("Waiting for 5 seconds...") Threading.Thread.Sleep(5 * 1000) End Sub Private Shared Sub client_DataChangeNotification(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs) If e.Succeeded Then Console.WriteLine(e.AttributeData.Value) Else Console.WriteLine("*** Failure: {0}", e.ErrorMessageBrief) End If End Sub End Class End Namespace
// This example shows how to change the sampling rate of an existing monitored // item subscription. type TClientEventHandlers110 = class procedure OnDataChangeNotification( ASender: TObject; sender: OleVariant; const eventArgs: _EasyUADataChangeNotificationEventArgs); end; procedure TClientEventHandlers110.OnDataChangeNotification( ASender: TObject; sender: OleVariant; const eventArgs: _EasyUADataChangeNotificationEventArgs); begin // Display the data if eventArgs.Succeeded then WriteLn(eventArgs.AttributeData.ToString) else WriteLn('*** Failure: ', eventArgs.ErrorMessageBrief); end; class procedure ChangeMonitoredItemSubscription.Main; var Client: TEasyUAClient; ClientEventHandlers: TClientEventHandlers110; Handle: Cardinal; begin // Instantiate the client object and hook events Client := TEasyUAClient.Create(nil); ClientEventHandlers := TClientEventHandlers110.Create; Client.OnDataChangeNotification := ClientEventHandlers.OnDataChangeNotification; WriteLn('Subscribing...'); Handle := Client.SubscribeDataChange( //'http://opcua.demo-this.com:51211/UA/SampleServer', //'https://opcua.demo-this.com:51212/UA/SampleServer/', 'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer', 'nsu=http://test.org/UA/Data/ ;i=10853', 1000); WriteLn('Processing monitored item changed events for 10 seconds...'); PumpSleep(10*1000); Client.ChangeMonitoredItemSubscription(Handle, 100); WriteLn('Processing monitored item changed events for 10 seconds...'); PumpSleep(10*1000); WriteLn('Unsubscribing...'); Client.UnsubscribeAllMonitoredItems; WriteLn('Waiting for 5 seconds...'); PumpSleep(5*1000); WriteLn('Finished.'); FreeAndNil(Client); FreeAndNil(ClientEventHandlers); end;
Rem This example shows how to change the sampling rate of an existing monitored Rem item subscription. ' The client object, with events 'Public WithEvents Client5 As EasyUAClient Public Sub ChangeMonitoredItemSubscription_Main_Command_Click() OutputText = "" Set Client5 = New EasyUAClient OutputText = OutputText & "Subscribing..." & vbCrLf Dim Handle As Long Handle = Client5.SubscribeDataChange("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853", 1000) OutputText = OutputText & "Processing monitored item changed events for 10 seconds..." & vbCrLf Pause 10000 Call Client5.ChangeMonitoredItemSubscription(Handle, 100) OutputText = OutputText & "Processing monitored item changed events for 10 seconds..." & vbCrLf Pause 10000 OutputText = OutputText & "Unsubscribing..." & vbCrLf Client5.UnsubscribeAllMonitoredItems OutputText = OutputText & "Waiting for 5 seconds..." & vbCrLf Pause 5000 OutputText = OutputText & "Finished." & vbCrLf Set Client5 = Nothing End Sub Public Sub Client5_DataChangeNotification(ByVal sender As Variant, ByVal eventArgs As EasyUADataChangeNotificationEventArgs) ' Display the data If eventArgs.Exception Is Nothing Then OutputText = OutputText & eventArgs.AttributeData & vbCrLf Else OutputText = OutputText & eventArgs.ErrorMessageBrief & vbCrLf End If End Sub
Rem This example shows how to change the sampling rate of an existing monitored item subscription. Option Explicit ' Instantiate the client object and hook events Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient") WScript.ConnectObject Client, "Client_" WScript.Echo "Subscribing..." Dim handle: handle = Client.SubscribeDataChange( _ "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", _ "nsu=http://test.org/UA/Data/ ;i=10853", _ 1000) WScript.Echo "Processing monitored item changed events for 10 seconds..." WScript.Sleep 10 * 1000 WScript.Echo "Changing subscription..." Client.ChangeMonitoredItemSubscription handle, 100 WScript.Echo "Processing monitored item changed events for 10 seconds..." WScript.Sleep 10 * 1000 WScript.Echo "Unsubscribing..." Client.UnsubscribeAllMonitoredItems WScript.Echo "Waiting for 5 seconds..." WScript.Sleep 5 * 1000 Sub Client_DataChangeNotification(Sender, e) Dim display: If e.Exception Is Nothing Then display = e.AttributeData Else display = e.ErrorMessageBrief WScript.Echo display End Sub
For changing parameters of multiple subscriptions in an efficient manner, call the ChangeMultipleItemSubscriptions (OPC Classic), or ChangeMultipleDataChangeSubscriptions or ChangeMultipleMonitoredItemSubscriptions (OPC UA) method.
// This example shows how change the update rate of multiple existing subscriptions. using System; using System.Threading; using OpcLabs.EasyOpc.DataAccess; using OpcLabs.EasyOpc.DataAccess.OperationModel; namespace DocExamples.DataAccess._EasyDAClient { class ChangeMultipleItemSubscriptions { public static void Main1() { // Instantiate the client object. using (var client = new EasyDAClient()) { client.ItemChanged += client_ItemChanged; Console.WriteLine("Subscribing..."); int[] handleArray = client.SubscribeMultipleItems(new[] { new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, null), new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 1000, null), new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Sine (1 min)", 1000, null), new DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Register_I4", 1000, null) }); Console.WriteLine("Waiting for 10 seconds..."); Thread.Sleep(10 * 1000); Console.WriteLine("Changing subscriptions..."); client.ChangeMultipleItemSubscriptions(new[] { new DAHandleGroupArguments(handleArray[0], 100), new DAHandleGroupArguments(handleArray[1], 100) }); Console.WriteLine("Waiting for 10 seconds..."); Thread.Sleep(10 * 1000); Console.WriteLine("Unsubscribing..."); client.UnsubscribeAllItems(); Console.WriteLine("Waiting for 10 seconds..."); Thread.Sleep(10 * 1000); } } // Item changed event handler static void client_ItemChanged(object sender, EasyDAItemChangedEventArgs e) { if (e.Succeeded) Console.WriteLine(e.Vtq); else Console.WriteLine($"*** Failure: {e.ErrorMessageBrief}"); } } }
# This example shows how change the update rate of multiple existing subscriptions. # 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, e): if e.Succeeded: print(e.Arguments.ItemDescriptor.ItemId, ': ', e.Vtq, sep='') else: print(e.Arguments.ItemDescriptor.ItemId, ' *** Failure: ', e.ErrorMessageBrief, sep='') # Instantiate the client object. client = EasyDAClient() client.ItemChanged += itemChanged print('Subscribing item changes...') handleArray = client.SubscribeMultipleItems([ EasyDAItemSubscriptionArguments('', 'OPCLabs.KitServer.2', 'Simulation.Random', 1000, None), EasyDAItemSubscriptionArguments('', 'OPCLabs.KitServer.2', 'Trends.Ramp (1 min)', 1000, None), EasyDAItemSubscriptionArguments('', 'OPCLabs.KitServer.2', 'Trends.Sine (1 min)', 1000, None), EasyDAItemSubscriptionArguments('', 'OPCLabs.KitServer.2', 'Simulation.Register_I4', 1000, None), ]) print('Processing item change notifications for 10 seconds...') time.sleep(10) print('Changing item subscriptions...') client.ChangeMultipleItemSubscriptions([ DAHandleGroupArguments(handleArray[0], 100), DAHandleGroupArguments(handleArray[1], 100), ]) print('Processing item change notifications for 10 seconds...') time.sleep(10) print('Unsubscribing all items...') client.UnsubscribeAllItems() print('Waiting for 10 seconds...') time.sleep(10) client.ItemChanged -= itemChanged print('Finished.')
Rem This example shows how change the update rate of multiple existing subscriptions. Option Explicit Dim ItemSubscriptionArguments1: Set ItemSubscriptionArguments1 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.EasyDAItemSubscriptionArguments") ItemSubscriptionArguments1.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2" ItemSubscriptionArguments1.ItemDescriptor.ItemID = "Simulation.Random" ItemSubscriptionArguments1.GroupParameters.RequestedUpdateRate = 1000 Dim ItemSubscriptionArguments2: Set ItemSubscriptionArguments2 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.EasyDAItemSubscriptionArguments") ItemSubscriptionArguments2.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2" ItemSubscriptionArguments2.ItemDescriptor.ItemID = "Trends.Ramp (1 min)" ItemSubscriptionArguments2.GroupParameters.RequestedUpdateRate = 1000 Dim ItemSubscriptionArguments3: Set ItemSubscriptionArguments3 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.EasyDAItemSubscriptionArguments") ItemSubscriptionArguments3.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2" ItemSubscriptionArguments3.ItemDescriptor.ItemID = "Trends.Sine (1 min)" ItemSubscriptionArguments3.GroupParameters.RequestedUpdateRate = 1000 Dim ItemSubscriptionArguments4: Set ItemSubscriptionArguments4 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.EasyDAItemSubscriptionArguments") ItemSubscriptionArguments4.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2" ItemSubscriptionArguments4.ItemDescriptor.ItemID = "Simulation.Register_I4" ItemSubscriptionArguments4.GroupParameters.RequestedUpdateRate = 1000 Dim arguments(3) Set arguments(0) = ItemSubscriptionArguments1 Set arguments(1) = ItemSubscriptionArguments2 Set arguments(2) = ItemSubscriptionArguments3 Set arguments(3) = ItemSubscriptionArguments4 Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient") WScript.ConnectObject Client, "Client_" WScript.Echo "Subscribing..." Dim handleArray: handleArray = Client.SubscribeMultipleItems(arguments) WScript.Echo "Waiting for 10 seconds..." WScript.Sleep 10*1000 WScript.Echo "Changing subscriptions..." Dim HandleGroupArguments1: Set HandleGroupArguments1 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAHandleGroupArguments") HandleGroupArguments1.Handle = handleArray(0) HandleGroupArguments1.GroupParameters.RequestedUpdateRate = 100 Dim HandleGroupArguments2: Set HandleGroupArguments2 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAHandleGroupArguments") HandleGroupArguments2.Handle = handleArray(1) HandleGroupArguments2.GroupParameters.RequestedUpdateRate = 100 Dim subscriptionChangeArguments(1) Set subscriptionChangeArguments(0) = HandleGroupArguments1 Set subscriptionChangeArguments(1) = HandleGroupArguments2 Client.ChangeMultipleItemSubscriptions subscriptionChangeArguments WScript.Echo "Waiting for 10 seconds..." WScript.Sleep 10*1000 WScript.Echo "Unsubscribing..." Client.UnsubscribeAllItems WScript.Echo "Waiting for 10 seconds..." WScript.Sleep 10*1000 WScript.DisconnectObject Client Set Client = Nothing Sub Client_ItemChanged(Sender, e) If Not (e.Succeeded) Then WScript.Echo "*** Failure: " & e.ErrorMessageBrief Exit Sub End If WScript.Echo e.Vtq End Sub
// This example shows how change the sampling rate of multiple existing monitored item subscriptions. using System; using OpcLabs.EasyOpc.UA; using OpcLabs.EasyOpc.UA.OperationModel; namespace UADocExamples._EasyUAClient { class ChangeMultipleMonitoredItemSubscriptions { public static void Overload2() { UAEndpointDescriptor endpointDescriptor = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"; // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported) // or "https://opcua.demo-this.com:51212/UA/SampleServer/" // Instantiate the client object and hook events. var client = new EasyUAClient(); client.DataChangeNotification += client_DataChangeNotification; Console.WriteLine("Subscribing..."); int[] handleArray = client.SubscribeMultipleMonitoredItems(new[] { new EasyUAMonitoredItemArguments(null, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845", 1000), new EasyUAMonitoredItemArguments(null, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000), new EasyUAMonitoredItemArguments(null, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855", 1000) }); Console.WriteLine("Processing data change events for 10 seconds..."); System.Threading.Thread.Sleep(10 * 1000); Console.WriteLine("Changing subscriptions..."); client.ChangeMultipleMonitoredItemSubscriptions(handleArray, 100); Console.WriteLine("Processing data change events for 10 seconds..."); System.Threading.Thread.Sleep(10 * 1000); Console.WriteLine("Unsubscribing..."); client.UnsubscribeAllMonitoredItems(); Console.WriteLine("Waiting for 5 seconds..."); System.Threading.Thread.Sleep(5 * 1000); Console.WriteLine("Finished."); } static void client_DataChangeNotification(object sender, EasyUADataChangeNotificationEventArgs e) { // Display value if (e.Succeeded) Console.WriteLine($"{e.Arguments.NodeDescriptor}: {e.AttributeData.Value}"); else Console.WriteLine($"{e.Arguments.NodeDescriptor} *** Failure: {e.ErrorMessageBrief}"); } } }
# This example shows how change the sampling rate of multiple existing monitored item subscriptions. #requires -Version 5.1 using namespace OpcLabs.EasyOpc.UA using namespace OpcLabs.EasyOpc.UA.AddressSpace using namespace OpcLabs.EasyOpc.UA.OperationModel # The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows . Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUA.dll" Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUAComponents.dll" $endpointDescriptor = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer" # or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported) # or "https://opcua.demo-this.com:51212/UA/SampleServer/" # Instantiate the client object. $client = New-Object EasyUAClient # Data change notification handler Register-ObjectEvent -InputObject $client -EventName DataChangeNotification -Action { if ($EventArgs.Succeeded) { Write-Host "$($EventArgs.Arguments.NodeDescriptor): $($EventArgs.AttributeData.Value)" } else { Write-Host "$($EventArgs.Arguments.NodeDescriptor) *** Failure: $($EventArgs.ErrorMessageBrief)" } } Write-Host "Subscribing..." $handleArray = $client.SubscribeMultipleMonitoredItems(@( (New-Object UAMonitoredItemArguments( (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10845")), 1000)), (New-Object UAMonitoredItemArguments( (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10853")), 1000)), (New-Object UAMonitoredItemArguments( (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10855")), 1000)) )) Write-Host "Processing data change events for 10 seconds..." $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() while ($stopwatch.Elapsed.TotalSeconds -lt 10) { Start-Sleep -Seconds 1 } Write-Host "Changing subscriptions..." [IEasyUAClientExtension]::ChangeMultipleMonitoredItemSubscriptions($client, $handleArray, 100) Write-Host "Processing data change events for 10 seconds..." $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() while ($stopwatch.Elapsed.TotalSeconds -lt 10) { Start-Sleep -Seconds 1 } Write-Host "Unsubscribing..." $client.UnsubscribeAllMonitoredItems() Write-Host "Waiting for 5 seconds..." Start-Sleep -Seconds 5 Write-Host "Finished."
# This example shows how change the sampling rate of multiple existing monitored item subscriptions. # The QuickOPC package is needed. Install it using "pip install opclabs_quickopc". import opclabs_quickopc import time # Import .NET namespaces. from OpcLabs.EasyOpc.UA import * from OpcLabs.EasyOpc.UA.OperationModel import * def dataChangeNotification(sender, e): # Display value if e.Succeeded: print(e.Arguments.NodeDescriptor, ': ', e.AttributeData.Value, sep='') else: print(e.Arguments.NodeDescriptor, ' *** Failure: ', e.ErrorMessageBrief, sep='') endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer') # or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported) # or 'https://opcua.demo-this.com:51212/UA/SampleServer/' # Instantiate the client object and hook events. client = EasyUAClient() client.DataChangeNotification += dataChangeNotification print('Subscribing...') handleArray = client.SubscribeMultipleMonitoredItems([ EasyUAMonitoredItemArguments( None, UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'), UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'), UAMonitoringParameters(1000)), EasyUAMonitoredItemArguments( None, UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'), UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'), UAMonitoringParameters(1000)), EasyUAMonitoredItemArguments( None, UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'), UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'), UAMonitoringParameters(1000)), ]) print('Processing data change events for 10 seconds...') time.sleep(10) print('Changing subscriptions...') IEasyUAClientExtension.ChangeMultipleMonitoredItemSubscriptions(client, handleArray, 100) print('Processing data change events for 10 seconds...') time.sleep(10) print('Unsubscribing...') client.UnsubscribeAllMonitoredItems() print('Waiting for 5 seconds...') time.sleep(5) print('Finished.')
' This example shows how change the sampling rate of multiple existing monitored item subscriptions. Imports OpcLabs.EasyOpc.UA Imports OpcLabs.EasyOpc.UA.OperationModel Namespace _EasyUAClient Friend Class ChangeMultipleMonitoredItemSubscriptions Public Shared Sub Overload2() ' Define which server we will work with. Dim endpointDescriptor As UAEndpointDescriptor = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer" ' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported) ' or "https://opcua.demo-this.com:51212/UA/SampleServer/" ' Instantiate the client object and hook events Dim client = New EasyUAClient() AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification Console.WriteLine("Subscribing...") Dim handleArray() As Integer = client.SubscribeMultipleMonitoredItems(New EasyUAMonitoredItemArguments() _ { _ New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845", 1000), _ New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000), _ New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855", 1000) _ }) Console.WriteLine("Processing monitored item changed events for 10 seconds...") Threading.Thread.Sleep(10 * 1000) Console.WriteLine("Changing subscriptions...") client.ChangeMultipleMonitoredItemSubscriptions(handleArray, 100) Console.WriteLine("Processing monitored item changed events for 10 seconds...") Threading.Thread.Sleep(10 * 1000) Console.WriteLine("Unsubscribing...") client.UnsubscribeAllMonitoredItems() Console.WriteLine("Waiting for 5 seconds...") Threading.Thread.Sleep(5 * 1000) End Sub Private Shared Sub client_DataChangeNotification(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs) ' Display value If e.Succeeded Then Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value) Else Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief) End If End Sub End Class End Namespace
// This example shows how change the sampling rate of multiple existing monitored item subscriptions. type TClientEventHandlers111 = class procedure OnDataChangeNotification( ASender: TObject; sender: OleVariant; const eventArgs: _EasyUADataChangeNotificationEventArgs); end; procedure TClientEventHandlers111.OnDataChangeNotification( ASender: TObject; sender: OleVariant; const eventArgs: _EasyUADataChangeNotificationEventArgs); begin // Display the data if eventArgs.Succeeded then WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ': ', eventArgs.AttributeData.ToString) else WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ' *** Failure: ', eventArgs.ErrorMessageBrief); end; class procedure ChangeMultipleMonitoredItemSubscriptions.Main; var Arguments: OleVariant; Client: TEasyUAClient; ClientEventHandlers: TClientEventHandlers111; Handle: Cardinal; HandleArray: OleVariant; I: Cardinal; MonitoredItemArguments1, MonitoredItemArguments2, MonitoredItemArguments3: _EasyUAMonitoredItemArguments; OldMonitoringParameters, NewMonitoringParameters: _UAMonitoringParameters; SubscriptionChangeArguments: OleVariant; SubscriptionChangeArguments1, SubscriptionChangeArguments2, SubscriptionChangeArguments3: _EasyUASubscriptionChangeArguments; begin // Instantiate the client object and hook events Client := TEasyUAClient.Create(nil); ClientEventHandlers := TClientEventHandlers111.Create; Client.OnDataChangeNotification := ClientEventHandlers.OnDataChangeNotification; WriteLn('Subscribing...'); OldMonitoringParameters := CoUAMonitoringParameters.Create; OldMonitoringParameters.SamplingInterval := 1000; MonitoredItemArguments1 := CoEasyUAMonitoredItemArguments.Create; MonitoredItemArguments1.EndpointDescriptor.UrlString := //'http://opcua.demo-this.com:51211/UA/SampleServer'; //'https://opcua.demo-this.com:51212/UA/SampleServer/'; 'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'; MonitoredItemArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10845'; MonitoredItemArguments1.MonitoringParameters := OldMonitoringParameters; MonitoredItemArguments2 := CoEasyUAMonitoredItemArguments.Create; MonitoredItemArguments2.EndpointDescriptor.UrlString := //'http://opcua.demo-this.com:51211/UA/SampleServer'; //'https://opcua.demo-this.com:51212/UA/SampleServer/'; 'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'; MonitoredItemArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10853'; MonitoredItemArguments2.MonitoringParameters := OldMonitoringParameters; MonitoredItemArguments3 := CoEasyUAMonitoredItemArguments.Create; MonitoredItemArguments3.EndpointDescriptor.UrlString := //'http://opcua.demo-this.com:51211/UA/SampleServer'; //'https://opcua.demo-this.com:51212/UA/SampleServer/'; 'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'; MonitoredItemArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10855'; MonitoredItemArguments3.MonitoringParameters := OldMonitoringParameters; Arguments := VarArrayCreate([0, 2], varVariant); Arguments[0] := MonitoredItemArguments1; Arguments[1] := MonitoredItemArguments2; Arguments[2] := MonitoredItemArguments3; TVarData(HandleArray).VType := varArray or varVariant; TVarData(HandleArray).VArray := PVarArray( Client.SubscribeMultipleMonitoredItems(Arguments)); for I := VarArrayLowBound(HandleArray, 1) to VarArrayHighBound(HandleArray, 1) do begin Handle := Cardinal(HandleArray[I]); WriteLn('HandleArray[', I, ']: ', Handle); end; WriteLn('Processing monitored item changed events for 10 seconds...'); PumpSleep(10*1000); WriteLn('Changing subscriptions...'); NewMonitoringParameters := CoUAMonitoringParameters.Create; NewMonitoringParameters.SamplingInterval := 100; SubscriptionChangeArguments1 := CoEasyUASubscriptionChangeArguments.Create; SubscriptionChangeArguments1.Handle := Cardinal(HandleArray[0]); SubscriptionChangeArguments1.MonitoringParameters := NewMonitoringParameters; SubscriptionChangeArguments2 := CoEasyUASubscriptionChangeArguments.Create; SubscriptionChangeArguments2.Handle := Cardinal(HandleArray[1]); SubscriptionChangeArguments2.MonitoringParameters := NewMonitoringParameters; SubscriptionChangeArguments3 := CoEasyUASubscriptionChangeArguments.Create; SubscriptionChangeArguments3.Handle := Cardinal(HandleArray[2]); SubscriptionChangeArguments3.MonitoringParameters := NewMonitoringParameters; SubscriptionChangeArguments := VarArrayCreate([0, 2], varVariant); SubscriptionChangeArguments[0] := SubscriptionChangeArguments1; SubscriptionChangeArguments[1] := SubscriptionChangeArguments2; SubscriptionChangeArguments[2] := SubscriptionChangeArguments3; Client.ChangeMultipleMonitoredItemSubscriptions(SubscriptionChangeArguments); WriteLn('Processing monitored item changed events for 10 seconds...'); PumpSleep(10*1000); WriteLn('Unsubscribing...'); Client.UnsubscribeAllMonitoredItems; WriteLn('Waiting for 5 seconds...'); Sleep(5*1000); WriteLn('Finished.'); VarClear(HandleArray); VarClear(Arguments); FreeAndNil(Client); FreeAndNil(ClientEventHandlers); end;
Rem This example shows how change the sampling rate of multiple existing monitored item subscriptions. ' Instantiate the client object and hook events Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient") WScript.ConnectObject Client, "Client_" WScript.Echo "Subscribing..." Dim OldMonitoringParameters: Set OldMonitoringParameters = CreateObject("OpcLabs.EasyOpc.UA.UAMonitoringParameters") OldMonitoringParameters.SamplingInterval = 1000 Dim MonitoredItemArguments1: Set MonitoredItemArguments1 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments") MonitoredItemArguments1.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer" MonitoredItemArguments1.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845" MonitoredItemArguments1.MonitoringParameters = OldMonitoringParameters Dim MonitoredItemArguments2: Set MonitoredItemArguments2 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments") MonitoredItemArguments2.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer" MonitoredItemArguments2.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853" MonitoredItemArguments2.MonitoringParameters = OldMonitoringParameters Dim MonitoredItemArguments3: Set MonitoredItemArguments3 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments") MonitoredItemArguments3.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer" MonitoredItemArguments3.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10855" MonitoredItemArguments3.MonitoringParameters = OldMonitoringParameters Dim arguments(2) Set arguments(0) = MonitoredItemArguments1 Set arguments(1) = MonitoredItemArguments2 Set arguments(2) = MonitoredItemArguments3 Dim handleArray: handleArray = Client.SubscribeMultipleMonitoredItems(arguments) Dim i: For i = LBound(handleArray) To UBound(handleArray) WScript.Echo "handleArray(" & i & "): " & handleArray(i) Next WScript.Echo "Processing monitored item changed events for 10 seconds..." WScript.Sleep 10 * 1000 WScript.Echo "Changing subscriptions..." Dim NewMonitoringParameters: Set NewMonitoringParameters = CreateObject("OpcLabs.EasyOpc.UA.UAMonitoringParameters") NewMonitoringParameters.SamplingInterval = 100 Dim SubscriptionChangeArguments1: Set SubscriptionChangeArguments1 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUASubscriptionChangeArguments") SubscriptionChangeArguments1.Handle = handleArray(0) Set SubscriptionChangeArguments1.MonitoringParameters = NewMonitoringParameters Dim SubscriptionChangeArguments2: Set SubscriptionChangeArguments2 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUASubscriptionChangeArguments") SubscriptionChangeArguments2.Handle = handleArray(1) Set SubscriptionChangeArguments2.MonitoringParameters = NewMonitoringParameters Dim SubscriptionChangeArguments3: Set SubscriptionChangeArguments3 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUASubscriptionChangeArguments") SubscriptionChangeArguments3.Handle = handleArray(2) Set SubscriptionChangeArguments3.MonitoringParameters = NewMonitoringParameters Dim subscriptionChangeArguments(2) Set subscriptionChangeArguments(0) = SubscriptionChangeArguments1 Set subscriptionChangeArguments(1) = SubscriptionChangeArguments2 Set subscriptionChangeArguments(2) = SubscriptionChangeArguments3 Client.ChangeMultipleMonitoredItemSubscriptions subscriptionChangeArguments WScript.Echo "Processing monitored item changed events for 10 seconds..." WScript.Sleep 10 * 1000 WScript.Echo "Unsubscribing..." Client.UnsubscribeAllMonitoredItems WScript.Echo "Waiting for 5 seconds..." WScript.Sleep 5 * 1000 Sub Client_DataChangeNotification(Sender, e) ' Display the data Dim display: If e.Exception Is Nothing Then display = e.AttributeData Else display = e.ErrorMessageBrief WScript.Echo e.Arguments.NodeDescriptor & ":" & display End Sub
Copyright © 2004-2023 CODE Consulting and Development, s.r.o., Plzen. All rights reserved. Web page: www.opclabs.com
Send Documentation Feedback. Resources: Knowledge Base. Technical support: Online Forums, FAQ.