apache / plc4x

PLC4X The Industrial IoT adapter

Home Page:https://plc4x.apache.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request]: Implement `PlcConnection.ping()`

takraj opened this issue · comments

What would you like to happen?

Currently the ping() method only seems to be implemented in plc4j-driver-s7. In all other drivers it throws an exception, when called.

Please implement it for all drivers, where this is technically possible, so the user application could rely on this standard interface to test if a connection is broken, or it could use it for keeping a connection alive without actually doing real traffic.

Programming Languages

  • plc4j
  • plc4go
  • plc4c
  • plc4net

Protocols

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

I guess for most drivers it should be quite simple ... however it probably should be a call that comes at as little as much costs ... do you happen to know for some of the protocols which requests could act as such low-cost requests?

@chrisdutz Unfortunately I'm not familiar with these protocols. The sole reason of adding my contributions is that, I'm working at a company who has this library integrated in one of their solutions, and there were issues at a customer that I had to troubleshoot.

I have started adding ping implementations to some of the PLC4J drivers ... please have a look.

So far the following drivers should be supporting the PING operation:

  • ADS
  • KNXNet/IP
  • Modbus(TCP/RTU/ASCII)
  • S7
  • Simulated

Hi,
I have tried the ping with Modbus TCP using 0.12.0-SNAPSHOT, but I receive null as a response. See the code below:

      CompletableFuture<? extends PlcPingResponse> future = plcConnection.ping();
      future.whenComplete((response, throwable) -> {
          try {
              System.out.println("Response " + response);
          } catch (Exception e) {
              System.out.println("Throwable " + throwable);
            e.printStackTrace();
          }
      });

I was using a request, that the Modbus spec indicated as being mandatory, however have I seen that there are almost no Modbus devices that actually support it.

But the good thing is ... all of them respond with the same valid Error of "Illegal Function" or whatever ... so you can actually use it to ping if a device is responsive, however there is no always valid register, coil or whatsoever. So are you getting errors from the ping request, or are you getting OK status back?

In "throwable" I receive java.util.concurrent.TimeoutException

Ok ... that's odd ... cause I thought the devices would simply return an error ... could you please send me a wireshark recording of this?

Perhaps we should switch to simply reading the holding-register:1 as I would assume that this should be implemented in any device.

This is the Wireshark summary. The request is sent, but I receive no response

Modbus/TCP	65	   Query: Trans:     1; Unit: 255, Func:  43/  1: Read Device Identification

Modbus/TCP
    Transaction Identifier: 1
    Protocol Identifier: 0
    Length: 5
    Unit Identifier: 255
Modbus
    .010 1011 = Function Code: Encapsulated Interface Transport (43)
    MEI type: Read Device Identification (14)
    Read Device ID: Basic Device Identification (1)
    Object ID: VendorName (0)

I was previously using EasyModbus library and I have implemented the ping manually in the way that you have described - reading holding register 1.

Could you please attach the pgap or pcapng file here?
You sent the request ... I'm more interested in the response (Or was there no response at all? ... in that case, don't worry)

There was no response, sorry

Well that's important information ... let me quickly change the ping operations to reading the holding-register:1

Ok ... I just pushed a change, that might help resolve this issue :-)

So I've added a "pingAddress" which defaults to 0x40001 (Holding Register 1). It will use this to do the ping operation. If the default causes problems with your modbus device, you can simply override it in the connection string by providing a "ping-address={someotheraddress}" option.

Have you updated the SNAPSHOT version or how can I test this feature as simple as possible?

I can confirm that now it works! Thank you!

YAY! ... so time to close this ... will probably be released in a few days ;-)