apache / plc4x

PLC4X The Industrial IoT adapter
https://plc4x.apache.org/
Apache License 2.0
1.2k stars 389 forks source link

[Bug]: plc4j-driver-opcua - No subscription events are generated for `addCyclicField(...)` tags #1102

Open takraj opened 9 months ago

takraj commented 9 months ago

What happened?

The documentation says that tags added via addCyclicField(...) will be polled in the specified time intervals. My expectation is to get subscription events each time these fields are getting polled, but apparently I don't get any. The other two types of subscriptions are working OK, however I don't see any difference between addChangeOfStateField(...) and addEventField(...) with the OPC-UA driver.

Example code to reproduce the issue:

PlcDriverManager driverManager = new PlcDriverManager();
try (PlcConnection opcuaConnection = driverManager.getConnection("opcua:tcp://opcuaserver.com:48010")) {
    PlcSubscriptionRequest request = opcuaConnection.subscriptionRequestBuilder()
            .addCyclicField(
                    "Demo",
                    "ns=2;s=Demo.Static.Scalar.String",
                    Duration.ofSeconds(1)
            )
            .build();

    PlcSubscriptionResponse response = request.execute().get();
    if (response.getResponseCode("Demo") != PlcResponseCode.OK) {
        throw new RuntimeException("Not OK.");
    }

    AtomicLong counter = new AtomicLong();

    response.getSubscriptionHandle("Demo").register(
            subscriptionEvent -> {
                counter.incrementAndGet();
                System.out.println(subscriptionEvent);
            }
    );

    Thread.sleep(10 * 1000); // 10 seconds

    if (counter.get() == 0) {
        throw new RuntimeException("No events received.");
    }
}

System.out.println("OK");

Logs

Version

v0.10.0

Programming Languages

Protocols

chrisdutz commented 9 months ago

@hutcheb or @sruehl ... I know you two are involved a bit more in this protocol ... can you help here?

hutcheb commented 9 months ago

So it turns out the OPCUA subscriptions don’t support a poling interval (Return a value every X seconds). They only support returning values when they change.

We would have to create an internal register of values, update it every time we see values change, and then use the internal value to generate a subscription response every X seconds.

chrisdutz commented 9 months ago

I guess building a general purpose subscription simulator that can be used for any driver would be a good idea.