Reputation: 21
I've wrote code for OPC UA
client that has 10 subscription each handling 3 nodeids
. Even though monitored items are being created for every node id, the subscription only receives value from the last nodeid
in each subscription.
public static void main(String[] args) throws Exception {
OpcUaClient client = OpcUaClient.create("opc.tcp://KCT-L-610:53530/OPCUA/SimulationServer"); // Update with your Prosys OPC UA Server endpoint
client.connect().get();
// Create 10 subscriptions, each handling 3 tags
for (int i = 0; i < 10; i++) {
createSubscription(client, i);
}
// Sleep to allow subscriptions to run and collect data
Thread.sleep(10000); // Example: run for 10 seconds before completing
client.disconnect().get();
}
private static void createSubscription(OpcUaClient client, int subscriptionIndex) throws Exception {
// Create a new subscription every time
UaSubscription subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
// Define the 3 tags (nodes) to monitor for this subscription
List<ReadValueId> readValueIds = newArrayList(
new ReadValueId(new NodeId(3, 1007 + subscriptionIndex * 3), AttributeId.Value.uid(), null, QualifiedName.NULL_VALUE), // Tag 1 for Subscription
new ReadValueId(new NodeId(3, 1008 + subscriptionIndex * 3), AttributeId.Value.uid(), null, QualifiedName.NULL_VALUE), // Tag 2 for Subscription
new ReadValueId(new NodeId(3, 1009 + subscriptionIndex * 3), AttributeId.Value.uid(), null, QualifiedName.NULL_VALUE) // Tag 3 for Subscription
);
// Create a MonitoringParameters object for the subscription
MonitoringParameters parameters = new MonitoringParameters(
subscription.nextClientHandle(),
1000.0, // Sampling interval: 1 second
null, // No filter, use default
uint(10), // Queue size
true // Discard oldest value if queue is full
);
// Create requests for the monitored items
List<MonitoredItemCreateRequest> requests = newArrayList();
for (ReadValueId readValueId : readValueIds) {
requests.add(new MonitoredItemCreateRequest(readValueId, MonitoringMode.Reporting, parameters));
}
// Create the monitored items and set a callback for value updates
//UaSubscription.ItemCreationCallback onItemCreated = (item, id) -> item.setValueConsumer((item1, value) -> onSubscriptionValue(item1, value, subscriptionIndex));
UaSubscription.ItemCreationCallback onItemCreated = (item, id) -> {
item.setValueConsumer((item1, value) -> onSubscriptionValue(item1, value, subscriptionIndex));
};
// Create monitored items and process
List<UaMonitoredItem> items = subscription.createMonitoredItems(
TimestampsToReturn.Both,
requests,
onItemCreated
).get();
for (UaMonitoredItem item : items) {
if (item.getStatusCode().isGood()) {
logger.info("Subscription {}: Monitored item created for nodeId={}", subscriptionIndex, item.getReadValueId().getNodeId());
} else {
logger.warn("Subscription {}: Failed to create item for nodeId={} (status={})", subscriptionIndex, item.getReadValueId().getNodeId(), item.getStatusCode());
}
}
}
private static void onSubscriptionValue(UaMonitoredItem item, DataValue value, int subscriptionIndex) {
// This method is called when the monitored item value is updated
logger.info("Subscription {}: Received value for nodeId={}: {}", subscriptionIndex, item.getReadValueId().getNodeId(), value.getValue());
}
and this was the output i was getting
14:56:45.402 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 0: Received value for nodeId=NodeId{ns=3, id=1009}: Variant{value=0.0}
14:56:45.403 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 0: Received value for nodeId=NodeId{ns=3, id=1009}: Variant{value=-1.618126}
14:56:45.403 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 0: Received value for nodeId=NodeId{ns=3, id=1009}: Variant{value=-2.0}
14:56:45.413 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 1: Received value for nodeId=NodeId{ns=3, id=1012}: Variant{value=0.1333334}
14:56:45.417 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 1: Received value for nodeId=NodeId{ns=3, id=1012}: Variant{value=27.0}
14:56:45.417 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 1: Received value for nodeId=NodeId{ns=3, id=1012}: Variant{value=0.0}
14:56:45.417 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 1: Received value for nodeId=NodeId{ns=3, id=1012}: Variant{value=28.0}
14:56:45.427 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 2: Received value for nodeId=NodeId{ns=3, id=1015}: Variant{value=-5.235019}
14:56:45.427 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 2: Received value for nodeId=NodeId{ns=3, id=1015}: Variant{value=0.209057}
14:56:45.427 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 2: Received value for nodeId=NodeId{ns=3, id=1015}: Variant{value=-4.472503}
14:56:45.427 [milo-shared-thread-pool-3] INFO c.m.o.MultipleSubscriptionExample - Subscription 2: Received value for nodeId=NodeId{ns=3, id=1015}: Variant{value=0.0}
Upvotes: 1
Views: 33
Reputation: 6985
You are erroneously re-using the same MonitoringParameters
for each group of 3 items you create, rather than creating a new one, which is necessary because each parameters should contain a unique client handle.
// Create a MonitoringParameters object for the subscription MonitoringParameters parameters = new MonitoringParameters( subscription.nextClientHandle(), 1000.0, // Sampling interval: 1 second null, // No filter, use default uint(10), // Queue size true // Discard oldest value if queue is full ); // Create requests for the monitored items List<MonitoredItemCreateRequest> requests = newArrayList(); for (ReadValueId readValueId : readValueIds) { requests.add(new MonitoredItemCreateRequest(readValueId, MonitoringMode.Reporting, parameters)); }
Upvotes: 0