digitalpetri / ethernet-ip

Asynchronous, non-blocking, EtherNet/IP client implementation for Java
Apache License 2.0
145 stars 50 forks source link

Can not read attribute. #78

Closed AntonLiashenka closed 1 week ago

AntonLiashenka commented 1 week ago

Hello,

I'm trying to read an attribute readvalue (Param2) from scales controller. Here is EDS file:

$ EZ-EDS Version 3.25.1.20181218 Generated Electronic Data Sheet

[File]
        DescText = "EDS for ST550TE";
        CreateDate = 05-19-2015;
        CreateTime = 14:36:02;
        ModDate = 05-22-2015;
        ModTime = 14:29:07;
        Revision = 1.6;
        HomeURL = "www.linwt.com";

[Device]
        VendCode = 283;
        VendName = "Hilscher GmbH";
        ProdType = 12;
        ProdTypeStr = "Communications Adapter";
        ProdCode = 17;
        MajRev = 2;
        MinRev = 2;
        ProdName = "Scale Terminal";
        Catalog = "ST550TE EtherNet/IP";

[Device Classification]
        Class1 = EtherNetIP;

[Params]
        Param1 =
                0,                      $ reserved, shall equal 0
                6,"20 0F 24 01 30 01",  $ Link Path Size, Link Path
                0x0010,                 $ Descriptor
                0xC3,                   $ Data Type
                2,                      $ Data Size in bytes
                "status1",              $ name
                "",                     $ units
                "status1",              $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param2 =
                0,                      $ reserved, shall equal 0
                6,"20 0F 24 02 30 01",  $ Link Path Size, Link Path
                0x0010,                 $ Descriptor
                0xCA,                   $ Data Type
                4,                      $ Data Size in bytes
                "readvalue",            $ name
                "",                     $ units
                "readvalue",            $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param3 =
                0,                      $ reserved, shall equal 0
                6,"20 0F 24 03 30 01",  $ Link Path Size, Link Path
                0x0010,                 $ Descriptor
                0xC3,                   $ Data Type
                2,                      $ Data Size in bytes
                "status2",              $ name
                "",                     $ units
                "status2",              $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param4 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xD4,                   $ Data Type
                8,                      $ Data Size in bytes
                "inReserved1",          $ name
                "",                     $ units
                "inReserved1",          $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param5 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xD4,                   $ Data Type
                8,                      $ Data Size in bytes
                "inReserved2",          $ name
                "",                     $ units
                "inReserved2",          $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param6 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xD4,                   $ Data Type
                8,                      $ Data Size in bytes
                "inReserved3",          $ name
                "",                     $ units
                "inReserved4",          $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param7 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xD4,                   $ Data Type
                8,                      $ Data Size in bytes
                "inReserved4",          $ name
                "",                     $ units
                "inReserved4",          $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param8 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xC3,                   $ Data Type
                2,                      $ Data Size in bytes
                "UserReserved",         $ name
                "",                     $ units
                "UserReserved",         $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param9 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xC3,                   $ Data Type
                2,                      $ Data Size in bytes
                "cmd",                  $ name
                "",                     $ units
                "cmd",                  $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param10 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xCA,                   $ Data Type
                4,                      $ Data Size in bytes
                "writevalue",           $ name
                "",                     $ units
                "writevalue",           $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param11 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xD4,                   $ Data Type
                8,                      $ Data Size in bytes
                "outReserved1",         $ name
                "",                     $ units
                "outReserved1",         $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param12 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xD4,                   $ Data Type
                8,                      $ Data Size in bytes
                "outReserved2",         $ name
                "",                     $ units
                "outReserved2",         $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param13 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xD4,                   $ Data Type
                8,                      $ Data Size in bytes
                "outReserved3",         $ name
                "",                     $ units
                "outReserved3",         $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places
        Param14 =
                0,                      $ reserved, shall equal 0
                ,,                      $ Link Path Size, Link Path
                0x0000,                 $ Descriptor
                0xD4,                   $ Data Type
                8,                      $ Data Size in bytes
                "outReserved4",         $ name
                "",                     $ units
                "outReserved4",         $ help string
                ,,0,                    $ min, max, default data values
                ,,,,                    $ mult, div, base, offset scaling
                ,,,,                    $ mult, div, base, offset links
                ;                       $ decimal places

[Assembly]
        Object_Name = "Assembly Object";
        Object_Class_Code = 0x04;
        Assem100 =
                "InputData",
                "20 04 24 64 30 03",
                ,
                0x0020,
                ,,
                16,Param8,
                16,Param9,
                32,Param10,
                64,Param11,
                64,Param12,
                64,Param13,
                64,Param14;
        Assem150 =
                "OutputData",
                "20 04 24 96 30 03",
                ,
                0x0020,
                ,,
                16,Param1,
                32,Param2,
                16,Param3,
                64,Param4,
                64,Param5,
                64,Param6,
                64,Param7;

[Connection Manager]
        Object_Name = "Connection Manager Object";
        Object_Class_Code = 0x06;
        Connection1 =
                0x04030002,             $ 0-15    = supported transport classes
                                        $ 16      = trigger: cyclic
                                        $ 17      = trigger: change of state
                                        $ 18      = trigger: application
                                        $ 19-23   = trigger: reserved
                                        $ 24      = application type: listen-only
                                        $ 25      = application type: input-only
                                        $ 26      = application type: exclusive-owner
                                        $ 27      = application type: redundant-owner
                                        $ 28-30   = reserved
                                        $ 31      = Direction: Client = 0 / Server = 1
                0x44640005,             $ 0       = O->T fixed size supported
                                        $ 1       = O->T variable size supported
                                        $ 2       = T->O fixed size supported
                                        $ 3       = T->O variable size supported
                                        $ 4-5     = O->T number of bytes per slot (obsolete)
                                        $ 6-7     = T->O number of bytes per slot (obsolete)
                                        $ 8-10    = O->T Real time transfer format
                                        $ 11      = reserved
                                        $ 12-14   = T->O Real time transfer format
                                        $ 15      = reserved
                                        $ 16      = O->T connection type: NULL
                                        $ 17      = O->T connection type: MULTICAST
                                        $ 18      = O->T connection type: POINT2POINT
                                        $ 19      = O->T connection type: reserved
                                        $ 20      = T->O connection type: NULL
                                        $ 21      = T->O connection type: MULTICAST
                                        $ 22      = T->O connection type: POINT2POINT
                                        $ 23      = T->O connection type: reserved
                                        $ 24      = O->T priority: LOW
                                        $ 25      = O->T priority: HIGH
                                        $ 26      = O->T priority: SCHEDULED
                                        $ 27      = O->T priority: reserved
                                        $ 28      = T->O priority: LOW
                                        $ 29      = T->O priority: HIGH
                                        $ 30      = T->O priority: SCHEDULED
                                        $ 31      = T->O priority: reserved
                ,,Assem100,             $ O->T RPI, size, format
                ,,Assem150,             $ T->O RPI, size, format
                ,,                      $ proxy config size, format
                ,,                      $ target config size, format
                "IOConnection",         $ Connection Name
                "",                     $ help string
                "20 04 24 C6 2C 96 2C 64";    $ Path

[Port]
        Object_Name = "Port Object";
        Object_Class_Code = 0xF4;
        Port1 =
                TCP,
                "EthernetIP Port",
                "20 F5 24 01",
                2,
                0,
                ;

My code:

EtherNetIpClientConfig config = EtherNetIpClientConfig.builder("172.18.1.40")
                .setSerialNumber(0x00)
                .setVendorId(0x00)
                .setTimeout(Duration.ofSeconds(2))
                .build();

            PaddedEPath connectionPath = new PaddedEPath(
                new PortSegment(1, new byte[]{(byte) 0}));

            CipClient client = new CipClient(config, connectionPath);

            client.connect().get();

            CipConnectionPool pool = new CipConnectionPool(2, client, connectionPath, 500);

            PaddedEPath requestPath = new PaddedEPath(
                new LogicalSegment.ClassId(0x0F),
                new LogicalSegment.InstanceId(0x02),
                new LogicalSegment.AttributeId(0x30)
            );

            ReadTagService service = new ReadTagService(requestPath);

            pool.acquire().whenComplete((connection, ex) -> {
                if (connection != null) {
                    CompletableFuture<ByteBuf> f = client.invokeConnected(connection.getO2tConnectionId(), service);

                    f.whenComplete((data, ex2) -> {
                        if (data != null) {
                            System.out.println("Tag data: " + ByteBufUtil.hexDump(data));
                        } else {
                            ex2.printStackTrace();
                        }
                        pool.release(connection);
                    });
                } else {
                    ex.printStackTrace();
                }
            });

I'm getting error in the response:

com.digitalpetri.enip.cip.CipResponseException: status=0x05 [path destination unknown] , additional=[]
    at com.digitalpetri.enip.logix.services.ReadTagService.decodeResponse(ReadTagService.java:63)
    at com.digitalpetri.enip.logix.services.ReadTagService.decodeResponse(ReadTagService.java:13)
    at com.digitalpetri.enip.cip.CipClient.lambda$invokeConnected$0(CipClient.java:71)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
    at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
    at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
    at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
    at com.digitalpetri.enip.cip.CipClient$ConnectedDataHandler.itemsReceived(CipClient.java:270)
    at com.digitalpetri.enip.cip.CipClient.onUnitDataReceived(CipClient.java:239)
    at com.digitalpetri.enip.EtherNetIpClient.onChannelRead(EtherNetIpClient.java:196)
    at com.digitalpetri.enip.EtherNetIpClient.access$900(EtherNetIpClient.java:50)
    at com.digitalpetri.enip.EtherNetIpClient$EtherNetIpClientHandler.lambda$channelRead0$0(EtherNetIpClient.java:346)

I'm not sure if the code I wrote is correct. Could you please advice how to read this attribute?

kevinherron commented 1 week ago

This isn't a Logix tag, you aren't going to be reading it with the ReadTagService or any other services from the logix sub-module.

You probably need to use the standard CIP GetAttributeSingle service to read assemble instance number 150 or something like that. It looks like that will give you all of the output data.

AntonLiashenka commented 1 week ago

@kevinherron thank you for reply! are you able to give me code sample how to read this attribute readvalue using GetAttributeSingle service ? I'm not sure how to build PaddedEPath param.

Thank you!

kevinherron commented 1 week ago

Try creating a PaddedEPath of these components:

20 0F - ClassId 0x0F
24 02 - InstanceId 0x02
30 01 - AttributeId 0x01