nauful / LibUA

Open-source OPC UA client and server library
Apache License 2.0
262 stars 94 forks source link

I would need help with monitoreditems please #80

Closed ne-fas-tus closed 2 years ago

ne-fas-tus commented 2 years ago

Not knowing where to contact you I do it here. I have already written to you in a previous report that I would like to communicate with an OPC-UA server of a Modicon m241 PLC from a client application made in Unity3D. I imported your library and managed to connect to the server. I can activate a session, a subscription, browse the variables, read the values, write them etc... as written in your sample program. What I would like to do now is to use the MonitoredItems but I did not understand how it works. After I call the CreateMonitoredItems method to monitor a variable, what should I do? Should I receive NotificationMessages from the server from which to extract the variable? How do I read them? I don't understand how I have to do it. Sorry if I'm so ignorant! If you could write a few lines of example, I would be infinitely grateful

nauful commented 2 years ago

As I understand it, you have a client and you want to subscribe to server nodes.

Start by creating a subscription: https://github.com/nauful/LibUA/blob/7c9e1a22ba38743af4dbdd3bdb1420788e2238e6/NET%20Core/TestClient/Program.cs#L239

Create a client handle for the nodes you want to monitor (user-defined, I just use 1, 2, 3... in the sample): https://github.com/nauful/LibUA/blob/7c9e1a22ba38743af4dbdd3bdb1420788e2238e6/NET%20Core/TestClient/Program.cs#L249

Create some monitored items for this subscription: https://github.com/nauful/LibUA/blob/7c9e1a22ba38743af4dbdd3bdb1420788e2238e6/NET%20Core/TestClient/Program.cs#L252 Specifically, you probably just want to monitor NodeAttribute.Value: https://github.com/nauful/LibUA/blob/7c9e1a22ba38743af4dbdd3bdb1420788e2238e6/NET%20Core/TestClient/Program.cs#L260 Note how your user-defined client handles are passed in (e.g. first monitored item uses first user-defined handle=1, second has handle=2, etc). monitorCreateResults should give you some helpful information.

Override NotifyDataChangeNotifications: https://github.com/nauful/LibUA/blob/7c9e1a22ba38743af4dbdd3bdb1420788e2238e6/NET%20Core/TestClient/Program.cs#L79 This method is now called whenever a change for those monitored items comes back. You receive subscriptionId and a sequence of user-defined handles -> notifications.

Try stepping through the TestServer and TestClient projects if you get stuck. TestServer publishes data once per second, TestClient subscribes to 3 of those nodes and prints updates to the console.

ne-fas-tus commented 2 years ago

Thanks for the reply. Unfortunately, it seems that the NotifyDataChangeNotifications method is never called. The server in fact (which is on a PLC, so I do not know how to modify it) accepts the request to create a monitoredItem with StatusCode GOOD but ends there. Conversely, if I add a variable with UA-Expert, the server constantly updates its value. I didn't try with the TestServer script. I can try to run it but it wouldn't solve the problem as I can't handle the code on the PLC server.

ne-fas-tus commented 2 years ago

I correct myself. The NotifyDataChangeNotifications method is called, but the for loop is not executed because clientHandles has length 0...

            public override void NotifyDataChangeNotifications(uint subscrId, uint[] clientHandles, DataValue[] notifications)
            {
                Debug.Log("CALLED");
                for (int i = 0; i < clientHandles.Length; i++)
                {
                    Debug.Log("subscrId "+ subscrId + " handle "+ clientHandles[i]+":" + notifications[i].Value.ToString());
                }
            }
OUTPUT: "CALLED"
        "CALLED"
        "CALLED"
...

maybe I'm doing something wrong in monitoringParameters :-(

nauful commented 2 years ago

Try MonitoringMode.Sampling, perhaps the PLC is clock based. If not that, I suspect UaExpert is reading off a timer and not actually subscribing.

If Sampling does not work, take a capture of network traffic with Wireshark (UaExpert-Server), filter by port to the ua connection, then share that. I can take a look at how UaExpert is doing this.

ne-fas-tus commented 2 years ago

Solved! Then, it also works with MonitoringMode.Reporting. The problem was that I was getting the ID of the node to be monitored wrong but I got GOOD from the CreateMonitoredItems method. I logged the statusCode of the monitorsCreateResults, it was BadIdParameter... Now the NotifyDataChangeNotifications method is called and returns the updated value correctly. However, I had not understood the operation well before I explained it to myself. Thank you thank you thank you

nauful commented 2 years ago

Glad to hear it worked.