You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Api Change - Chris Copy

General

  • I ensured all of our classes have the "Plc" prefix, as I did encounter situations in which very generic type names had collisions and I had to use the fully qualified class name (including the package name). The "Plc" prefix reduces this risk.
  • This model is now simplified as it currently doesn't support reading of multi-values. There are multiple options to add Multi-Values, but I haven't decided on which option I like best:
    • Rename PlcRequest/ResponseItem to PlcSingleValueRequest/ResponseItem and add a Multi-Value counterpart, wich handles the multi-value.
    • Add a PlcMultiValueRequest/ResponseItem, which simply references multiple PlcRequest/ResponseItem objects and provides a "get(index)" method.
    • Add a getNumValues() (Not insisting on this name) method and give each of the accessors an "index" property (eventually additionally a no-args version which defaults to index 0) (I think I prefer this one but didn't want to blow up the class-diagram too much).

PlcField (Aka Address)

  • I Renamed Address to PlcField
  • I still think there is no immediate need to define any fields or methods in this interface as I haven't seen any common ground yet. Even if we are currently adding "TYPE" information to most fields, in Modbus the type is directly tied to the address you are reading. So If you are reading a "Register" or a "Coil", the datatype is fixed.

PlcConnection

  • I removed the "getLister" method as I haven't seen any protocol or use-case where this actually made sense.

  • I changed the "parseAddress" to "prepareField" as it sort of correlates to the "prepareStatement" of JDBC ... and some times I could imagine, that more work is involved than simple parsing of a string (For Beckhoff ADS and EtherNet/IP this method could actively connect to the corresponding resource so in future read operations only the connection-id has to be provided)

PlcRequest & PlcResponse

  • I changed the List for referencing the items with a Map, so we can directly reference items.
  • I removed the "single-item" convenience methods.
  • I added getItem(name) methods for directly referencing a given item.

PlcRequestItem & PlcResponseItem

  • I removed the datatype both from the properties as well as the generic type as I think type information - if needed - should be inside the query object.
  • A request item now has a name, which allows to access it via it's name.
  • PlcReadRequestItem no longer has a "size", as that's part of the query now. Some protocols ... such as Modbus (I think) ... don't support this concept.
  • NOTE: I would suggest to not remove PlcReadRequestItem or PlcWriteResponseItem class entirely, even if we could simply make PlcRequestItem and PlcResponseItem non-abstract. For simplicity of the API I would opt for keeping it ... so we always have matching pairs of PlcXYZRequestItem and PlcXYZResponseItems.

Example Code

Here comes some example code to demonstrate how a Programm using this API could look like.

    public static void main(String[] args) throws Exception {
        PlcDriverManager manager = new PlcDriverManager();
        try (PlcConnection conn = manager.getConnection("s7://192.168.167.211/0/0")) {
            Optional<PlcReader> optionalReader = conn.getReader();
            if (!optionalReader.isPresent()) {
                return;
            }

            PlcReader Reader = optionalReader.get();

			PlcReadRequest request = new PlcReadRequest(
				new PlcReadRequestItem("parameterX", conn.prepareQuery("%DB8.DBX3:INT")),
				new PlcReadRequestItem("parameterY", conn.prepareQuery("%DB9.DBW4:DOUBLE")),
				new PlcReadRequestItem("others", conn.prepareQuery("%DB2.DBW2:BYTE[10]")));

            CompletableFuture<PlcReadResponse> future = reader.read(request);

            PlcReadResponse response = future.get();


			// Access an item by it's name.
            System.out.println("Parameter X: " + response.getInteger("parameterX"));


			// Iterate over all items
			for(PlcReadResponseItem item: response.getItems()) {
				// Conditionally handle an item by it's name.
				if("parameterY".equals(item.getName()) {
					// If using getInteger without an index, the index 0 is used.
					System.out.println("Parameter y: " + item.getDouble());
				}
				else if("others".equals(item.getName()) {
					System.out.println("Others:");
					// Handle multi-value items.
					for(int i = 0; i < item.getNumValues(); i++) {
						// Intentionally using short instead of byte 
						// In this case it will return Byte[i] but convert that into a Short.
						System.out.println(" - " + item.getShort(i));
					}
				}
			}
        }
    }




  • No labels