plc4x icon indicating copy to clipboard operation
plc4x copied to clipboard

[Bug]: ads driver, writing multiple tags in 1 writeRequestBuilder doesnt work anymore

Open patrickboisclair opened this issue 1 year ago • 12 comments

What happened?

Hi all,

Beckhoff ads driver.

When trying to write multiple TAGS at once, seems to be broken at the moment. Doing the same thing with 0.9.1 works just fine.

Example:

            PlcWriteRequest writeRequest = plcConnection.writeRequestBuilder()
                                                        .addTagAddress("ValX", "MAIN.ValX", new PlcDINT(154))
                                                        .addTagAddress("ValY", "MAIN.ValY", new PlcDINT(178))
                                                        .build();

            PlcWriteResponse writeResponse = writeRequest.execute().get(); 

Results in:

Exception in thread "main" java.util.concurrent.ExecutionException: org.apache.plc4x.java.api.exceptions.PlcException: Error at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396) at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2073) at com.epsilia.Beckhoff.execute(Beckhoff.java:48) at com.epsilia.Main.main(Main.java:6) Caused by: org.apache.plc4x.java.api.exceptions.PlcException: Error at org.apache.plc4x.java.ads.protocol.AdsProtocolLogic.lambda$84(AdsProtocolLogic.java:1108) at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65) at org.apache.plc4x.java.spi.Plc4xNettyWrapper.decode(Plc4xNettyWrapper.java:183) at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88) at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:833)

Version

v0.12.0

Programming Languages

  • [X] plc4j
  • [ ] plc4go
  • [ ] plc4c
  • [ ] plc4net

Protocols

  • [ ] AB-Ethernet
  • [X] ADS /AMS
  • [ ] BACnet/IP
  • [ ] CANopen
  • [ ] DeltaV
  • [ ] DF1
  • [ ] EtherNet/IP
  • [ ] Firmata
  • [ ] KNXnet/IP
  • [ ] Modbus
  • [ ] OPC-UA
  • [ ] S7

patrickboisclair avatar Feb 27 '24 15:02 patrickboisclair

The thing is that this is explicitly tested in the ManualADS test ... there I read each tag sepatately, write it separately and then read all of them in one big read, but with random order of the tags ... this test always passed.

I guess there must be something else odd going on.

Could you possibly provide a bit more information:

  • Which Type of PLC are you using?
  • Which version of TwinCat is it running on?
  • A Wireshark recording when running above test.

chrisdutz avatar Feb 27 '24 15:02 chrisdutz

Buuuuuuut ... now that you're mentioning it ... I am not doing a mixed bulk write of all of them ... hmmm ... possibly something I could look into. But still the above information would still be useful.

chrisdutz avatar Feb 27 '24 15:02 chrisdutz

I'll provide the info in 1 or 2 hours

patrickboisclair avatar Feb 27 '24 15:02 patrickboisclair

  • PLC Type: CX8190 / Standard
  • TwinCat: v3.1.4024.11
  • WireShare recording attached (NOTE: I launched the APP 3 times, it simply do the writeRequest as mentionned in the original post) plc4x_0_12_0_ads_multiple_writes.zip

patrickboisclair avatar Feb 27 '24 18:02 patrickboisclair

Hi all,

Just askin if there's any news on this ?

patrickboisclair avatar Mar 04 '24 19:03 patrickboisclair

Haven't had any time yet... Also probably not in the next week, as I'll be snowboarding. I'll try to have a look after that.

chrisdutz avatar Mar 04 '24 20:03 chrisdutz

Oh nice ! We got almost no snow this winter here, making skiing and snowboarding, almost undoable :(

Thanks for the heads up, appreciate it !

patrickboisclair avatar Mar 05 '24 11:03 patrickboisclair

I was able to confirm the issue by extending the ManualTest class to not only do single-item write tests, but also the random multi-item tests. Here the test failed, as you described. Also did the S7 manual test of the quick-tests that I was able to run on my hardware.

chrisdutz avatar Apr 12 '24 14:04 chrisdutz

Ty Chris for taking time to look into this. Really appreciated.

I can test on my hardware when a fix will be available if it can helps.

patrickboisclair avatar Apr 12 '24 14:04 patrickboisclair

Guess what line it's happening in? Bildschirmfoto 2024-04-12 um 16 34 54

chrisdutz avatar Apr 12 '24 14:04 chrisdutz

So the root cause is an "invalid size" in the multi-item write ... if anyone is able to spot the issue, happy to have some assistance here. ads-driver-multi-item-write-error.pcapng.zip

chrisdutz avatar Apr 12 '24 15:04 chrisdutz

The issue is that the IndexOffset is being set to the amount of bytes instead of tags, and the size of the tag types points to the data type table entry length instead of the data type size from said entry.

IsmoLeszczynski avatar Apr 12 '24 23:04 IsmoLeszczynski

Issue was resolved by Ismo's PR.

chrisdutz avatar May 17 '24 12:05 chrisdutz