Professional OPC
Development Tools

logos

UA Alarms&Conditions in FreePascal (Lazarus)

More
16 Sep 2016 07:19 - 19 Sep 2016 07:23 #4332 by Joachim@FreePascal
I changed the event method like this:
procedure TForm1.OnEvent(Sender: TObject; sender1: OleVariant; eventArgs: _EasyUAEventNotificationEventArgs);
var
  UAEventData:_UAEventData;
begin
  if assigned(eventArgs.Exception) then
  begin
    memo1.Lines.Add(EventArgs.ErrorMessage);
    if assigned(UAEventData) then // never happens, why
      memo1.Lines.Add(UAEventData.ToString);
  end;
  //
  try
    memo1.Lines.Add(EventArgs.ToString);
    memo1.Lines.Add(EventArgs.DisplayString);
    memo1.Lines.Add(EventArgs.ErrorMessage);
    memo1.Lines.Add(inttostr(EventArgs.Diagnostics.Count));
    UAEventData :=EventArgs.EventData;
    if assigned(UAEventData) then // never happens, why
      memo1.Lines.Add(UAEventData.ToString);
  except
    memo1.Lines.Add('Exception');
  end;
end;

This is what I got back:
[] Success
[] Success

0
OPC-UA service result - An error specific to OPC-UA service occurred.
---- SERVICE RESULT ----
StatusCode: {BadMonitoredItemFilterInvalid} = 0x80430000 (2151874560)

[] *** Failure -2143092736 (0x80430000): OPC-UA service result - An error specific to OPC-UA service occurred.
[] *** Failure -2143092736 (0x80430000): OPC-UA service result - An error specific to OPC-UA service occurred.
OPC-UA service result - An error specific to OPC-UA service occurred.
---- SERVICE RESULT ----
StatusCode: {BadMonitoredItemFilterInvalid} = 0x80430000 (2151874560)

0


I hope this helps,
thank You
Last edit: 19 Sep 2016 07:23 by admin.

Please Log in or Create an account to join the conversation.

More
16 Sep 2016 07:02 #4331 by support
Hello, some notes from me, in order to allow to troubleshoot:

1. First thing that needs to be checked is whether there are some events coming in with non-null eventArgs.Exception. Instead of simply ignoring that ('exit'), in case of non-null eventArgs.Exception, add the eventArgs.ErrorMessage to memo1.Lines.

2. You stated that eventArgs.EventData is always null, but have not stated whetehr the code ever
gets past the 'if assigned(eventArgs.Exception) then exit;' statement. Please clarify.

3. make some 'memo1.Lines.Add...' in the 'except' part of the 'try' statement.

Ideally, make the changes, and then post here the output.

Thank you

Please Log in or Create an account to join the conversation.

More
16 Sep 2016 06:54 #4330 by support
From: J.
Sent: Friday, September 16, 2016 8:48 AM
[...]

Hello [...]
I really would like to use the QuickOPC component for the communication with the Bosch MTX control.
May you can help me to make it run…
Best regards

J.
AxcEasyUAClient := TAxcEasyUAClient.Create(self);
AxcEasyUAClient.OnEventNotification:=OnEvent;
res:=AxcEasyUAClient.OleServer.SubscribeEvent(servername,'ns=16;s=DiagnosisLogbook', 1000);
 
procedure TForm1.OnEvent(Sender: TObject; sender1: OleVariant; eventArgs: _EasyUAEventNotificationEventArgs);
var
  UAEventData:_UAEventData;
begin
  if assigned(eventArgs.Exception) then
    exit;
  //
  try
    memo1.Lines.Add(EventArgs.ToString);
    memo1.Lines.Add(EventArgs.DisplayString);
    memo1.Lines.Add(EventArgs.ErrorMessage);
    memo1.Lines.Add(inttostr(EventArgs.Diagnostics.Count));
    UAEventData :=EventArgs.EventData;
    if assigned(UAEventData) then // never happens, why
      memo1.Lines.Add(UAEventData.ToString);
  except
  end;
end;

Please Log in or Create an account to join the conversation.

More
25 Jul 2016 13:39 #4254 by support
Dear Sir,

we have some very basic examples in Delphi for UA Alarms&Conditions that come with the product (just look under the install directory, ExamplesCom\OP). The reason why we do not have more examples is because there is such a big number of tools and languages from which QuickOPC can be used, that it makes it impossible to provide high number of examples in all of them. The Delphi examples show OPC UA Alarms&Conditions, but currently without filtering. It look e.g. like this:
type
  TClientEventHandlers2 = class
    procedure OnEventNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUAEventNotificationEventArgs);
  end;
 
procedure TClientEventHandlers2.OnEventNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUAEventNotificationEventArgs);
begin
  // Display the event
  WriteLn(eventArgs.ToString);
end;
 
class procedure SubscribeEvent.Main;
var
  Client: TEasyUAClient;
  ClientEventHandlers2: TClientEventHandlers2;
begin
  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers2 := TClientEventHandlers2.Create;
  Client.OnEventNotification := ClientEventHandlers2.OnEventNotification;
 
  WriteLn('Subscribing...');
  Client.SubscribeEvent(
    'opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer',
    'nsu=http://opcfoundation.org/UA/;i=2253',  // UAObjectIds.Server
    1000);
 
  WriteLn('Processing event notifications for 30 seconds...');
  PumpSleep(30*1000);
 
  //WriteLn('Unsubscribing...');
  Client.UnsubscribeAllMonitoredItems;
 
  WriteLn('Waiting for 5 seconds...');
  PumpSleep(5*1000);
end;

It can also be done with hooking events (using a "pull" mechanism), and there is an example for it as well in the product.

As to the filter: You wrote "it failed". That's not enough information. What precisely have you tried, and what were the results? I would be more than happy to help, and even we can even commonly create some FreePascal examples that would then help other users.

Creating a filter can be fairly complicated - because UA is very flexible in this manner. Below some example in C#. Once you understand what is going on, we can try to do an equivalent, or something similar, in Delphi or FreePascal.
        class SelectClauses
        {
            public static void Main()
            {
                // Instantiate the client object and hook events
                var easyUAClient = new EasyUAClient();
                easyUAClient.EventNotification += easyUAClient_EventNotification;
 
                Console.WriteLine("Subscribing...");
                easyUAClient.SubscribeEvent(
                    "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer",
                    UAObjectIds.Server,
                    1000,
                    new UAAttributeFieldCollection
                    {
                        // Select specific fields using standard operand symbols
                        UABaseEventObject.Operands.NodeId,
                        UABaseEventObject.Operands.SourceNode,
                        UABaseEventObject.Operands.SourceName,
                        UABaseEventObject.Operands.Time,
 
                        // Select specific fields using an event type ID and a simple relative path
                        UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Message"),
                        UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Severity"),
                    });
 
                Console.WriteLine("Processing event notifications for 30 seconds...");
                System.Threading.Thread.Sleep(30 * 1000);
 
                Console.WriteLine("Unsubscribing...");
                easyUAClient.UnsubscribeAllMonitoredItems();
 
                Console.WriteLine("Waiting for 5 seconds...");
                System.Threading.Thread.Sleep(5 * 1000);
            }
 
            static void easyUAClient_EventNotification(object sender, EasyUAEventNotificationEventArgs e)
            {
                Console.WriteLine();
 
                // Display the event
                if (e.EventData == null)
                {
                    Console.WriteLine(e);
                    return;
                }
                Console.WriteLine("All fields:");
                foreach (KeyValuePair<UAAttributeField, ValueResult> pair in e.EventData.FieldResults)
                {
                    UAAttributeField attributeField = pair.Key;
                    ValueResult valueResult = pair.Value;
                    Console.WriteLine("  {0} -> {1}", attributeField, valueResult);
                }
                // Extracting a specific field using a standard operand symbol
                Console.WriteLine("Source name: {0}", 
                    e.EventData.FieldResults[UABaseEventObject.Operands.SourceName]);
                // Extracting a specific field using an event type ID and a simple relative path
                Console.WriteLine("Message: {0}", 
                    e.EventData.FieldResults[UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Message")]);
            }
        }

and
        class WhereClause
        {
            public static void Main()
            {
                // Instantiate the client object and hook events
                var easyUAClient = new EasyUAClient();
                easyUAClient.EventNotification += easyUAClient_EventNotification;
 
                Console.WriteLine("Subscribing...");
                easyUAClient.SubscribeEvent(
                    "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer",
                    UAObjectIds.Server,
                    1000,
                    new UAEventFilterBuilder(
                        // Either the severity is >= 500, or the event comes from a specified source node
                        UAFilterElements.Or(
                            UAFilterElements.GreaterThanOrEqual(UABaseEventObject.Operands.Severity, 500),
                            UAFilterElements.Equals(
                                UABaseEventObject.Operands.SourceNode, 
                                new UANodeId("nsu=http://opcfoundation.org/Quickstarts/AlarmCondition;ns=2;s=1:Metals/SouthMotor"))),
                        UABaseEventObject.AllFields));
 
                Console.WriteLine("Processing event notifications for 30 seconds...");
                System.Threading.Thread.Sleep(30 * 1000);
 
                Console.WriteLine("Unsubscribing...");
                easyUAClient.UnsubscribeAllMonitoredItems();
 
                Console.WriteLine("Waiting for 5 seconds...");
                System.Threading.Thread.Sleep(5 * 1000);
            }
 
            static void easyUAClient_EventNotification(object sender, EasyUAEventNotificationEventArgs e)
            {
                // Display the event
                Console.WriteLine(e);
            }
        }


Best regards

Please Log in or Create an account to join the conversation.

More
25 Jul 2016 13:25 #4253 by support
From: J.
Sent: Friday, July 22, 2016 7:42 AM
...

Hello Mr Zahradnik,
thank you for your hints.
I have used version 5.3. I develop using FreePascal. Is there any Pascal (Delphi) example available for Alarms & Conditions?
Later I used version 5.4, but it failed also. How can I set a filter for the subscription? I want to subscribe the DiagnosisLogbook of a Bosch control.

Best regards

J.

Please Log in or Create an account to join the conversation.

More
25 Jul 2016 13:24 #4252 by support
Dear Sir,

Thank you for your interest in our products.

QuickOPC version 5.40 supports OPC-UA Alarms & Conditions. Are you using this version?
If not, please have a look at it.
If you are already using it, but something in relation to Alarms&Conditions does not work as expected, please inform me about the details.

Best regards

Please Log in or Create an account to join the conversation.

More
25 Jul 2016 13:24 #4251 by support
From: OPC Labs Download Follow-up Form [...]
Sent: Thursday, July 14, 2016 4:26 PM
To: Zbynek Zahradnik <...>
Subject: OPC Labs Download Follow-up Form

...

Hello,
I have played around with the EasyOpcUA typelib with FreePascal (Lazarus). I have to establish a connection with an OPC.UA Server. This runs so far, but I can not access the Alarm-Event via Filter.
Is it planed to implement this feature?

J.

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.193 seconds

      

 Recommend this on Google