// This example shows how to select fields for event notifications.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
type
TClientEventHandlers4 = class
procedure OnEventNotification(
Sender: TObject;
sender0: OleVariant;
eventArgs: _EasyUAEventNotificationEventArgs);
end;
procedure TClientEventHandlers4.OnEventNotification(
Sender: TObject;
sender0: OleVariant;
eventArgs: _EasyUAEventNotificationEventArgs);
function ToUAAttributeField(Operand: UASimpleAttributeOperand): UAAttributeField;
var
AttributeField: UAAttributeField;
begin
AttributeField := CoUAAttributeField.Create;
AttributeField.Operand := Operand;
ToUAAttributeField := AttributeField;
end;
function UAFilterElements_SimpleAttribute(TypeId: UANodeId; SimpleRelativeBrowsePathString: string): UASimpleAttributeOperand;
var
Operand: UASimpleAttributeOperand;
BrowsePathParser: UABrowsePathParser;
begin
BrowsePathParser := CoUABrowsePathParser.Create;
Operand := CoUASimpleAttributeOperand.Create;
Operand.TypeId.NodeId := TypeId;
Operand.QualifiedNames := BrowsePathParser.ParseRelative(SimpleRelativeBrowsePathString).ToUAQualifiedNameCollection;
UAFilterElements_SimpleAttribute := Operand;
end;
function ObjectTypeIds_BaseEventType: UANodeId;
var
NodeId: UANodeId;
begin
NodeId := CoUANodeId.Create;
NodeId.StandardName := 'BaseEventType';
ObjectTypeIds_BaseEventType := NodeId;
end;
var
Count: Cardinal;
Element: OleVariant;
EntryEnumerator: IEnumVariant;
Entry: DictionaryEntry2;
AttributeField: UAAttributeField;
AValueResult: ValueResult;
begin
WriteLn;
// Display the event
if eventArgs.EventData = nil then
begin
WriteLn(eventArgs.ToString);
Exit;
end;
WriteLn('All fields:');
EntryEnumerator := eventArgs.EventData.FieldResults.GetEnumerator;
while EntryEnumerator.Next(1, Element, Count) = S_OK do
begin
Entry := IUnknown(Element) as DictionaryEntry2;
AttributeField := IUnknown(Entry.key) as UAAttributeField;
AValueResult := IUnknown(Entry.Value) as ValueResult;
WriteLn(' ', AttributeField.ToString, ' -> ', AValueResult.ToString);
end;
// Extracting a specific field using an event type ID and a simple relative path
WriteLn('Source name: ',
eventArgs.EventData.FieldResults[ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceName'))].ToString);
WriteLn('Message: ',
eventArgs.EventData.FieldResults[ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Message'))].ToString);
end;
class procedure SelectClauses.Main;
function ToUAAttributeField(Operand: UASimpleAttributeOperand): UAAttributeField;
var
AttributeField: UAAttributeField;
begin
AttributeField := CoUAAttributeField.Create;
AttributeField.Operand := Operand;
ToUAAttributeField := AttributeField;
end;
function ObjectTypeIds_BaseEventType: UANodeId;
var
NodeId: UANodeId;
begin
NodeId := CoUANodeId.Create;
NodeId.StandardName := 'BaseEventType';
ObjectTypeIds_BaseEventType := NodeId;
end;
function UABaseEventObject_Operands_NodeId: UASimpleAttributeOperand;
var
Operand: UASimpleAttributeOperand;
begin
Operand := CoUASimpleAttributeOperand.Create;
Operand.TypeId.NodeId.StandardName := 'BaseEventType';
Operand.AttributeId := UAAttributeId_NodeId;
UABaseEventObject_Operands_NodeId := Operand;
end;
function UAFilterElements_SimpleAttribute(TypeId: UANodeId; SimpleRelativeBrowsePathString: string): UASimpleAttributeOperand;
var
Operand: UASimpleAttributeOperand;
BrowsePathParser: UABrowsePathParser;
begin
BrowsePathParser := CoUABrowsePathParser.Create;
Operand := CoUASimpleAttributeOperand.Create;
Operand.TypeId.NodeId := TypeId;
Operand.QualifiedNames := BrowsePathParser.ParseRelative(SimpleRelativeBrowsePathString).ToUAQualifiedNameCollection;
UAFilterElements_SimpleAttribute := Operand;
end;
var
Arguments: OleVariant;
EvsClient: TEvsEasyUAClient;
Client: EasyUAClient;
ClientEventHandlers: TClientEventHandlers4;
Handle: Cardinal;
HandleArray: OleVariant;
MonitoredItemArguments: EasyUAMonitoredItemArguments;
MonitoringParameters: UAMonitoringParameters;
EventFilter: UAEventFilter;
SelectClauses: UAAttributeFieldCollection;
begin
// Instantiate the client object and hook events
EvsClient := TEvsEasyUAClient.Create(nil);
Client := EvsClient.ComServer;
ClientEventHandlers := TClientEventHandlers4.Create;
EvsClient.OnEventNotification := @ClientEventHandlers.OnEventNotification;
WriteLn('Subscribing...');
SelectClauses := CoUAAttributeFieldCollection.Create;
// Select specific fields using an event type ID and a simple relative path
SelectClauses.Add(ToUAAttributeField(UABaseEventObject_Operands_NodeId));
SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceNode')));
SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceName')));
SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Time')));
SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Message')));
SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Severity')));
EventFilter := CoUAEventFilter.Create;
EventFilter.SelectClauses := SelectClauses;
MonitoringParameters := CoUAMonitoringParameters.Create;
MonitoringParameters.SamplingInterval := 1000;
MonitoringParameters.EventFilter := EventFilter;
MonitoringParameters.QueueSize := 1000;
MonitoredItemArguments := CoEasyUAMonitoredItemArguments.Create;
MonitoredItemArguments.EndpointDescriptor.UrlString := 'opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer';
MonitoredItemArguments.NodeDescriptor.NodeId.StandardName := 'Server';
MonitoredItemArguments.MonitoringParameters := MonitoringParameters;
//MonitoredItemArguments.SubscriptionParameters.PublishingInterval := 0;
MonitoredItemArguments.AttributeId := UAAttributeId_EventNotifier;
Arguments := VarArrayCreate([0, 0], varVariant);
Arguments[0] := MonitoredItemArguments;
TVarData(HandleArray).VType := varArray or varVariant;
TVarData(HandleArray).VArray := PVarArray(
Client.SubscribeMultipleMonitoredItems(PSafeArray(TVarData(Arguments).VArray)));
WriteLn('Processing event notifications for 30 seconds...');
PumpSleep(30*1000);
WriteLn('Unsubscribing...');
Client.UnsubscribeAllMonitoredItems;
WriteLn('Waiting for 5 seconds...');
PumpSleep(5*1000);
WriteLn('Finished...');
end;
// This example shows how to select fields for event notifications.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
type
THelperMethods17 = class
class function ObjectTypeIds_BaseEventType: _UANodeId; static;
class function UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand;
class function UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand; static;
class function UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand; static;
class function UABaseEventObject_Operands_Time: _UASimpleAttributeOperand; static;
class function UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand; static;
class function UABaseEventObject_Operands_Message: _UASimpleAttributeOperand; static;
class function UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand; static;
end;
type
TClientEventHandlers17 = class
procedure Client_EventNotification(
ASender: TObject;
sender: OleVariant;
const eventArgs: _EasyUAEventNotificationEventArgs);
end;
procedure TClientEventHandlers17.Client_EventNotification(
ASender: TObject;
sender: OleVariant;
const eventArgs: _EasyUAEventNotificationEventArgs);
var
AttributeField: OleVariant;
Count: Cardinal;
Element: OleVariant;
EntryEnumerator: IEnumVARIANT;
ValueResult: OleVariant;
begin
WriteLn;
// Display the event
if eventArgs.EventData = nil then
begin
WriteLn(eventArgs.ToString);
Exit;
end;
WriteLn('All fields:');
EntryEnumerator := eventArgs.EventData.FieldResults.GetEnumerator;
while (EntryEnumerator.Next(1, Element, Count) = S_OK) do
begin
AttributeField := IUnknown(Element.Key) as _UAAttributeField;
ValueResult := IUnknown(Element.Value) as _ValueResult;
WriteLn(' ', AttributeField.ToString, ' -> ', ValueResult.ToString);
end;
// Extracting specific fields using an event type ID and a simple relative path
WriteLn('Source name: ', eventArgs.EventData.FieldResults.Item[THelperMethods17.UABaseEventObject_Operands_SourceName.ToUAAttributeField].ToString);
WriteLn('Message: ', eventArgs.EventData.FieldResults.Item[THelperMethods17.UABaseEventObject_Operands_Message.ToUAAttributeField].ToString);
end;
class procedure SelectClauses.Main;
const
UAObjectIds_Server = 'nsu=http://opcfoundation.org/UA/;i=2253';
var
Arguments: OleVariant;
Client: TEasyUAClient;
ClientEventHandlers: TClientEventHandlers17;
EndpointDescriptor: string;
EventFilter: _UAEventFilter;
MonitoredItemArguments: _EasyUAMonitoredItemArguments;
MonitoringParameters: _UAMonitoringParameters;
SelectClauses: UAAttributeFieldCollection;
begin
EndpointDescriptor := 'opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer';
// Instantiate the client object and hook events
Client := TEasyUAClient.Create(nil);
ClientEventHandlers := TClientEventHandlers17.Create;
Client.OnEventNotification := ClientEventHandlers.Client_EventNotification;
WriteLn('Subscribing...');
SelectClauses := CoUAAttributeFieldCollection.Create;
// Select specific fields using an event type ID and a simple relative path
SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_NodeId.ToUAAttributeField);
SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_SourceNode.ToUAAttributeField);
SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_SourceName.ToUAAttributeField);
SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_Time.ToUAAttributeField);
SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_Message.ToUAAttributeField);
SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_Severity.ToUAAttributeField);
EventFilter := CoUAEventFilter.Create;
EventFilter.SelectClauses := SelectClauses;
MonitoringParameters := CoUAMonitoringParameters.Create;
MonitoringParameters.SamplingInterval := 1000;
MonitoringParameters.EventFilter := EventFilter;
MonitoringParameters.QueueSize := 1000;
MonitoredItemArguments := CoEasyUAMonitoredItemArguments.Create;
MonitoredItemArguments.EndpointDescriptor.UrlString := EndpointDescriptor;
MonitoredItemArguments.NodeDescriptor.NodeId.StandardName := 'Server';
MonitoredItemArguments.MonitoringParameters := MonitoringParameters;
//MonitoredItemArguments.SubscriptionParameters.PublishingInterval := 0;
MonitoredItemArguments.AttributeId := UAAttributeId_EventNotifier;
Arguments := VarArrayCreate([0, 0], varVariant);
Arguments[0] := MonitoredItemArguments;
Client.SubscribeMultipleMonitoredItems(Arguments);
WriteLn('Processing event notifications for 30 seconds...');
PumpSleep(30*1000);
WriteLn('Unsubscribing...');
Client.UnsubscribeAllMonitoredItems;
WriteLn('Waiting for 5 seconds...');
Sleep(5*1000);
WriteLn('Finished.');
VarClear(Arguments);
FreeAndNil(Client);
FreeAndNil(ClientEventHandlers);
end;
class function THelperMethods17.ObjectTypeIds_BaseEventType: _UANodeId;
var NodeId: _UANodeId;
begin
NodeId := CoUANodeId.Create;
NodeId.StandardName := 'BaseEventType';
Result := NodeId;
end;
class function THelperMethods17.UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand;
var
BrowsePathParser: _UABrowsePathParser;
Operand: _UASimpleAttributeOperand;
begin
BrowsePathParser := CoUABrowsePathParser.Create;
Operand := CoUASimpleAttributeOperand.Create;
Operand.TypeId.NodeId := TypeId;
Operand.QualifiedNames := BrowsePathParser.ParseRelative(simpleRelativeBrowsePathString).ToUAQualifiedNameCollection;
Result := Operand;
end;
class function THelperMethods17.UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand;
var
Operand: _UASimpleAttributeOperand;
begin
Operand := CoUASimpleAttributeOperand.Create;
Operand.TypeId.NodeId.StandardName := 'BaseEventType';
Operand.AttributeId := UAAttributeId_NodeId;
Result := Operand;
end;
class function THelperMethods17.UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand;
begin
Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceNode');
end;
class function THelperMethods17.UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand;
begin
Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceName');
end;
class function THelperMethods17.UABaseEventObject_Operands_Time: _UASimpleAttributeOperand;
begin
Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Time');
end;
class function THelperMethods17.UABaseEventObject_Operands_Message: _UASimpleAttributeOperand;
begin
Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Message');
end;
class function THelperMethods17.UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand;
begin
Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Severity');
end;
// This example shows how to select fields for event notifications.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
const UAAttributeId_NodeId = 1;
const UAAttributeId_EventNotifier = 12;
class ClientEvents {
function EventNotification($Sender, $E)
{
printf("\n");
// Display the event
if (is_null($E->EventData)) {
printf("%s\n", $E);
return;
}
printf("All fields:\n");
foreach ($E->EventData->FieldResults as $Pair)
{
$AttributeField = $Pair->Key;
$ValueResult = $Pair->Value;
printf(" %s -> %s\n", $AttributeField, $ValueResult);
}
// Extracting specific fields using an event type ID and a simple relative path
printf("Source name: %s\n", $E->EventData->FieldResults->Item(UABaseEventObject_Operands_SourceName()->ToUAAttributeField()));
printf("Message: %s\n", $E->EventData->FieldResults->Item(UABaseEventObject_Operands_Message()->ToUAAttributeField()));
}
}
const UAObjectIds_Server = "nsu=http://opcfoundation.org/UA/;i=2253";
$EndpointDescriptor = "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";
// Instantiate the client object and hook events
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
$ClientEvents = new ClientEvents();
com_event_sink($Client, $ClientEvents, "DEasyUAClientEvents");
printf("Subscribing...\n");
$SelectClauses = new COM("OpcLabs.EasyOpc.UA.UAAttributeFieldCollection");
// Select specific fields using an event type ID and a simple relative path
$SelectClauses->Add(UABaseEventObject_Operands_NodeId()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_SourceNode()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_SourceName()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_Time()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_Message()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_Severity()->ToUAAttributeField());
$EventFilter = new COM("OpcLabs.EasyOpc.UA.UAEventFilter");
$EventFilter->SelectClauses = $SelectClauses;
$MonitoringParameters = new COM("OpcLabs.EasyOpc.UA.UAMonitoringParameters");
$MonitoringParameters->EventFilter = $EventFilter;
$MonitoringParameters->QueueSize = 1000;
$MonitoringParameters->SamplingInterval = 1000;
$MonitoredItemArguments = new COM("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments");
$MonitoredItemArguments->EndpointDescriptor->UrlString = $EndpointDescriptor;
$MonitoredItemArguments->NodeDescriptor->NodeId->StandardName = "Server";
$MonitoredItemArguments->MonitoringParameters = $MonitoringParameters;
// $MonitoredItemArguments->SubscriptionParameters->PublishingInterval = 0;
$MonitoredItemArguments->AttributeId = UAAttributeId_EventNotifier;
$Arguments[0] = $MonitoredItemArguments;
$Client->SubscribeMultipleMonitoredItems($Arguments);
printf("Processing event notifications for 30 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 30);
printf("Unsubscribing...\n");
$Client->UnsubscribeAllMonitoredItems;
printf("Waiting for 5 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 5);
function ObjectTypeIds_BaseEventType() {
$NodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId->StandardName = "BaseEventType";
return $NodeId;
}
function UAFilterElements_SimpleAttribute($TypeId, $simpleRelativeBrowsePathString) {
$BrowsePathParser = new COM("OpcLabs.EasyOpc.UA.Navigation.Parsing.UABrowsePathParser");
$Operand = new COM("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand");
$Operand->TypeId->NodeId = $TypeId;
$Operand->QualifiedNames = $BrowsePathParser->ParseRelative($simpleRelativeBrowsePathString)->ToUAQualifiedNameCollection;
return $Operand;
}
function UABaseEventObject_Operands_NodeId() {
$Operand = new COM("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand");
$Operand->TypeId->NodeId->StandardName = "BaseEventType";
$Operand->AttributeId = UAAttributeId_NodeId;
return $Operand;
}
function UABaseEventObject_Operands_SourceNode() {
return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/SourceNode");
}
function UABaseEventObject_Operands_SourceName() {
return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/SourceName");
}
function UABaseEventObject_Operands_Time() {
return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Time");
}
function UABaseEventObject_Operands_Message() {
return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Message");
}
function UABaseEventObject_Operands_Severity() {
return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Severity");
}
// Example output (truncated):
//Subscribing...
//Processing event notifications for 30 seconds...
//
//[] Success
//
//[] Success; Refresh; RefreshInitiated
//
//All fields:
// NodeId="BaseEventType", NodeId -> Success; nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?OnlineState {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
// NodeId="BaseEventType"/EventId -> Success; [16] {95, 68, 22, 205, 114, ...} {System.Byte[]}
// NodeId="BaseEventType"/EventType -> Success; DialogConditionType {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
// NodeId="BaseEventType"/SourceNode -> Success; nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
// NodeId="BaseEventType"/SourceName -> Success; EastTank {System.String}
// NodeId="BaseEventType"/Time -> Success; 9/10/2019 8:08:23 PM {System.DateTime}
// NodeId="BaseEventType"/ReceiveTime -> Success; 9/10/2019 8:08:23 PM {System.DateTime}
// NodeId="BaseEventType"/LocalTime -> Success; 00:00, DST {OpcLabs.EasyOpc.UA.UATimeZoneData}
// NodeId="BaseEventType"/Message -> Success; The dialog was activated {System.String}
// NodeId="BaseEventType"/Severity -> Success; 100 {System.Int32}
//Source name: Success; EastTank {System.String}
//Message: Success; The dialog was activated {System.String}
//
//All fields:
// NodeId="BaseEventType", NodeId -> Success; nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Red {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
// NodeId="BaseEventType"/EventId -> Success; [16] {124, 156, 219, 54, 120, ...} {System.Byte[]}
// NodeId="BaseEventType"/EventType -> Success; ExclusiveDeviationAlarmType {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
// NodeId="BaseEventType"/SourceNode -> Success; nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
// NodeId="BaseEventType"/SourceName -> Success; EastTank {System.String}
// NodeId="BaseEventType"/Time -> Success; 10/14/2019 4:00:13 PM {System.DateTime}
// NodeId="BaseEventType"/ReceiveTime -> Success; 10/14/2019 4:00:13 PM {System.DateTime}
// NodeId="BaseEventType"/LocalTime -> Success; 00:00, DST {OpcLabs.EasyOpc.UA.UATimeZoneData}
// NodeId="BaseEventType"/Message -> Success; The alarm was acknoweledged. {System.String}
// NodeId="BaseEventType"/Severity -> Success; 500 {System.Int32}
//Source name: Success; EastTank {System.String}
//Message: Success; The alarm was acknoweledged. {System.String}
//
//...