Search code examples
opc-uamilo

OPC UA Milo - Collection of Monitored Items in Callback onDataChangeNotification


I am testing some things with the SubscriptionExample of the Eclipse Milo OPC-UA project (https://github.com/eclipse/milo) and found a behavior which I am not sure it is intended. I created two MonitoredItemCreateRequests for each of two different nodes on the Milo test server (opc.tcp://milo.digitalpetri.com:62541/milo/) and passed them to the createMonitoredItems() method of the subscription. Status code for both items is good. Since I want to get all collected values for both monitored items at once I added a NotificationListener to the subscription.

NodeId dynNodeId = NodeId.parse("ns=2;s=Dynamic/RandomInt32");
NodeId statNodeId = NodeId.parse("ns=2;s=Dynamic/RandomDouble");

Here is the callback method to receive the data values:

@Override
public void onDataChangeNotification(UaSubscription subscription, List<UaMonitoredItem> monitoredItems, List<DataValue> dataValues, DateTime publishTime) {
        Iterator<UaMonitoredItem> itemIterator = monitoredItems.iterator();
        Iterator<DataValue> dataValueIterator = dataValues.iterator();

        while(itemIterator.hasNext() && dataValueIterator.hasNext()) {
            logger.info("subscription value received: item={}, value={}",
                    itemIterator.next().getReadValueId().getNodeId(), dataValueIterator.next().getValue());
        }
    }

I expected that the list of monitoredItems holds the items with the OPC-UA node ID in the order corresponding to the list of dataValues. By debugging one can see that the size of both collections are equal -- that is fine. But all the monitored items in the callback have the same node ID? The node ID for the logged Double values should have the ID ns=2;s=Dynamic/RandomDouble.

15:32:01.221 [milo-shared-thread-pool-0] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=0.19167566173987927}
15:32:01.221 [milo-shared-thread-pool-0] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=0.17914743791503218}
15:32:01.221 [milo-shared-thread-pool-0] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=-1911450762}
15:32:01.221 [milo-shared-thread-pool-0] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=-238565139}
15:32:02.172 [milo-shared-thread-pool-1] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=0.004420353528696297}
15:32:02.173 [milo-shared-thread-pool-1] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=1391780361}
15:32:03.171 [milo-shared-thread-pool-2] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=0.5815483661983246}
15:32:03.172 [milo-shared-thread-pool-2] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=560950904}
15:32:04.245 [milo-shared-thread-pool-2] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=0.18123040450226635}
15:32:04.246 [milo-shared-thread-pool-2] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=521198031}
15:32:05.258 [milo-shared-thread-pool-2] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=0.42193483414925215}
15:32:05.258 [milo-shared-thread-pool-2] INFO  o.e.m.e.client.SubscriptionExample - subscription value received: item=NodeId{ns=2, id=Dynamic/RandomInt32}, value=Variant{value=680732464}

I am aware of the possibility of using a individual callback for each node, but I want to handle them all at once.

Is this behavior intended or could it be a bug in the server implementation?

Edit:

During debugging I found that the collection of the monitoredItems in the callback holds x times the same object (same memory address) but the x dataValues differ.

Same behavior if I try it with the local OPC server from the milo example.


Solution

  • You probably used the same clientHandle value in both of your items MonitoringParameters when you created them.

    If not can you post your entire example code?