plc4x icon indicating copy to clipboard operation
plc4x copied to clipboard

[Bug]: some asymmetry in tag-handling

Open DvonHolten opened this issue 1 month ago • 6 comments

What happened?

when you add parameters to a S7 request, you have two ways to do it:

  • builder.addTagAddress( "name", "%DB69:68:STRING(20)" )
  • builder.addTag( "name", S7Tag.of("%DB69:68:STRING(20)" )

however, in the second form we get an error, because the S7Tag.of() notation does not recognize the string-length parameter. It may be good enough when reading a string from PLC, but will make a mess when writing. Looking into S7Tag.of() and addTagAddress() shows, that S7Tag.of() does not use the regexes which could handle the added "(20)" length parameter. addTagAddress() uses these regexes and can deal with this addresses.

Version

V0.13.1

Programming Languages

  • [ ] plc4c
  • [ ] plc4go
  • [x] plc4j
  • [ ] plc4net
  • [ ] plc4py

Protocols

  • [ ] AB-Ethernet
  • [ ] ADS /AMS
  • [ ] BACnet/IP
  • [ ] C-Bus
  • [ ] CANopen
  • [ ] EtherNet/IP
  • [ ] Firmata
  • [ ] IEC-69870
  • [ ] KNXnet/IP
  • [ ] Modbus
  • [ ] OPC-UA
  • [ ] Profinet
  • [ ] S7
  • [x] S7-light

DvonHolten avatar Dec 09 '25 18:12 DvonHolten

Actually using s7tag.of uses internal classes of the s7 driver. Plc4x was designed to only use the types of the plc4x-api module.

chrisdutz avatar Dec 09 '25 20:12 chrisdutz

well - it's good to have some kind of 'clean API', but that doesn't explain/excuse why S7Tag.of() misses the String-length arguments. S7Tag is convenient to use - it is an immutable object holding the meta-data of some object in the S7 PLC. Can be used for reading and writing. There is no need to parse it from address-string in every cycle.

DvonHolten avatar Dec 10 '25 10:12 DvonHolten

Hi Dvon,

well if you're creating a new ReadRequest for every cycle, you're using the API not as we designed it. Intentionally you can execute a ReadRequest multiple times and will always get back a new Future.

So the general design-pattern we would reccomend, would be to use the addTagAddress to build the request (the addTag is intended for being used, if you got tags via the Browse API. and to re-use the request.

Chris

chrisdutz avatar Dec 12 '25 10:12 chrisdutz

Thank - that is interesting and important information. So, the best use it to prepare the required set of S7Tags from the S7 addresses, have them handy when the connection goes live to create the necessary reuseable request-objects and then use those to manage data traffic in and out the S7. The request-objects are created from a connection-object. Does the connection have to be alive for that? do the request objectes have to be re-build when the connection goes offline and returns online?

DvonHolten avatar Dec 12 '25 11:12 DvonHolten

Well you need a live connection first, but can re use them. Right now the request is tied with the connection object that created it. This was something I recently discovered recently and we started discussing here. Expect the request to get the connection passed in on execution in the future.

But I just wanted to make sure you also know the connection cache? Connecting in s7 requires a handshake, which executing on every read is quite expensive. Reusing and sharing a connection among the application is a best practice.

chrisdutz avatar Dec 12 '25 11:12 chrisdutz

Well you need a live connection first, but can re use them. Right now the request is tied with the connection object that created it. This was something I recently discovered recently and we started discussing here. Expect the request to get the connection passed in on execution in the future.

But I just wanted to make sure you also know the connection cache? Connecting in s7 requires a handshake, which executing on every read is quite expensive. Reusing and sharing a connection among the application is a best practice.

chrisdutz avatar Dec 12 '25 11:12 chrisdutz