Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

"SubscribeDataChange" using the read function

More
26 Nov 2019 13:02 #8028 by Moien
First: I commented out the parts in my code related to the subscribe data change and reading functions. Which means in my Delphi application I am not reading any data from OPC Server and I am not subscribing any data changes.
Second: Including those two parts in my ccode lead to a total CPU usage of 60% and when I am commenting out those parts the CPU usage reduces to 20% in total!

Best regards,
Moien

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

More
26 Nov 2019 12:50 - 26 Nov 2019 12:50 #8027 by support
Hello,

can you please give me more information to "I already commented out the handlers regarding both read function and data change function. I get something like 40 to 50 percent less CPU usage!"

First, I do not know what you mean by "handler", when it goes about the Read. There is no (event) handler for Read. Are you talking about the code that processes the results, after the Read call?

Second, can you just confirm that I understand it well: So, with the code commented out, the CPU usage goes, very roughly, from e.g. 30% to 18% ?

Thank you
Last edit: 26 Nov 2019 12:50 by support.

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

More
26 Nov 2019 12:43 #8026 by support
Let's have a look at the example I pointed to before:
static void client_DataChangeNotification(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            // Display value
            if (e.Succeeded)
                Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value);
            else
                Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief);
        }
So, it prints out the Value.

If you wanted the timestamps or the status, you have additional properties on the e.AttributeData, such as

.ServerTimestamp
.SourceTimestamp
.StatusCode

opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...A.UAAttributeData_members.html

Best regards

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

More
26 Nov 2019 12:34 #8025 by Moien
I already commented out the handlers regarding both read function and data change function. I get something like 40 to 50 percent less CPU usage!

Best regards,
Moien

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

More
26 Nov 2019 12:30 #8024 by support
Hello,
referring to my previous response, most likely you do not have to do any Read.

Second: The CPU usage is indeed quite high. We are normally not observing that with couple with this kind of load.
In order to rule out the actual data processing demands, can you please comment out all code that you have in the data change notification handler, leaving the handler empty, and the re-run the test, and measure the CPU usage again?

What I trying to determine is whether CPU usage comes from the event handler, or elsewhere.

Best regards

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

More
26 Nov 2019 12:29 #8023 by Moien
How can I get the time stamp and status using subscriptions?

Best regards,
Moien

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

More
26 Nov 2019 12:24 #8022 by support
Hello,

subscribing means that at the beginning, the server will send you the value it has currently. So, if you want the current value plus all updates (which is quite common), you can use just subscriptions; no reads are necessary.

Best regards
The following user(s) said Thank You: Moien

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

More
26 Nov 2019 10:31 - 26 Nov 2019 12:26 #8021 by Moien
This is what I have done to subscribe data changes:
SubscribeChangeClient := TEasyUAClient.Create(nil);
 
    SetLength(MonitoredItemArguments,Length(OPCServerItemArray)-NoV_DB100);
    MonitoringParameters := CoUAMonitoringParameters.Create;
    MonitoringParameters.SamplingInterval := 1000;
 
    for J := NoV_DB100 to Length(OPCServerItemArray)-1 do begin
       Name := OPCServerItemArray[J].Source + '.' + OPCServerItemArray[J].ItemName;
       MonitoredItemArguments[J-NoV_DB100] := CoEasyUAMonitoredItemArguments.Create;
       MonitoredItemArguments[J-NoV_DB100].EndpointDescriptor.UrlString := Url_String;
       MonitoredItemArguments[J-NoV_DB100].NodeDescriptor.NodeId.ExpandedText := 'nsu='+ nsu + ';s=Local Items.' + Name;
       MonitoredItemArguments[J-NoV_DB100].MonitoringParameters := MonitoringParameters;
 
    end;
 
    SubscribeArguments := VarArrayCreate([0, Length(OPCServerItemArray)-NoV_DB100-1], varVariant);
    for I := 0 to Length(OPCServerItemArray)-NoV_DB100-1 do begin
       SubscribeArguments[I] := MonitoredItemArguments[I];
    end;
 
    TVarData(HandleArray).VType := varArray or varVariant;
    TVarData(HandleArray).VArray := PVarArray(
    SubscribeChangeClient.SubscribeMultipleMonitoredItems(PSafeArray(TVarData(SubscribeArguments).VArray)));
It still adds 30% more load on the CPU. I cannot use "UnsubscribeAllMonitoredItems" at the end, as I have to read those values 24/7. Moreover I have another block to read those values as the following:
SetLength(ReadOPCUAArguments,Length(OPCServerItemArray)-NoV_DB100);
 
        for J := NoV_DB100 to Length(OPCServerItemArray)-1 do begin
           Name := OPCServerItemArray[J].Source + '.' + OPCServerItemArray[J].ItemName;
           ReadOPCUAArguments[J-NoV_DB100] := CoUAReadArguments.Create;
           ReadOPCUAArguments[J-NoV_DB100].EndpointDescriptor.UrlString := Url_String;
           ReadOPCUAArguments[J-NoV_DB100].NodeDescriptor.NodeId.ExpandedText := 'nsu='+ nsu + ';s=Local Items.' + Name;
        end;
 
        OPCUAArguments := VarArrayCreate([0, Length(OPCServerItemArray)-NoV_DB100-1], varVariant);
        for I := 0 to Length(OPCServerItemArray)-NoV_DB100-1 do begin
           OPCUAArguments[I] := ReadOPCUAArguments[I];
        end;
 
        // Perform the operation
        TVarData(OPCUAResults).VType := varArray or varVariant;
        TVarData(OPCUAResults).VArray := PVarArray(OPCUAClientRead.ReadMultiple(
        PSafeArray(TVarData(OPCUAArguments).VArray)));
At the end of the day, I get more than 60% loading on the CPU which could not be the case, while some other programs like Siemens WinCC are running on the same server!
Any idea how to improve the performance?

Best regards,
Moien
Last edit: 26 Nov 2019 12:26 by support.

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

More
26 Nov 2019 09:11 #8020 by Moien
Thank you for your response. Why aren't the values updated just using "ReadMultiple"? It means I should go throu my variables two times, one time for reading them and one more time for updating them! I have more than 300 variables. It seems kind of a hassle to do that and too much load on CPU performance! Isn't there any better solution for that?

Best regards,
Moien

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

More
Moderators: support
Time to create page: 0.068 seconds