You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2017/12/28 12:07:57 UTC

[incubator-plc4x] branch refactoring/java_generify created (now d4fdb5b)

This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a change to branch refactoring/java_generify
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git.


      at d4fdb5b  Java-Gernerify APIs

This branch includes the following new commits:

     new d4fdb5b  Java-Gernerify APIs

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@plc4x.apache.org" <co...@plc4x.apache.org>'].

[incubator-plc4x] 01/01: Java-Gernerify APIs

Posted by sr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch refactoring/java_generify
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit d4fdb5b3e21cf458546b0aa423b3c46531cbaa0a
Author: Sebastian Rühl <se...@codecentric.de>
AuthorDate: Fri Dec 22 13:13:52 2017 +0100

    Java-Gernerify APIs
---
 .../apache/plc4x/edgent/PlcConnectionAdapter.java  |  265 +++--
 .../plc4x/edgent/PlcConnectionAdapterTest.java     | 1019 ++++++++++----------
 .../apache/plc4x/edgent/mock/MockConnection.java   |  113 +--
 .../plc4x/java/api/connection/PlcReader.java       |    4 +-
 .../plc4x/java/api/connection/PlcWriter.java       |    3 +-
 .../plc4x/java/api/messages/PlcReadRequest.java    |   18 +-
 .../plc4x/java/api/messages/PlcReadResponse.java   |    8 +-
 .../plc4x/java/api/messages/PlcWriteRequest.java   |   18 +-
 .../plc4x/java/api/messages/PlcWriteResponse.java  |   12 +-
 .../java/api/messages/items/ReadRequestItem.java   |   10 +-
 .../java/api/messages/items/ReadResponseItem.java  |   10 +-
 .../java/api/messages/items/WriteRequestItem.java  |   20 +-
 .../java/api/messages/items/WriteResponseItem.java |    8 +-
 .../plc4x/java/s7/netty/Plc4XS7Protocol.java       |   66 +-
 .../apache/plc4x/java/s7/S7PlcReaderSample.java    |    8 +-
 .../org/apache/plc4x/java/s7/S7PlcScanner.java     |   14 +-
 .../org/apache/plc4x/java/s7/S7PlcTestConsole.java |   10 +-
 .../apache/plc4x/java/s7/S7PlcWriterSample.java    |    9 +-
 18 files changed, 822 insertions(+), 793 deletions(-)

diff --git a/integrations/apache-edgent/src/main/java/org/apache/plc4x/edgent/PlcConnectionAdapter.java b/integrations/apache-edgent/src/main/java/org/apache/plc4x/edgent/PlcConnectionAdapter.java
index be4e56c..1a91c26 100644
--- a/integrations/apache-edgent/src/main/java/org/apache/plc4x/edgent/PlcConnectionAdapter.java
+++ b/integrations/apache-edgent/src/main/java/org/apache/plc4x/edgent/PlcConnectionAdapter.java
@@ -18,8 +18,7 @@ under the License.
 */
 package org.apache.plc4x.edgent;
 
-import java.util.Calendar;
-
+import com.google.gson.JsonObject;
 import org.apache.edgent.function.Consumer;
 import org.apache.edgent.function.Function;
 import org.apache.edgent.function.Supplier;
@@ -28,18 +27,19 @@ import org.apache.plc4x.java.api.connection.PlcConnection;
 import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.connection.PlcWriter;
 import org.apache.plc4x.java.api.exceptions.PlcException;
-import org.apache.plc4x.java.api.messages.*;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.model.Address;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.gson.JsonObject;
+import java.util.Calendar;
 
 /**
  * PlcConnectionAdapter encapsulates a plc4x {@link PlcConnection}.
  * <p>
  * The idea here is to use PlcConnectionAdapter to enable our Edgent Supplier/Consumer
- * instances to be isolated from the details of / variability of 
+ * instances to be isolated from the details of / variability of
  * PlcConnection mgmt and such.
  * <p>
  * A PlcConnectionAdapter is subject to the constraints of the underlying
@@ -53,17 +53,17 @@ import com.google.gson.JsonObject;
  * support for multiple connections from a single client.
  * <p>
  * A single PlcConnectionAdapter can be used by multiple threads concurrently
- * (e.g., used by multiple PlcFunctions Consumers for {@code Topology.poll()} and/or 
- * multiple Suppliers for {@code TStream.sink()}). 
- * 
+ * (e.g., used by multiple PlcFunctions Consumers for {@code Topology.poll()} and/or
+ * multiple Suppliers for {@code TStream.sink()}).
+ *
  * @see PlcFunctions
  */
-public class PlcConnectionAdapter implements AutoCloseable{
+public class PlcConnectionAdapter implements AutoCloseable {
 
-  private final static Logger logger = LoggerFactory.getLogger(PlcConnectionAdapter.class);
-  
-  private String plcConnectionUrl;
-  private PlcConnection plcConnection;
+    private final static Logger logger = LoggerFactory.getLogger(PlcConnectionAdapter.class);
+
+    private String plcConnectionUrl;
+    private PlcConnection plcConnection;
   
   /*
    * NOTES:
@@ -71,130 +71,127 @@ public class PlcConnectionAdapter implements AutoCloseable{
    *   of read or write errors, my thinking is to enhance the PlcConnectionAdapter
    *   to enable the app to register an error callback handler or such.
    */
-  
-  public PlcConnectionAdapter(PlcConnection plcConnection) {
-    this.plcConnection = plcConnection;
-  }
-  
-  public PlcConnectionAdapter(String plcConnectionUrl) {
-    this.plcConnectionUrl = plcConnectionUrl;
-  }
-  
-  PlcConnection getConnection() throws PlcException {
-    synchronized(this) {
-      if (plcConnection == null) {
-        plcConnection = new PlcDriverManager().getConnection(plcConnectionUrl);
-      }
-      return plcConnection;
+
+    public PlcConnectionAdapter(PlcConnection plcConnection) {
+        this.plcConnection = plcConnection;
     }
-  }
-
-  @Override
-  public void close() throws Exception {
-    // only close a connection this instance created/connected
-    if (plcConnectionUrl != null) {
-      if (plcConnection != null)
-        plcConnection.close();
+
+    public PlcConnectionAdapter(String plcConnectionUrl) {
+        this.plcConnectionUrl = plcConnectionUrl;
     }
-  }
-
-  <T> Supplier<T> newSupplier(Class<T> datatype, String addressStr) {
-    PlcConnectionAdapter.checkDatatype(datatype);
-    return new Supplier<T>() {
-      private static final long serialVersionUID = 1L;
-
-      @Override
-      public T get() {
-        PlcConnection connection = null;
-        Address address = null;
-        try {
-          connection = getConnection();
-          address = connection.parseAddress(addressStr);
-          PlcReader reader = connection.getReader().get();
-          PlcReadRequest readRequest = PlcConnectionAdapter.newPlcReadRequest(datatype, address);
-          T value = (T) reader.read(readRequest).get().getResponseItems().get(0).getValues().get(0);
-          return value;
-        }
-        catch (Exception e) {
-          logger.error("reading from plc device {} {} failed", connection, address, e);
-          return null;
-        }
-      }
-      
-    };
-  }
-
-  <T> Consumer<T> newConsumer(Class<T> datatype, String addressStr) {
-    PlcConnectionAdapter.checkDatatype(datatype);
-    return new Consumer<T>() {
-      private static final long serialVersionUID = 1L;
-
-      @Override
-      public void accept(T arg0) {
-        PlcConnection connection = null;
-        Address address = null;
-        try {
-          connection = getConnection();
-          address = connection.parseAddress(addressStr);
-          PlcWriter writer = connection.getWriter().get();
-          PlcWriteRequest writeReq = PlcConnectionAdapter.newPlcWriteRequest(address, arg0);
-          writer.write(writeReq).get();
-        }
-        catch (Exception e) {
-          logger.error("writing to plc device {} {} failed", connection, address, e);
-        }
-      }
-      
-    };
-  }
-  
-  <T> Consumer<JsonObject> newConsumer(Class<T> datatype, Function<JsonObject,String> addressFn, Function<JsonObject,T> valueFn) {
-    PlcConnectionAdapter.checkDatatype(datatype);
-    return new Consumer<JsonObject>() {
-      private static final long serialVersionUID = 1L;
-
-      @Override
-      public void accept(JsonObject jo) {
-        PlcConnection connection = null;
-        Address address = null;
-        try {
-          connection = getConnection();
-          String addressStr = addressFn.apply(jo);
-          address = connection.parseAddress(addressStr);
-          T value = valueFn.apply(jo);
-          PlcWriter writer = connection.getWriter().get();
-          PlcWriteRequest writeReq = newPlcWriteRequest(address, value);
-          writer.write(writeReq).get();
+
+    PlcConnection getConnection() throws PlcException {
+        synchronized (this) {
+            if (plcConnection == null) {
+                plcConnection = new PlcDriverManager().getConnection(plcConnectionUrl);
+            }
+            return plcConnection;
         }
-        catch (Exception e) {
-          logger.error("writing to plc device {} {} failed", connection, address, e);
+    }
+
+    @Override
+    public void close() throws Exception {
+        // only close a connection this instance created/connected
+        if (plcConnectionUrl != null) {
+            if (plcConnection != null)
+                plcConnection.close();
         }
-      }
-      
-    };
-  }
-
-  static void checkDatatype(Class<?> cls) {
-    if (cls == Boolean.class
-        || cls == Byte.class
-        || cls == Short.class
-        || cls == Integer.class
-        || cls == Float.class
-        || cls == String.class
-        || cls == Calendar.class)
-      return;
-    throw new IllegalArgumentException("Not a legal plc data type: "+cls.getSimpleName());
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> PlcWriteRequest newPlcWriteRequest(Address address, T value) {
-    Class<?> cls = value.getClass();
-    return new PlcWriteRequest(cls, address, value);
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> PlcReadRequest newPlcReadRequest(Class<T> datatype, Address address) {
-      return new PlcReadRequest(datatype, address);
-  }
+    }
+
+    <T> Supplier<T> newSupplier(Class<T> datatype, String addressStr) {
+        PlcConnectionAdapter.checkDatatype(datatype);
+        return new Supplier<T>() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public T get() {
+                PlcConnection connection = null;
+                Address address = null;
+                try {
+                    connection = getConnection();
+                    address = connection.parseAddress(addressStr);
+                    PlcReader reader = connection.getReader().get();
+                    PlcReadRequest<T> readRequest = PlcConnectionAdapter.newPlcReadRequest(datatype, address);
+                    T value = (T) reader.read(readRequest).get().getResponseItems().get(0).getValues().get(0);
+                    return value;
+                } catch (Exception e) {
+                    logger.error("reading from plc device {} {} failed", connection, address, e);
+                    return null;
+                }
+            }
+
+        };
+    }
+
+    <T> Consumer<T> newConsumer(Class<T> datatype, String addressStr) {
+        PlcConnectionAdapter.checkDatatype(datatype);
+        return new Consumer<T>() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public void accept(T arg0) {
+                PlcConnection connection = null;
+                Address address = null;
+                try {
+                    connection = getConnection();
+                    address = connection.parseAddress(addressStr);
+                    PlcWriter writer = connection.getWriter().get();
+                    PlcWriteRequest writeReq = PlcConnectionAdapter.newPlcWriteRequest(address, arg0);
+                    writer.write(writeReq).get();
+                } catch (Exception e) {
+                    logger.error("writing to plc device {} {} failed", connection, address, e);
+                }
+            }
+
+        };
+    }
+
+    <T> Consumer<JsonObject> newConsumer(Class<T> datatype, Function<JsonObject, String> addressFn, Function<JsonObject, T> valueFn) {
+        PlcConnectionAdapter.checkDatatype(datatype);
+        return new Consumer<JsonObject>() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public void accept(JsonObject jo) {
+                PlcConnection connection = null;
+                Address address = null;
+                try {
+                    connection = getConnection();
+                    String addressStr = addressFn.apply(jo);
+                    address = connection.parseAddress(addressStr);
+                    T value = valueFn.apply(jo);
+                    PlcWriter writer = connection.getWriter().get();
+                    PlcWriteRequest writeReq = newPlcWriteRequest(address, value);
+                    writer.write(writeReq).get();
+                } catch (Exception e) {
+                    logger.error("writing to plc device {} {} failed", connection, address, e);
+                }
+            }
+
+        };
+    }
+
+    static void checkDatatype(Class<?> cls) {
+        if (cls == Boolean.class
+            || cls == Byte.class
+            || cls == Short.class
+            || cls == Integer.class
+            || cls == Float.class
+            || cls == String.class
+            || cls == Calendar.class)
+            return;
+        throw new IllegalArgumentException("Not a legal plc data type: " + cls.getSimpleName());
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> PlcWriteRequest<T> newPlcWriteRequest(Address address, T value) {
+        Class<T> cls = (Class<T>) value.getClass();
+        return new PlcWriteRequest<>(cls, address, value);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> PlcReadRequest<T> newPlcReadRequest(Class<T> datatype, Address address) {
+        return new PlcReadRequest<>(datatype, address);
+    }
 
 }
diff --git a/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/PlcConnectionAdapterTest.java b/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/PlcConnectionAdapterTest.java
index 88cec7d..36e4d1c 100644
--- a/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/PlcConnectionAdapterTest.java
+++ b/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/PlcConnectionAdapterTest.java
@@ -18,11 +18,7 @@ under the License.
 */
 package org.apache.plc4x.edgent;
 
-import java.lang.reflect.Array;
-import java.util.Calendar;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
+import com.google.gson.JsonObject;
 import org.apache.edgent.function.Consumer;
 import org.apache.edgent.function.Function;
 import org.apache.edgent.function.Supplier;
@@ -30,7 +26,10 @@ import org.apache.plc4x.edgent.mock.MockAddress;
 import org.apache.plc4x.edgent.mock.MockConnection;
 import org.apache.plc4x.java.PlcDriverManager;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-import org.apache.plc4x.java.api.messages.*;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteResponse;
 import org.apache.plc4x.java.api.messages.items.ReadRequestItem;
 import org.apache.plc4x.java.api.messages.items.WriteRequestItem;
 import org.apache.plc4x.java.api.model.Address;
@@ -38,507 +37,525 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
-import com.google.gson.JsonObject;
+import java.lang.reflect.Array;
+import java.util.Calendar;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
 
 public class PlcConnectionAdapterTest {
-  
-  // TODO figure out how to get these run via Eclipse (org.junit.jupiter.api?) and remove this
-  // Ah... Junit 5... needs newer Eclipse (newer than neon 1.a)
-  public static void main(String[] args) throws Exception {
-    PlcConnectionAdapterTest t = new PlcConnectionAdapterTest();
-    t.testCtor1();
-    t.testCtor2();
-    t.testCheckDatatype();
-    t.testNewPlcReadRequest();
-    t.testNewPlcWriteRequest();
-    t.testNewSupplier();
-    t.testNewSupplierNeg();
-    t.testNewConsumer1();
-    t.testNewConsumer1Neg();
-    t.testNewConsumer2();
-    t.testNewConsumer2Neg();
-    System.out.println("SUCCESS");
-  }
-  
-  protected MockConnection getMockConnection() throws PlcConnectionException {
-    return (MockConnection) new PlcDriverManager().getConnection("mock://some-cool-url");
-  }
-  
-  /*
-   * Test the PlcConnectionAdapter(PlcConnection) ctor, getConnection() and close()
-   */
-  @Test
-  @Tag("fast")
-  public void testCtor1() throws Exception {
-    MockConnection mockConnection = getMockConnection();
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(mockConnection);
-    Assertions.assertSame(mockConnection, adapter.getConnection());
-    // and again... multiple adapter.getConnection() returns the same
-    Assertions.assertSame(mockConnection, adapter.getConnection());
-    adapter.close();
-  }
-  
-  /*
-   * Test the PlcConnectionAdapter(url) ctor, getConnection() and close()
-   */
-  @Test
-  @Tag("fast")
-  public void testCtor2() throws Exception {
-    MockConnection mockConnection = getMockConnection();
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(mockConnection.getUrl());
-    MockConnection mockConnection2 = (MockConnection) adapter.getConnection();
-    Assertions.assertNotSame(mockConnection, mockConnection2);
-    Assertions.assertSame(mockConnection.getUrl(), mockConnection2.getUrl());
-    // and again... multiple adapter.getConnection() returns the same
-    Assertions.assertSame(mockConnection2, adapter.getConnection());
-    adapter.close();
-  }
- 
-  @Test
-  @Tag("fast")
-  public void testCheckDatatype() throws Exception {
-    PlcConnectionAdapter.checkDatatype(Boolean.class);
-    PlcConnectionAdapter.checkDatatype(Byte.class);
-    PlcConnectionAdapter.checkDatatype(Short.class);
-    PlcConnectionAdapter.checkDatatype(Integer.class);
-    PlcConnectionAdapter.checkDatatype(Float.class);
-    PlcConnectionAdapter.checkDatatype(String.class);
-    PlcConnectionAdapter.checkDatatype(Calendar.class);
-    Assertions.assertThrows(IllegalArgumentException.class,
-        () -> PlcConnectionAdapter.checkDatatype(Long.class));
-    Assertions.assertThrows(IllegalArgumentException.class,
-        () -> PlcConnectionAdapter.checkDatatype(Double.class));
-  }
-  
-  private <T> void checkRead(MockConnection connection, PlcReadRequest request, T value) throws InterruptedException, ExecutionException {
-    // this is really a tests of our mock tooling but knowing it's behaving as expected
-    // will help identify problems in the adapter/supplier/consumer
-    connection.setDataValue(request.getReadRequestItems().get(0).getAddress(), value);
-    
-    CompletableFuture<PlcReadResponse> cf = connection.read(request);
-    
-    Assertions.assertTrue(cf.isDone());
-    PlcReadResponse response = cf.get();
-    Assertions.assertEquals(value, response.getResponseItems().get(0).getValues().get(0));
-  }
-  
-  private <T> void checkWrite(MockConnection connection, PlcWriteRequest request, T value) throws InterruptedException, ExecutionException {
-    // this is really a tests of our mock tooling but knowing it's behaving as expected
-    // will help identify problems in the adapter/supplier/consumer
-    connection.setDataValue(request.getRequestItems().get(0).getAddress(), value);
-    
-    CompletableFuture<PlcWriteResponse> cf = connection.write(request);
-    
-    Assertions.assertTrue(cf.isDone());
-    PlcWriteResponse response = cf.get();
-    Assertions.assertNotNull(response);
-    T writtenData = (T) connection.getDataValue(request.getRequestItems().get(0).getAddress());
-    if(writtenData.getClass().isArray()) {
-      writtenData = (T) Array.get(writtenData, 0);
+
+    // TODO figure out how to get these run via Eclipse (org.junit.jupiter.api?) and remove this
+    // Ah... Junit 5... needs newer Eclipse (newer than neon 1.a)
+    public static void main(String[] args) throws Exception {
+        PlcConnectionAdapterTest t = new PlcConnectionAdapterTest();
+        t.testCtor1();
+        t.testCtor2();
+        t.testCheckDatatype();
+        t.testNewPlcReadRequest();
+        t.testNewPlcWriteRequest();
+        t.testNewSupplier();
+        t.testNewSupplierNeg();
+        t.testNewConsumer1();
+        t.testNewConsumer1Neg();
+        t.testNewConsumer2();
+        t.testNewConsumer2Neg();
+        System.out.println("SUCCESS");
     }
-    Assertions.assertEquals(value, writtenData);
-  }
-  
-  /*
-   * Verify the adapter yields the appropriate PlcReadRequest for each type and that it works.
-   */
-  @SuppressWarnings("unchecked")
-  @Test
-  @Tag("fast")
-  public void testNewPlcReadRequest() throws Exception {
-    String addressStr = "MyReadWriteAddress/0";
-    MockAddress address = new MockAddress(addressStr);
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
-    MockConnection connection = (MockConnection) adapter.getConnection();
-
-    PlcReadRequest request;
-    
-    request = PlcConnectionAdapter.newPlcReadRequest(Boolean.class, address);
-    ReadRequestItem requestItem = request.getReadRequestItems().get(0);
-    Class dataType = requestItem.getDatatype();
-    Assertions.assertTrue(dataType == Boolean.class, "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkRead(connection, request, true);
-    checkRead(connection, request, false);
-    
-    request = PlcConnectionAdapter.newPlcReadRequest(Byte.class, address);
-    requestItem = request.getReadRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(dataType == Byte.class, "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkRead(connection, request, (byte)0x13);
-    checkRead(connection, request, (byte)0x23);
-    
-    request = PlcConnectionAdapter.newPlcReadRequest(Short.class, address);
-    requestItem = request.getReadRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(dataType == Short.class, "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkRead(connection, request, (short)13);
-    checkRead(connection, request, (short)23);
-
-    request = PlcConnectionAdapter.newPlcReadRequest(Integer.class, address);
-    requestItem = request.getReadRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(dataType == Integer.class, "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkRead(connection, request, 33);
-    checkRead(connection, request, -133);
-    
-    request = PlcConnectionAdapter.newPlcReadRequest(Float.class, address);
-    requestItem = request.getReadRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(dataType == Float.class, "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkRead(connection, request, 43.5f);
-    checkRead(connection, request, -143.5f);
-    
-    request = PlcConnectionAdapter.newPlcReadRequest(String.class, address);
-    requestItem = request.getReadRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(dataType == String.class, "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkRead(connection, request, "ReadySetGo");
-    checkRead(connection, request, "OneMoreTime");
-    
-    request = PlcConnectionAdapter.newPlcReadRequest(Calendar.class, address);
-    requestItem = request.getReadRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(dataType == Calendar.class, "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkRead(connection, request, Calendar.getInstance());
-    
-    adapter.close();
-  }
-  
-  
-  /*
-   * Verify the adapter yields the appropriate PlcWriteRequest for each type and that it works.
-   */
-  @SuppressWarnings("unchecked")
-  @Test
-  @Tag("fast")
-  public void testNewPlcWriteRequest() throws Exception {
-    String addressStr = "MyReadWriteAddress/0";
-    MockAddress address = new MockAddress(addressStr);
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
-    MockConnection connection = (MockConnection) adapter.getConnection();
-
-    PlcWriteRequest request;
-    
-    request = PlcConnectionAdapter.newPlcWriteRequest(address, true);
-    WriteRequestItem requestItem = request.getRequestItems().get(0);
-    Class dataType = requestItem.getDatatype();
-    Assertions.assertTrue(Boolean.class.isAssignableFrom(dataType), "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkWrite(connection, request, true);
-    
-    request = PlcConnectionAdapter.newPlcWriteRequest(address, (byte)0x113);
-    requestItem = request.getRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(Byte.class.isAssignableFrom(dataType), "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkWrite(connection, request, (byte)0x113);
-    
-    request = PlcConnectionAdapter.newPlcWriteRequest(address, (short)113);
-    requestItem = request.getRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(Short.class.isAssignableFrom(dataType), "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkWrite(connection, request, (short)113);
-
-    request = PlcConnectionAdapter.newPlcWriteRequest(address, 1033);
-    requestItem = request.getRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(Integer.class.isAssignableFrom(dataType), "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkWrite(connection, request, 1033);
-    
-    request = PlcConnectionAdapter.newPlcWriteRequest(address, 1043.5f);
-    requestItem = request.getRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(Float.class.isAssignableFrom(dataType), "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkWrite(connection, request, 1043.5f);
-    
-    request = PlcConnectionAdapter.newPlcWriteRequest(address, "A written value");
-    requestItem = request.getRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    Assertions.assertTrue(String.class.isAssignableFrom(dataType), "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkWrite(connection, request, "A written value");
-    
-    Calendar calValue = Calendar.getInstance();
-    request = PlcConnectionAdapter.newPlcWriteRequest(address, calValue);
-    requestItem = request.getRequestItems().get(0);
-    dataType = requestItem.getDatatype();
-    request = PlcConnectionAdapter.newPlcWriteRequest(address, calValue);
-    Assertions.assertTrue(Calendar.class.isAssignableFrom(dataType), "class:"+request.getClass());
-    Assertions.assertSame(address, requestItem.getAddress());
-    checkWrite(connection, request, calValue);
-    
-    adapter.close();
-  }
-
-  /*
-   * test PlcConnectionAdapter.newSupplier
-   */
-  @SuppressWarnings("unchecked")
-  @Test
-  @Tag("fast")
-  public void testNewSupplier() throws Exception {
-    String addressStr = "MyReadWriteAddress/0";
-    MockAddress address = new MockAddress(addressStr);
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
-    MockConnection connection = (MockConnection) adapter.getConnection();
-
-    Supplier<?> supplier;
-    
-    supplier = adapter.newSupplier(Boolean.class, addressStr);
-    Assertions.assertNotSame(supplier, adapter.newSupplier(Boolean.class, addressStr));
-    checkSupplier(connection, address, (Supplier<Boolean>)supplier, true, false);
-    
-    supplier = adapter.newSupplier(Byte.class, addressStr);
-    checkSupplier(connection, address, (Supplier<Byte>)supplier, (byte)0x1, (byte)0x2, (byte)0x3);
-    
-    supplier = adapter.newSupplier(Short.class, addressStr);
-    checkSupplier(connection, address, (Supplier<Short>)supplier, (short)1, (short)2, (short)3);
-
-    supplier = adapter.newSupplier(Integer.class, addressStr);
-    checkSupplier(connection, address, (Supplier<Integer>)supplier, 1000, 1001, 1002);
-    
-    supplier = adapter.newSupplier(Float.class, addressStr);
-    checkSupplier(connection, address, (Supplier<Float>)supplier, 1000.5f, 1001.5f, 1002.5f);
-    
-    supplier = adapter.newSupplier(String.class, addressStr);
-    checkSupplier(connection, address, (Supplier<String>)supplier, "one", "two", "three");
-    
-    adapter.close();
-  }
-  
-  /*
-   * test PlcConnectionAdapter.newSupplier with read exception
-   */
-  @SuppressWarnings("unchecked")
-  @Test
-  @Tag("fast")
-  public void testNewSupplierNeg() throws Exception {
-    String addressStr = "MyReadWriteAddress/0";
-    MockAddress address = new MockAddress(addressStr);
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
-    MockConnection connection = (MockConnection) adapter.getConnection();
-
-    Supplier<?> supplier;
-    
-    supplier = adapter.newSupplier(String.class, addressStr);
-    checkSupplier(2, connection, address, (Supplier<String>)supplier, "one", "two", "three");
-    
-    adapter.close();
-  }
-  
-  static <T> void checkSupplier(MockConnection connection, Address address, Supplier<T> supplier, Object ... values) throws Exception {
-    checkSupplier(0, connection, address, supplier, values);
-  }
-  private static <T> void checkSupplier(int readFailureCountTrigger, MockConnection connection, Address address, Supplier<T> supplier, Object ... values) throws Exception {
-    // verify that a read failure doesn't kill the consumer
-    // it logs (not verified) but returns null (as designed) and keeps working for the subsequent reads
-    connection.setReadException(readFailureCountTrigger, "This is a mock read exception");
-    int readCount = 0;
-    for (Object value : values) {
-      connection.setDataValue(address, value);
-      T readData = supplier.get();
-      // System.out.println("checkSupplier"+(readFailureCountTrigger > 0 ? "NEG" : "")+": value:"+value+" readData:"+readData);
-      if (readFailureCountTrigger <= 0)
-        Assertions.assertEquals(value, readData);
-      else {
-        if (++readCount != readFailureCountTrigger)
-          Assertions.assertEquals(value, readData);
-        else
-          Assertions.assertNull(readData);
-      }
+
+    protected MockConnection getMockConnection() throws PlcConnectionException {
+        return (MockConnection) new PlcDriverManager().getConnection("mock://some-cool-url");
     }
-  }
-
-  /*
-   * test PlcConnectionAdapter.newConsumer(address)
-   */
-  @SuppressWarnings("unchecked")
-  @Test
-  @Tag("fast")
-  public void testNewConsumer1() throws Exception {
-    String addressStr = "MyReadWriteAddress/0";
-    MockAddress address = new MockAddress(addressStr);
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
-    MockConnection connection = (MockConnection) adapter.getConnection();
-
-    Consumer<?> consumer;
-    
-    consumer = adapter.newConsumer(Boolean.class, addressStr);
-    Assertions.assertNotSame(consumer, adapter.newConsumer(Boolean.class, addressStr));
-    checkConsumer(connection, address, consumer, true, false);
-    
-    consumer = adapter.newConsumer(Byte.class, addressStr);
-    checkConsumer(connection, address, consumer, (byte)0x1, (byte)0x2, (byte)0x3);
-    
-    consumer = adapter.newConsumer(Short.class, addressStr);
-    checkConsumer(connection, address, consumer, (short)1, (short)2, (short)3);
-
-    consumer = adapter.newConsumer(Integer.class, addressStr);
-    checkConsumer(connection, address, consumer, 1000, 1001, 1002);
-    
-    consumer = adapter.newConsumer(Float.class, addressStr);
-    checkConsumer(connection, address, consumer, 1000.5f, 1001.5f, 1002.5f);
-    
-    consumer = adapter.newConsumer(String.class, addressStr);
-    checkConsumer(connection, address, consumer, "one", "two", "three");
-    
-    adapter.close();
-  }
-
-  /*
-   * test PlcConnectionAdapter.newConsumer(address) with write exception
-   */
-  @SuppressWarnings("unchecked")
-  @Test
-  @Tag("fast")
-  public void testNewConsumer1Neg() throws Exception {
-    String addressStr = "MyReadWriteAddress/0";
-    MockAddress address = new MockAddress(addressStr);
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
-    MockConnection connection = (MockConnection) adapter.getConnection();
-
-    Consumer<?> consumer;
-    
-    consumer = adapter.newConsumer(String.class, addressStr);
-    checkConsumer(2, connection, address, (Consumer<String>)consumer, "one", "two", "three");
-    
-    adapter.close();
-  }
-  
-  static <T> void checkConsumer(MockConnection connection, Address address, Consumer<T> consumer, Object ... values) throws Exception {
-    checkConsumer(0, connection, address, consumer, values);
-  }
-  @SuppressWarnings("unchecked")
-  private static <T> void checkConsumer(int writeFailureCountTrigger, MockConnection connection, Address address, Consumer<T> consumer, Object ... values) throws Exception {
-    // verify that a write failure doesn't kill the consumer
-    // it logs (not verified) but keeps working for the subsequent writes
-    connection.setWriteException(writeFailureCountTrigger, "This is a mock write exception");
-    int writeCount = 0;
-    Object previousValue = null;
-    for (Object value : values) {
-      consumer.accept((T)value);
-      T writtenData = (T) connection.getDataValue(address);
-      if(writtenData.getClass().isArray()) {
-        writtenData = (T) Array.get(writtenData, 0);
-      }
-      // System.out.println("checkConsumer"+(writeFailureCountTrigger > 0 ? "NEG" : "")+": value:"+value+" writtenData:"+writtenData);
-      if (writeFailureCountTrigger <= 0)
-        Assertions.assertEquals(value, writtenData);
-      else { 
-        if (++writeCount != writeFailureCountTrigger)
-          Assertions.assertEquals(value, writtenData);
-        else
-          Assertions.assertEquals(previousValue, writtenData);
-      }
-      previousValue = value;
+
+    /*
+     * Test the PlcConnectionAdapter(PlcConnection) ctor, getConnection() and close()
+     */
+    @Test
+    @Tag("fast")
+    public void testCtor1() throws Exception {
+        MockConnection mockConnection = getMockConnection();
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(mockConnection);
+        Assertions.assertSame(mockConnection, adapter.getConnection());
+        // and again... multiple adapter.getConnection() returns the same
+        Assertions.assertSame(mockConnection, adapter.getConnection());
+        adapter.close();
+    }
+
+    /*
+     * Test the PlcConnectionAdapter(url) ctor, getConnection() and close()
+     */
+    @Test
+    @Tag("fast")
+    public void testCtor2() throws Exception {
+        MockConnection mockConnection = getMockConnection();
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(mockConnection.getUrl());
+        MockConnection mockConnection2 = (MockConnection) adapter.getConnection();
+        Assertions.assertNotSame(mockConnection, mockConnection2);
+        Assertions.assertSame(mockConnection.getUrl(), mockConnection2.getUrl());
+        // and again... multiple adapter.getConnection() returns the same
+        Assertions.assertSame(mockConnection2, adapter.getConnection());
+        adapter.close();
+    }
+
+    @Test
+    @Tag("fast")
+    public void testCheckDatatype() throws Exception {
+        PlcConnectionAdapter.checkDatatype(Boolean.class);
+        PlcConnectionAdapter.checkDatatype(Byte.class);
+        PlcConnectionAdapter.checkDatatype(Short.class);
+        PlcConnectionAdapter.checkDatatype(Integer.class);
+        PlcConnectionAdapter.checkDatatype(Float.class);
+        PlcConnectionAdapter.checkDatatype(String.class);
+        PlcConnectionAdapter.checkDatatype(Calendar.class);
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> PlcConnectionAdapter.checkDatatype(Long.class));
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> PlcConnectionAdapter.checkDatatype(Double.class));
+    }
+
+    private <T> void checkRead(MockConnection connection, PlcReadRequest<T> request, T value) throws InterruptedException, ExecutionException {
+        // this is really a tests of our mock tooling but knowing it's behaving as expected
+        // will help identify problems in the adapter/supplier/consumer
+        connection.setDataValue(request.getReadRequestItems().get(0).getAddress(), value);
+
+        CompletableFuture<PlcReadResponse<T>> cf = connection.read(request);
+
+        Assertions.assertTrue(cf.isDone());
+        PlcReadResponse<T> response = cf.get();
+        Assertions.assertEquals(value, response.getResponseItems().get(0).getValues().get(0));
     }
-  }
-
-  /*
-   * test PlcConnectionAdapter.newConsumer(addressFn, valueFn)
-   */
-  @Test
-  @Tag("fast")
-  public void testNewConsumer2() throws Exception {
-    String addressStr = "MyReadWriteAddress/0";
-    MockAddress address = new MockAddress(addressStr);
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
-    MockConnection connection = (MockConnection) adapter.getConnection();
-
-    Consumer<JsonObject> consumer;
-    
-    Function<JsonObject,String> addressFn = t -> t.get("address").getAsString(); 
-    
-    consumer = adapter.newConsumer(Boolean.class, addressFn, t -> t.get("value").getAsBoolean());
-    checkConsumerJson(connection, address, consumer, true, false);
-    
-    consumer = adapter.newConsumer(Byte.class, addressFn, t -> t.get("value").getAsByte());
-    checkConsumerJson(connection, address, consumer, (byte)0x1, (byte)0x2, (byte)0x3);
-    
-    consumer = adapter.newConsumer(Short.class, addressFn, t -> t.get("value").getAsShort());
-    checkConsumerJson(connection, address, consumer, (short)1, (short)2, (short)3);
-
-    consumer = adapter.newConsumer(Integer.class, addressFn, t -> t.get("value").getAsInt());
-    checkConsumerJson(connection, address, consumer, 1000, 1001, 1002);
-    
-    consumer = adapter.newConsumer(Float.class, addressFn, t -> t.get("value").getAsFloat());
-    checkConsumerJson(connection, address, consumer, 1000.5f, 1001.5f, 1002.5f);
-    
-    consumer = adapter.newConsumer(String.class, addressFn, t -> t.get("value").getAsString());
-    checkConsumerJson(connection, address, consumer, "one", "two", "three");
-    
-    adapter.close();
-  }
-
-  /*
-   * test PlcConnectionAdapter.newConsumer(addressFn, valueFn) with write failure
-   */
-  @Test
-  @Tag("fast")
-  public void testNewConsumer2Neg() throws Exception {
-    String addressStr = "MyReadWriteAddress/0";
-    MockAddress address = new MockAddress(addressStr);
-    PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
-    MockConnection connection = (MockConnection) adapter.getConnection();
-
-    Consumer<JsonObject> consumer;
-    
-    Function<JsonObject,String> addressFn = t -> t.get("address").getAsString(); 
-    
-    consumer = adapter.newConsumer(String.class, addressFn, t -> t.get("value").getAsString());
-    checkConsumerJson(2, connection, address, consumer, "one", "two", "three");
-    
-    adapter.close();
-  }
-  
-  static <T> void checkConsumerJson(MockConnection connection, MockAddress address, Consumer<JsonObject> consumer, Object ... values) throws Exception {
-    checkConsumerJson(0, connection, address, consumer, values);
-  }
-  private static <T> void checkConsumerJson(int writeFailureCountTrigger, MockConnection connection, MockAddress address, Consumer<JsonObject> consumer, Object ... values) throws Exception {
-    if (writeFailureCountTrigger > 0)
-      connection.setWriteException(writeFailureCountTrigger, "This is a mock write exception");
-    int writeCount = 0;
-    Object previousValue = null;
-    for (Object value : values) {
-      
-      // build the JsonObject to consume
-      JsonObject jo = new JsonObject();
-      jo.addProperty("address", address.getAddress());
-      if (value instanceof Boolean)
-        jo.addProperty("value", (Boolean)value);
-      else if (value instanceof Number)
-        jo.addProperty("value", (Number)value);
-      else if (value instanceof String)
-        jo.addProperty("value", (String)value);
-      
-      consumer.accept(jo);
-      
-      @SuppressWarnings("unchecked")
-      T writtenData = (T) connection.getDataValue(address);
-      if(writtenData.getClass().isArray()) {
-        writtenData = (T) Array.get(writtenData, 0);
-      }
-      // System.out.println("checkConsumerJson"+(writeFailureCountTrigger > 0 ? "NEG" : "")+": value:"+value+" writtenData:"+writtenData);
-      if (writeFailureCountTrigger <= 0)
+
+    @SuppressWarnings("unchecked")
+    private <T> void checkWrite(MockConnection connection, PlcWriteRequest<T> request, T value) throws InterruptedException, ExecutionException {
+        // this is really a tests of our mock tooling but knowing it's behaving as expected
+        // will help identify problems in the adapter/supplier/consumer
+        connection.setDataValue(request.getRequestItems().get(0).getAddress(), value);
+
+        CompletableFuture<PlcWriteResponse<T>> cf = connection.write(request);
+
+        Assertions.assertTrue(cf.isDone());
+        PlcWriteResponse response = cf.get();
+        Assertions.assertNotNull(response);
+        T writtenData = (T) connection.getDataValue(request.getRequestItems().get(0).getAddress());
+        if (writtenData.getClass().isArray()) {
+            writtenData = (T) Array.get(writtenData, 0);
+        }
         Assertions.assertEquals(value, writtenData);
-      else { 
-        if (++writeCount != writeFailureCountTrigger)
-          Assertions.assertEquals(value, writtenData);
-        else
-          Assertions.assertEquals(previousValue, writtenData);
-      }
-      previousValue = value;
     }
-  }
+
+    /*
+     * Verify the adapter yields the appropriate PlcReadRequest for each type and that it works.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    @Tag("fast")
+    public void testNewPlcReadRequest() throws Exception {
+        String addressStr = "MyReadWriteAddress/0";
+        MockAddress address = new MockAddress(addressStr);
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
+        MockConnection connection = (MockConnection) adapter.getConnection();
+
+        {
+            PlcReadRequest<Boolean> request = PlcConnectionAdapter.newPlcReadRequest(Boolean.class, address);
+            ReadRequestItem<Boolean> requestItem = request.getReadRequestItems().get(0);
+            Class<Boolean> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(dataType == Boolean.class, "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkRead(connection, request, true);
+            checkRead(connection, request, false);
+        }
+        {
+            PlcReadRequest<Byte> request = PlcConnectionAdapter.newPlcReadRequest(Byte.class, address);
+            ReadRequestItem<Byte> requestItem = request.getReadRequestItems().get(0);
+            Class<Byte> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(dataType == Byte.class, "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkRead(connection, request, (byte) 0x13);
+            checkRead(connection, request, (byte) 0x23);
+        }
+        {
+            PlcReadRequest<Short> request = PlcConnectionAdapter.newPlcReadRequest(Short.class, address);
+            ReadRequestItem<Short> requestItem = request.getReadRequestItems().get(0);
+            Class<Short> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(dataType == Short.class, "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkRead(connection, request, (short) 13);
+            checkRead(connection, request, (short) 23);
+        }
+        {
+            PlcReadRequest<Integer> request = PlcConnectionAdapter.newPlcReadRequest(Integer.class, address);
+            ReadRequestItem<Integer> requestItem = request.getReadRequestItems().get(0);
+            Class<Integer> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(dataType == Integer.class, "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkRead(connection, request, 33);
+            checkRead(connection, request, -133);
+        }
+        {
+            PlcReadRequest<Float> request = PlcConnectionAdapter.newPlcReadRequest(Float.class, address);
+            ReadRequestItem<Float> requestItem = request.getReadRequestItems().get(0);
+            Class<Float> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(dataType == Float.class, "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkRead(connection, request, 43.5f);
+            checkRead(connection, request, -143.5f);
+        }
+        {
+            PlcReadRequest<String> request = PlcConnectionAdapter.newPlcReadRequest(String.class, address);
+            ReadRequestItem<String> requestItem = request.getReadRequestItems().get(0);
+            Class<String> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(dataType == String.class, "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkRead(connection, request, "ReadySetGo");
+            checkRead(connection, request, "OneMoreTime");
+        }
+        {
+            PlcReadRequest<Calendar> request = PlcConnectionAdapter.newPlcReadRequest(Calendar.class, address);
+            ReadRequestItem<Calendar> requestItem = request.getReadRequestItems().get(0);
+            Class<Calendar> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(dataType == Calendar.class, "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkRead(connection, request, Calendar.getInstance());
+        }
+        adapter.close();
+    }
+
+
+    /*
+     * Verify the adapter yields the appropriate PlcWriteRequest for each type and that it works.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    @Tag("fast")
+    public void testNewPlcWriteRequest() throws Exception {
+        String addressStr = "MyReadWriteAddress/0";
+        MockAddress address = new MockAddress(addressStr);
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
+        MockConnection connection = (MockConnection) adapter.getConnection();
+
+        {
+            PlcWriteRequest<Boolean> request = PlcConnectionAdapter.newPlcWriteRequest(address, true);
+            WriteRequestItem<Boolean> requestItem = request.getRequestItems().get(0);
+            Class<Boolean> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(Boolean.class.isAssignableFrom(dataType), "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkWrite(connection, request, true);
+        }
+        {
+            PlcWriteRequest<Byte> request = PlcConnectionAdapter.newPlcWriteRequest(address, (byte) 0x113);
+            WriteRequestItem<Byte> requestItem = request.getRequestItems().get(0);
+            Class<Byte> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(Byte.class.isAssignableFrom(dataType), "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkWrite(connection, request, (byte) 0x113);
+        }
+        {
+            PlcWriteRequest<Short> request = PlcConnectionAdapter.newPlcWriteRequest(address, (short) 113);
+            WriteRequestItem<Short> requestItem = request.getRequestItems().get(0);
+            Class<Short> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(Short.class.isAssignableFrom(dataType), "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkWrite(connection, request, (short) 113);
+        }
+        {
+            PlcWriteRequest<Integer> request = PlcConnectionAdapter.newPlcWriteRequest(address, 1033);
+            WriteRequestItem<Integer> requestItem = request.getRequestItems().get(0);
+            Class<Integer> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(Integer.class.isAssignableFrom(dataType), "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkWrite(connection, request, 1033);
+        }
+        {
+            PlcWriteRequest<Float> request = PlcConnectionAdapter.newPlcWriteRequest(address, 1043.5f);
+            WriteRequestItem<Float> requestItem = request.getRequestItems().get(0);
+            Class<Float> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(Float.class.isAssignableFrom(dataType), "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkWrite(connection, request, 1043.5f);
+        }
+        {
+            PlcWriteRequest<String> request = PlcConnectionAdapter.newPlcWriteRequest(address, "A written value");
+            WriteRequestItem<String> requestItem = request.getRequestItems().get(0);
+            Class<String> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(String.class.isAssignableFrom(dataType), "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkWrite(connection, request, "A written value");
+        }
+        {
+            Calendar calValue = Calendar.getInstance();
+            PlcWriteRequest<Calendar> request = PlcConnectionAdapter.newPlcWriteRequest(address, calValue);
+            WriteRequestItem<Calendar> requestItem = request.getRequestItems().get(0);
+            Class<Calendar> dataType = requestItem.getDatatype();
+            Assertions.assertTrue(Calendar.class.isAssignableFrom(dataType), "class:" + request.getClass());
+            Assertions.assertSame(address, requestItem.getAddress());
+            checkWrite(connection, request, calValue);
+        }
+        adapter.close();
+    }
+
+    /*
+     * test PlcConnectionAdapter.newSupplier
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    @Tag("fast")
+    public void testNewSupplier() throws Exception {
+        String addressStr = "MyReadWriteAddress/0";
+        MockAddress address = new MockAddress(addressStr);
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
+        MockConnection connection = (MockConnection) adapter.getConnection();
+
+        {
+            Supplier<Boolean> supplier = adapter.newSupplier(Boolean.class, addressStr);
+            Assertions.assertNotSame(supplier, adapter.newSupplier(Boolean.class, addressStr));
+            checkSupplier(connection, address, supplier, true, false);
+        }
+        {
+            Supplier<Byte> supplier = adapter.newSupplier(Byte.class, addressStr);
+            checkSupplier(connection, address, supplier, (byte) 0x1, (byte) 0x2, (byte) 0x3);
+        }
+        {
+            Supplier<Short> supplier = adapter.newSupplier(Short.class, addressStr);
+            checkSupplier(connection, address, supplier, (short) 1, (short) 2, (short) 3);
+        }
+        {
+            Supplier<Integer> supplier = adapter.newSupplier(Integer.class, addressStr);
+            checkSupplier(connection, address, supplier, 1000, 1001, 1002);
+        }
+        {
+            Supplier<Float> supplier = adapter.newSupplier(Float.class, addressStr);
+            checkSupplier(connection, address, supplier, 1000.5f, 1001.5f, 1002.5f);
+        }
+        {
+            Supplier<?> supplier = adapter.newSupplier(String.class, addressStr);
+            checkSupplier(connection, address, supplier, "one", "two", "three");
+        }
+        adapter.close();
+    }
+
+    /*
+     * test PlcConnectionAdapter.newSupplier with read exception
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    @Tag("fast")
+    public void testNewSupplierNeg() throws Exception {
+        String addressStr = "MyReadWriteAddress/0";
+        MockAddress address = new MockAddress(addressStr);
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
+        MockConnection connection = (MockConnection) adapter.getConnection();
+
+        Supplier<String> supplier = adapter.newSupplier(String.class, addressStr);
+        checkSupplier(2, connection, address, supplier, "one", "two", "three");
+
+        adapter.close();
+    }
+
+    static <T> void checkSupplier(MockConnection connection, Address address, Supplier<T> supplier, Object... values) throws Exception {
+        checkSupplier(0, connection, address, supplier, values);
+    }
+
+    private static <T> void checkSupplier(int readFailureCountTrigger, MockConnection connection, Address address, Supplier<T> supplier, Object... values) throws Exception {
+        // verify that a read failure doesn't kill the consumer
+        // it logs (not verified) but returns null (as designed) and keeps working for the subsequent reads
+        connection.setReadException(readFailureCountTrigger, "This is a mock read exception");
+        int readCount = 0;
+        for (Object value : values) {
+            connection.setDataValue(address, value);
+            T readData = supplier.get();
+            // System.out.println("checkSupplier"+(readFailureCountTrigger > 0 ? "NEG" : "")+": value:"+value+" readData:"+readData);
+            if (readFailureCountTrigger <= 0)
+                Assertions.assertEquals(value, readData);
+            else {
+                if (++readCount != readFailureCountTrigger)
+                    Assertions.assertEquals(value, readData);
+                else
+                    Assertions.assertNull(readData);
+            }
+        }
+    }
+
+    /*
+     * test PlcConnectionAdapter.newConsumer(address)
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    @Tag("fast")
+    public void testNewConsumer1() throws Exception {
+        String addressStr = "MyReadWriteAddress/0";
+        MockAddress address = new MockAddress(addressStr);
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
+        MockConnection connection = (MockConnection) adapter.getConnection();
+
+        Consumer<?> consumer;
+
+        consumer = adapter.newConsumer(Boolean.class, addressStr);
+        Assertions.assertNotSame(consumer, adapter.newConsumer(Boolean.class, addressStr));
+        checkConsumer(connection, address, consumer, true, false);
+
+        consumer = adapter.newConsumer(Byte.class, addressStr);
+        checkConsumer(connection, address, consumer, (byte) 0x1, (byte) 0x2, (byte) 0x3);
+
+        consumer = adapter.newConsumer(Short.class, addressStr);
+        checkConsumer(connection, address, consumer, (short) 1, (short) 2, (short) 3);
+
+        consumer = adapter.newConsumer(Integer.class, addressStr);
+        checkConsumer(connection, address, consumer, 1000, 1001, 1002);
+
+        consumer = adapter.newConsumer(Float.class, addressStr);
+        checkConsumer(connection, address, consumer, 1000.5f, 1001.5f, 1002.5f);
+
+        consumer = adapter.newConsumer(String.class, addressStr);
+        checkConsumer(connection, address, consumer, "one", "two", "three");
+
+        adapter.close();
+    }
+
+    /*
+     * test PlcConnectionAdapter.newConsumer(address) with write exception
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    @Tag("fast")
+    public void testNewConsumer1Neg() throws Exception {
+        String addressStr = "MyReadWriteAddress/0";
+        MockAddress address = new MockAddress(addressStr);
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
+        MockConnection connection = (MockConnection) adapter.getConnection();
+
+        Consumer<?> consumer;
+
+        consumer = adapter.newConsumer(String.class, addressStr);
+        checkConsumer(2, connection, address, (Consumer<String>) consumer, "one", "two", "three");
+
+        adapter.close();
+    }
+
+    static <T> void checkConsumer(MockConnection connection, Address address, Consumer<T> consumer, Object... values) throws Exception {
+        checkConsumer(0, connection, address, consumer, values);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> void checkConsumer(int writeFailureCountTrigger, MockConnection connection, Address address, Consumer<T> consumer, Object... values) throws Exception {
+        // verify that a write failure doesn't kill the consumer
+        // it logs (not verified) but keeps working for the subsequent writes
+        connection.setWriteException(writeFailureCountTrigger, "This is a mock write exception");
+        int writeCount = 0;
+        Object previousValue = null;
+        for (Object value : values) {
+            consumer.accept((T) value);
+            T writtenData = (T) connection.getDataValue(address);
+            if (writtenData.getClass().isArray()) {
+                writtenData = (T) Array.get(writtenData, 0);
+            }
+            // System.out.println("checkConsumer"+(writeFailureCountTrigger > 0 ? "NEG" : "")+": value:"+value+" writtenData:"+writtenData);
+            if (writeFailureCountTrigger <= 0)
+                Assertions.assertEquals(value, writtenData);
+            else {
+                if (++writeCount != writeFailureCountTrigger)
+                    Assertions.assertEquals(value, writtenData);
+                else
+                    Assertions.assertEquals(previousValue, writtenData);
+            }
+            previousValue = value;
+        }
+    }
+
+    /*
+     * test PlcConnectionAdapter.newConsumer(addressFn, valueFn)
+     */
+    @Test
+    @Tag("fast")
+    public void testNewConsumer2() throws Exception {
+        String addressStr = "MyReadWriteAddress/0";
+        MockAddress address = new MockAddress(addressStr);
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
+        MockConnection connection = (MockConnection) adapter.getConnection();
+
+        Consumer<JsonObject> consumer;
+
+        Function<JsonObject, String> addressFn = t -> t.get("address").getAsString();
+
+        consumer = adapter.newConsumer(Boolean.class, addressFn, t -> t.get("value").getAsBoolean());
+        checkConsumerJson(connection, address, consumer, true, false);
+
+        consumer = adapter.newConsumer(Byte.class, addressFn, t -> t.get("value").getAsByte());
+        checkConsumerJson(connection, address, consumer, (byte) 0x1, (byte) 0x2, (byte) 0x3);
+
+        consumer = adapter.newConsumer(Short.class, addressFn, t -> t.get("value").getAsShort());
+        checkConsumerJson(connection, address, consumer, (short) 1, (short) 2, (short) 3);
+
+        consumer = adapter.newConsumer(Integer.class, addressFn, t -> t.get("value").getAsInt());
+        checkConsumerJson(connection, address, consumer, 1000, 1001, 1002);
+
+        consumer = adapter.newConsumer(Float.class, addressFn, t -> t.get("value").getAsFloat());
+        checkConsumerJson(connection, address, consumer, 1000.5f, 1001.5f, 1002.5f);
+
+        consumer = adapter.newConsumer(String.class, addressFn, t -> t.get("value").getAsString());
+        checkConsumerJson(connection, address, consumer, "one", "two", "three");
+
+        adapter.close();
+    }
+
+    /*
+     * test PlcConnectionAdapter.newConsumer(addressFn, valueFn) with write failure
+     */
+    @Test
+    @Tag("fast")
+    public void testNewConsumer2Neg() throws Exception {
+        String addressStr = "MyReadWriteAddress/0";
+        MockAddress address = new MockAddress(addressStr);
+        PlcConnectionAdapter adapter = new PlcConnectionAdapter(getMockConnection());
+        MockConnection connection = (MockConnection) adapter.getConnection();
+
+        Consumer<JsonObject> consumer;
+
+        Function<JsonObject, String> addressFn = t -> t.get("address").getAsString();
+
+        consumer = adapter.newConsumer(String.class, addressFn, t -> t.get("value").getAsString());
+        checkConsumerJson(2, connection, address, consumer, "one", "two", "three");
+
+        adapter.close();
+    }
+
+    static <T> void checkConsumerJson(MockConnection connection, MockAddress address, Consumer<JsonObject> consumer, Object... values) throws Exception {
+        checkConsumerJson(0, connection, address, consumer, values);
+    }
+
+    private static <T> void checkConsumerJson(int writeFailureCountTrigger, MockConnection connection, MockAddress address, Consumer<JsonObject> consumer, Object... values) throws Exception {
+        if (writeFailureCountTrigger > 0)
+            connection.setWriteException(writeFailureCountTrigger, "This is a mock write exception");
+        int writeCount = 0;
+        Object previousValue = null;
+        for (Object value : values) {
+
+            // build the JsonObject to consume
+            JsonObject jo = new JsonObject();
+            jo.addProperty("address", address.getAddress());
+            if (value instanceof Boolean)
+                jo.addProperty("value", (Boolean) value);
+            else if (value instanceof Number)
+                jo.addProperty("value", (Number) value);
+            else if (value instanceof String)
+                jo.addProperty("value", (String) value);
+
+            consumer.accept(jo);
+
+            @SuppressWarnings("unchecked")
+            T writtenData = (T) connection.getDataValue(address);
+            if (writtenData.getClass().isArray()) {
+                writtenData = (T) Array.get(writtenData, 0);
+            }
+            // System.out.println("checkConsumerJson"+(writeFailureCountTrigger > 0 ? "NEG" : "")+": value:"+value+" writtenData:"+writtenData);
+            if (writeFailureCountTrigger <= 0)
+                Assertions.assertEquals(value, writtenData);
+            else {
+                if (++writeCount != writeFailureCountTrigger)
+                    Assertions.assertEquals(value, writtenData);
+                else
+                    Assertions.assertEquals(previousValue, writtenData);
+            }
+            previousValue = value;
+        }
+    }
 
 }
diff --git a/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java b/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
index d02c7a0..c81ce11 100644
--- a/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
+++ b/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
@@ -18,9 +18,6 @@ under the License.
 */
 package org.apache.plc4x.edgent.mock;
 
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
-
 import org.apache.plc4x.java.api.authentication.PlcAuthentication;
 import org.apache.plc4x.java.api.connection.AbstractPlcConnection;
 import org.apache.plc4x.java.api.connection.PlcReader;
@@ -39,33 +36,36 @@ import org.apache.plc4x.java.api.messages.items.WriteResponseItem;
 import org.apache.plc4x.java.api.model.Address;
 import org.apache.plc4x.java.api.types.ResponseCode;
 
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+
 public class MockConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
 
     private final String url;
     private final PlcAuthentication authentication;
-    private final Map<Address,Object> dataValueMap = new HashMap<>();
+    private final Map<Address, Object> dataValueMap = new HashMap<>();
     private long curReadCnt;
     private int readExceptionTriggerCount;
     private String readExceptionMsg;
     private long curWriteCnt;
     private int writeExceptionTriggerCount;
     private String writeExceptionMsg;
-  
+
     public MockConnection(String url) {
-      this(url, null);
+        this(url, null);
     }
-  
+
     public MockConnection(String url, PlcAuthentication authentication) {
-      this.url = url;
-      this.authentication = authentication;
+        this.url = url;
+        this.authentication = authentication;
     }
-  
+
     public PlcAuthentication getAuthentication() {
         return authentication;
     }
-    
+
     public String getUrl() {
-      return url;
+        return url;
     }
 
     @Override
@@ -80,68 +80,73 @@ public class MockConnection extends AbstractPlcConnection implements PlcReader,
 
     @Override
     public Address parseAddress(String addressString) throws PlcException {
-      return new MockAddress(addressString);
+        return new MockAddress(addressString);
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
-      curReadCnt++;
-      if (readExceptionTriggerCount > 0 && curReadCnt == readExceptionTriggerCount) {
-        curReadCnt = 0;
-        CompletableFuture<PlcReadResponse> cf = new CompletableFuture<>();
-        cf.completeExceptionally(new PlcIoException(readExceptionMsg));
-        return cf;
-      }
-      List<ReadResponseItem> responseItems = new LinkedList<>();
-      for (ReadRequestItem requestItem : readRequest.getReadRequestItems()) {
-        ReadResponseItem responseItem = new ReadResponseItem(requestItem, ResponseCode.OK,
-          Collections.singletonList(getDataValue(requestItem.getAddress())));
-        responseItems.add(responseItem);
-      }
-      PlcReadResponse response = new PlcReadResponse(readRequest, responseItems);
-      return CompletableFuture.completedFuture(response);
+    public <T> CompletableFuture<PlcReadResponse<T>> read(PlcReadRequest<T> readRequest) {
+        curReadCnt++;
+        if (readExceptionTriggerCount > 0 && curReadCnt == readExceptionTriggerCount) {
+            curReadCnt = 0;
+            CompletableFuture<PlcReadResponse<T>> cf = new CompletableFuture<>();
+            cf.completeExceptionally(new PlcIoException(readExceptionMsg));
+            return cf;
+        }
+        List<ReadResponseItem> responseItems = new LinkedList<>();
+        for (ReadRequestItem requestItem : readRequest.getReadRequestItems()) {
+            ReadResponseItem responseItem = new ReadResponseItem(requestItem, ResponseCode.OK,
+                Collections.singletonList(getDataValue(requestItem.getAddress())));
+            responseItems.add(responseItem);
+        }
+        PlcReadResponse response = new PlcReadResponse(readRequest, responseItems);
+        return CompletableFuture.completedFuture(response);
     }
 
     @Override
-    public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
-      curWriteCnt++;
-      if (writeExceptionTriggerCount > 0 && curWriteCnt == writeExceptionTriggerCount) {
-        curWriteCnt = 0;
-        CompletableFuture<PlcWriteResponse> cf = new CompletableFuture<>();
-        cf.completeExceptionally(new PlcIoException(writeExceptionMsg));
-        return cf;
-      }
-       List<WriteResponseItem> responseItems = new LinkedList<>();
-        for (WriteRequestItem requestItem : writeRequest.getRequestItems()) {
+    public <T> CompletableFuture<PlcWriteResponse<T>> write(PlcWriteRequest<T> writeRequest) {
+        curWriteCnt++;
+        if (writeExceptionTriggerCount > 0 && curWriteCnt == writeExceptionTriggerCount) {
+            curWriteCnt = 0;
+            CompletableFuture<PlcWriteResponse<T>> cf = new CompletableFuture<>();
+            cf.completeExceptionally(new PlcIoException(writeExceptionMsg));
+            return cf;
+        }
+        List<WriteResponseItem<T>> responseItems = new LinkedList<>();
+        for (WriteRequestItem<T> requestItem : writeRequest.getRequestItems()) {
             setDataValue(requestItem.getAddress(), requestItem.getValues());
-            WriteResponseItem responseItem = new WriteResponseItem(requestItem, ResponseCode.OK);
-          responseItems.add(responseItem);
+            WriteResponseItem<T> responseItem = new WriteResponseItem<>(requestItem, ResponseCode.OK);
+            responseItems.add(responseItem);
         }
-      PlcWriteResponse response = new PlcWriteResponse(writeRequest, responseItems);
-      return CompletableFuture.completedFuture(response);
+        PlcWriteResponse<T> response = new PlcWriteResponse<>(writeRequest, responseItems);
+        return CompletableFuture.completedFuture(response);
     }
 
     public void setDataValue(Address address, Object o) {
-      dataValueMap.put(address, o);
+        dataValueMap.put(address, o);
     }
+
     public Object getDataValue(Address address) {
-      return dataValueMap.get(address);
+        return dataValueMap.get(address);
     }
-    public Map<Address,Object> getAllDataValues() {
-      return dataValueMap;
+
+    public Map<Address, Object> getAllDataValues() {
+        return dataValueMap;
     }
+
     public void clearAllDataValues() {
-      dataValueMap.clear();
+        dataValueMap.clear();
     }
+
     public void setReadException(int readTriggerCount, String msg) {
-      readExceptionTriggerCount = readTriggerCount;
-      readExceptionMsg = msg;
-      curReadCnt = 0;
+        readExceptionTriggerCount = readTriggerCount;
+        readExceptionMsg = msg;
+        curReadCnt = 0;
     }
+
     public void setWriteException(int writeTriggerCount, String msg) {
-      writeExceptionTriggerCount = writeTriggerCount;
-      writeExceptionMsg = msg;
-      curWriteCnt = 0;
+        writeExceptionTriggerCount = writeTriggerCount;
+        writeExceptionMsg = msg;
+        curWriteCnt = 0;
     }
 }
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcReader.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcReader.java
index 35ddf1b..d6faa78 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcReader.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcReader.java
@@ -28,12 +28,14 @@ import java.util.concurrent.CompletableFuture;
  */
 public interface PlcReader {
 
+
     /**
      * Reads a requested value from a PLC.
      *
      * @param readRequest object describing the type and location of the value.
+     * @param <T>         type that is being requested.
      * @return a {@link CompletableFuture} giving async access to the returned value.
      */
-    CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest);
+    <T> CompletableFuture<PlcReadResponse<T>> read(PlcReadRequest<T> readRequest);
 
 }
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcWriter.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcWriter.java
index d427dc8..53add5b 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcWriter.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcWriter.java
@@ -33,8 +33,9 @@ public interface PlcWriter {
      * Writes a given value to a PLC.
      *
      * @param writeRequest object describing the type, location and value that whould be written.
+     * @param <T>          type that is being requested.
      * @return a {@link CompletableFuture} giving async access to the response of the write operation.
      */
-    CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest);
+    <T> CompletableFuture<PlcWriteResponse<T>> write(PlcWriteRequest<T> writeRequest);
 
 }
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadRequest.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadRequest.java
index 5c3e522..fddbd4d 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadRequest.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadRequest.java
@@ -24,33 +24,33 @@ import org.apache.plc4x.java.api.model.Address;
 import java.util.LinkedList;
 import java.util.List;
 
-public class PlcReadRequest implements PlcRequest {
+public class PlcReadRequest<T> implements PlcRequest {
 
-    private final List<ReadRequestItem> readRequestItems;
+    private final List<ReadRequestItem<T>> readRequestItems;
 
     public PlcReadRequest() {
         this.readRequestItems = new LinkedList<>();
     }
 
-    public PlcReadRequest(Class dataType, Address address) {
+    public PlcReadRequest(Class<T> dataType, Address address) {
         this();
-        addItem(new ReadRequestItem(dataType, address));
+        addItem(new ReadRequestItem<>(dataType, address));
     }
 
-    public PlcReadRequest(Class dataType, Address address, int size) {
+    public PlcReadRequest(Class<T> dataType, Address address, int size) {
         this();
-        addItem(new ReadRequestItem(dataType, address, size));
+        addItem(new ReadRequestItem<>(dataType, address, size));
     }
 
-    public PlcReadRequest(List<ReadRequestItem> readRequestItems) {
+    public PlcReadRequest(List<ReadRequestItem<T>> readRequestItems) {
         this.readRequestItems = readRequestItems;
     }
 
-    public void addItem(ReadRequestItem readRequestItem) {
+    public void addItem(ReadRequestItem<T> readRequestItem) {
         readRequestItems.add(readRequestItem);
     }
 
-    public List<ReadRequestItem> getReadRequestItems() {
+    public List<ReadRequestItem<T>> getReadRequestItems() {
         return readRequestItems;
     }
 
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadResponse.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadResponse.java
index 8d4d7d9..7b31cb3 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadResponse.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcReadResponse.java
@@ -22,12 +22,12 @@ import org.apache.plc4x.java.api.messages.items.ReadResponseItem;
 
 import java.util.List;
 
-public class PlcReadResponse implements PlcResponse {
+public class PlcReadResponse<T> implements PlcResponse {
 
     private final PlcReadRequest request;
-    private final List<ReadResponseItem> responseItems;
+    private final List<ReadResponseItem<T>> responseItems;
 
-    public PlcReadResponse(PlcReadRequest request, List<ReadResponseItem> responseItems) {
+    public PlcReadResponse(PlcReadRequest request, List<ReadResponseItem<T>> responseItems) {
         this.request = request;
         this.responseItems = responseItems;
     }
@@ -36,7 +36,7 @@ public class PlcReadResponse implements PlcResponse {
         return request;
     }
 
-    public List<ReadResponseItem> getResponseItems() {
+    public List<ReadResponseItem<T>> getResponseItems() {
         return responseItems;
     }
 
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcWriteRequest.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcWriteRequest.java
index ecfdf53..3ff0999 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcWriteRequest.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcWriteRequest.java
@@ -24,33 +24,33 @@ import org.apache.plc4x.java.api.model.Address;
 import java.util.LinkedList;
 import java.util.List;
 
-public class PlcWriteRequest implements PlcRequest {
+public class PlcWriteRequest<T> implements PlcRequest {
 
-    private final List<WriteRequestItem> requestItems;
+    private final List<WriteRequestItem<T>> requestItems;
 
     public PlcWriteRequest() {
         this.requestItems = new LinkedList<>();
     }
 
-    public PlcWriteRequest(Class dataType, Address address, Object value) {
+    public PlcWriteRequest(Class<T> dataType, Address address, T value) {
         this();
-        addItem(new WriteRequestItem(dataType, address, value));
+        addItem(new WriteRequestItem<>(dataType, address, value));
     }
 
-    public PlcWriteRequest(Class dataType, Address address, Object[] values) {
+    public PlcWriteRequest(Class<T> dataType, Address address, T[] values) {
         this();
-        addItem(new WriteRequestItem(dataType, address, values));
+        addItem(new WriteRequestItem<>(dataType, address, values));
     }
 
-    public PlcWriteRequest(List<WriteRequestItem> requestItems) {
+    public PlcWriteRequest(List<WriteRequestItem<T>> requestItems) {
         this.requestItems = requestItems;
     }
 
-    public void addItem(WriteRequestItem requestItem) {
+    public void addItem(WriteRequestItem<T> requestItem) {
         requestItems.add(requestItem);
     }
 
-    public List<WriteRequestItem> getRequestItems() {
+    public List<WriteRequestItem<T>> getRequestItems() {
         return requestItems;
     }
 
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcWriteResponse.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcWriteResponse.java
index 9e8a925..58b8ce7 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcWriteResponse.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcWriteResponse.java
@@ -22,21 +22,21 @@ import org.apache.plc4x.java.api.messages.items.WriteResponseItem;
 
 import java.util.List;
 
-public class PlcWriteResponse implements PlcResponse {
+public class PlcWriteResponse<T> implements PlcResponse {
 
-    private final PlcWriteRequest request;
-    private final List<WriteResponseItem> responseItems;
+    private final PlcWriteRequest<T> request;
+    private final List<WriteResponseItem<T>> responseItems;
 
-    public PlcWriteResponse(PlcWriteRequest request, List<WriteResponseItem> responseItems) {
+    public PlcWriteResponse(PlcWriteRequest<T> request, List<WriteResponseItem<T>> responseItems) {
         this.request = request;
         this.responseItems = responseItems;
     }
 
-    public PlcWriteRequest getRequest() {
+    public PlcWriteRequest<T> getRequest() {
         return request;
     }
 
-    public List<WriteResponseItem> getResponseItems() {
+    public List<WriteResponseItem<T>> getResponseItems() {
         return responseItems;
     }
 
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/ReadRequestItem.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/ReadRequestItem.java
index b4e29fb..6086959 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/ReadRequestItem.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/ReadRequestItem.java
@@ -20,27 +20,27 @@ package org.apache.plc4x.java.api.messages.items;
 
 import org.apache.plc4x.java.api.model.Address;
 
-public class ReadRequestItem {
+public class ReadRequestItem<T> {
 
-    private final Class datatype;
+    private final Class<T> datatype;
 
     private final Address address;
 
     private final int size;
 
-    public ReadRequestItem(Class datatype, Address address) {
+    public ReadRequestItem(Class<T> datatype, Address address) {
         this.datatype = datatype;
         this.address = address;
         this.size = 1;
     }
 
-    public ReadRequestItem(Class datatype, Address address, int size) {
+    public ReadRequestItem(Class<T> datatype, Address address, int size) {
         this.datatype = datatype;
         this.address = address;
         this.size = size;
     }
 
-    public Class getDatatype() {
+    public Class<T> getDatatype() {
         return datatype;
     }
 
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/ReadResponseItem.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/ReadResponseItem.java
index 7bf33bb..286fb64 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/ReadResponseItem.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/ReadResponseItem.java
@@ -22,15 +22,15 @@ import org.apache.plc4x.java.api.types.ResponseCode;
 
 import java.util.List;
 
-public class ReadResponseItem {
+public class ReadResponseItem<T> {
 
-    private final ReadRequestItem requestItem;
+    private final ReadRequestItem<T> requestItem;
 
     private final ResponseCode responseCode;
 
-    private final List<Object> values;
+    private final List<T> values;
 
-    public ReadResponseItem(ReadRequestItem requestItem, ResponseCode responseCode, List<Object> values) {
+    public ReadResponseItem(ReadRequestItem<T> requestItem, ResponseCode responseCode, List<T> values) {
         this.requestItem = requestItem;
         this.responseCode = responseCode;
         this.values = values;
@@ -44,7 +44,7 @@ public class ReadResponseItem {
         return responseCode;
     }
 
-    public List<Object> getValues() {
+    public List<T> getValues() {
         return values;
     }
 
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/WriteRequestItem.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/WriteRequestItem.java
index c482359..44111ae 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/WriteRequestItem.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/WriteRequestItem.java
@@ -20,27 +20,31 @@ package org.apache.plc4x.java.api.messages.items;
 
 import org.apache.plc4x.java.api.model.Address;
 
-public class WriteRequestItem {
+import java.lang.reflect.Array;
 
-    private final Class datatype;
+public class WriteRequestItem<T> {
+
+    private final Class<T> datatype;
 
     private final Address address;
 
-    private final Object[] values;
+    private final T[] values;
 
-    public WriteRequestItem(Class datatype, Address address, Object value) {
+    @SuppressWarnings("unchecked")
+    public WriteRequestItem(Class<T> datatype, Address address, T value) {
         this.datatype = datatype;
         this.address = address;
-        this.values = new Object[]{value};
+        this.values = (T[]) Array.newInstance(datatype, 1);
+        this.values[0] = value;
     }
 
-    public WriteRequestItem(Class datatype, Address address, Object[] values) {
+    public WriteRequestItem(Class<T> datatype, Address address, T[] values) {
         this.datatype = datatype;
         this.address = address;
         this.values = values;
     }
 
-    public Class getDatatype() {
+    public Class<T> getDatatype() {
         return datatype;
     }
 
@@ -48,7 +52,7 @@ public class WriteRequestItem {
         return address;
     }
 
-    public Object[] getValues() {
+    public T[] getValues() {
         return values;
     }
 
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/WriteResponseItem.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/WriteResponseItem.java
index 5761c2b..524f68f 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/WriteResponseItem.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/items/WriteResponseItem.java
@@ -20,18 +20,18 @@ package org.apache.plc4x.java.api.messages.items;
 
 import org.apache.plc4x.java.api.types.ResponseCode;
 
-public class WriteResponseItem {
+public class WriteResponseItem<T> {
 
-    private final WriteRequestItem requestItem;
+    private final WriteRequestItem<T> requestItem;
 
     private final ResponseCode responseCode;
 
-    public WriteResponseItem(WriteRequestItem requestItem, ResponseCode responseCode) {
+    public WriteResponseItem(WriteRequestItem<T> requestItem, ResponseCode responseCode) {
         this.requestItem = requestItem;
         this.responseCode = responseCode;
     }
 
-    public WriteRequestItem getRequestItem() {
+    public WriteRequestItem<T> getRequestItem() {
         return requestItem;
     }
 
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
index e43c5d4..09eea8f 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
@@ -65,7 +65,7 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
         if (msg.getRequest() instanceof PlcReadRequest) {
             List<VarParameterItem> parameterItems = new LinkedList<>();
 
-            PlcReadRequest readRequest = (PlcReadRequest) msg.getRequest();
+            PlcReadRequest<?> readRequest = (PlcReadRequest<?>) msg.getRequest();
             for (ReadRequestItem requestItem : readRequest.getReadRequestItems()) {
                 // Try to get the correct S7 transport size for the given data type.
                 // (Map PLC4X data type to S7 data type)
@@ -78,7 +78,7 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
                 VarParameterItem varParameterItem = encodeVarParameterItem(requestItem.getAddress(), transportSize, requestItem.getSize());
                 parameterItems.add(varParameterItem);
             }
-            VarParameter readVarParameter =  new VarParameter(ParameterType.READ_VAR, parameterItems);
+            VarParameter readVarParameter = new VarParameter(ParameterType.READ_VAR, parameterItems);
 
             // Assemble the request.
             S7RequestMessage s7ReadRequest = new S7RequestMessage(MessageType.JOB,
@@ -88,11 +88,11 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
             requests.put(s7ReadRequest.getTpduReference(), msg);
 
             out.add(s7ReadRequest);
-        } else if(msg.getRequest() instanceof PlcWriteRequest) {
+        } else if (msg.getRequest() instanceof PlcWriteRequest) {
             List<VarParameterItem> parameterItems = new LinkedList<>();
             List<VarPayloadItem> payloadItems = new LinkedList<>();
 
-            PlcWriteRequest writeRequest = (PlcWriteRequest) msg.getRequest();
+            PlcWriteRequest<?> writeRequest = (PlcWriteRequest<?>) msg.getRequest();
             for (WriteRequestItem requestItem : writeRequest.getRequestItems()) {
                 // Try to get the correct S7 transport size for the given data type.
                 // (Map PLC4X data type to S7 data type)
@@ -116,7 +116,7 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
 
                 payloadItems.add(varPayloadItem);
             }
-            VarParameter writeVarParameter =  new VarParameter(ParameterType.WRITE_VAR, parameterItems);
+            VarParameter writeVarParameter = new VarParameter(ParameterType.WRITE_VAR, parameterItems);
             VarPayload writeVarPayload = new VarPayload(ParameterType.WRITE_VAR, payloadItems);
 
             // Assemble the request.
@@ -130,9 +130,10 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
         }
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     protected void decode(ChannelHandlerContext ctx, S7Message msg, List<Object> out) throws Exception {
-        if(msg instanceof S7ResponseMessage) {
+        if (msg instanceof S7ResponseMessage) {
             S7ResponseMessage responseMessage = (S7ResponseMessage) msg;
             short tpduReference = responseMessage.getTpduReference();
             if (requests.containsKey(tpduReference)) {
@@ -142,14 +143,14 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
 
                 // Handle the response to a read request.
                 if (requestContainer.getRequest() instanceof PlcReadRequest) {
-                    PlcReadRequest plcReadRequest = (PlcReadRequest) requestContainer.getRequest();
+                    PlcReadRequest<?> plcReadRequest = (PlcReadRequest<?>) requestContainer.getRequest();
 
                     List<ReadResponseItem> responseItems = new LinkedList<>();
                     VarPayload payload = responseMessage.getPayload(VarPayload.class);
                     // If the numbers of items don't match, we're in big trouble as the only
                     // way to know how to interpret the responses is by aligning them with the
                     // items from the request as this information is not returned by the PLC.
-                    if(plcReadRequest.getReadRequestItems().size() != payload.getPayloadItems().size()) {
+                    if (plcReadRequest.getReadRequestItems().size() != payload.getPayloadItems().size()) {
                         throw new PlcProtocolException(
                             "The number of requested items doesn't match the number of returned items");
                     }
@@ -158,20 +159,20 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
                         VarPayloadItem payloadItem = payloadItems.get(i);
 
                         // Get the request item for this payload item
-                        ReadRequestItem requestItem = plcReadRequest.getReadRequestItems().get(i);
+                        ReadRequestItem<?> requestItem = plcReadRequest.getReadRequestItems().get(i);
 
                         ResponseCode responseCode = decodeResponseCode(payloadItem.getReturnCode());
 
-                        ReadResponseItem responseItem;
+                        ReadResponseItem<?> responseItem;
                         // Something went wrong.
-                        if(responseCode != ResponseCode.OK) {
-                            responseItem = new ReadResponseItem(requestItem, responseCode, null);
+                        if (responseCode != ResponseCode.OK) {
+                            responseItem = new ReadResponseItem<>(requestItem, responseCode, null);
                         }
                         // All Ok.
                         else {
                             byte[] data = payloadItem.getData();
                             Class<?> datatype = requestItem.getDatatype();
-                            List<Object> value = decodeData(datatype, data);
+                            List<?> value = decodeData(datatype, data);
                             responseItem = new ReadResponseItem(requestItem, responseCode, value);
                         }
                         responseItems.add(responseItem);
@@ -181,13 +182,13 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
 
                 // Handle the response to a write request.
                 else if (requestContainer.getRequest() instanceof PlcWriteRequest) {
-                    PlcWriteRequest plcWriteRequest = (PlcWriteRequest) requestContainer.getRequest();
+                    PlcWriteRequest<?> plcWriteRequest = (PlcWriteRequest) requestContainer.getRequest();
                     List<WriteResponseItem> responseItems = new LinkedList<>();
                     VarPayload payload = responseMessage.getPayload(VarPayload.class);
                     // If the numbers of items don't match, we're in big trouble as the only
                     // way to know how to interpret the responses is by aligning them with the
                     // items from the request as this information is not returned by the PLC.
-                    if(plcWriteRequest.getRequestItems().size() != payload.getPayloadItems().size()) {
+                    if (plcWriteRequest.getRequestItems().size() != payload.getPayloadItems().size()) {
                         throw new PlcProtocolException(
                             "The number of requested items doesn't match the number of returned items");
                     }
@@ -286,7 +287,7 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
     }
 
     private byte[] encodeData(Object[] values) {
-        if(values.length == 0) {
+        if (values.length == 0) {
             return null;
         }
         byte[] result = null;
@@ -294,24 +295,24 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
         if (valueType == Boolean.class) {
             // TODO: Check if this is true and the result is not Math.ceil(values.lenght / 8)
             result = new byte[values.length * 1];
-            for(int i = 0; i < values.length; i++) {
+            for (int i = 0; i < values.length; i++) {
                 result[i] = (byte) (((Boolean) values[i]) ? 0x01 : 0x00);
             }
         } else if (valueType == Byte[].class) {
             result = new byte[values.length * 1];
-            for(int i = 0; i < values.length; i++) {
+            for (int i = 0; i < values.length; i++) {
                 result[i] = (byte) values[i];
             }
         } else if (valueType == Short.class) {
             result = new byte[values.length * 2];
-            for(int i = 0; i < values.length; i++) {
+            for (int i = 0; i < values.length; i++) {
                 short intValue = (short) values[i];
                 result[i * 2] = (byte) ((intValue & 0xff00) >> 8);
                 result[(i * 2) + 1] = (byte) (intValue & 0xff);
             }
         } else if (valueType == Integer.class) {
             result = new byte[values.length * 4];
-            for(int i = 0; i < values.length; i++) {
+            for (int i = 0; i < values.length; i++) {
                 int intValue = (int) values[i];
                 result[i * 4] = (byte) ((intValue & 0xff000000) >> 24);
                 result[(i * 4) + 1] = (byte) ((intValue & 0x00ff0000) >> 16);
@@ -322,7 +323,7 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
             result = null;
         } else if (valueType == Float.class) {
             result = new byte[values.length * 4];
-            for(int i = 0; i < values.length; i++) {
+            for (int i = 0; i < values.length; i++) {
                 float floatValue = (float) values[i];
                 int intValue = Float.floatToIntBits(floatValue);
                 result[i * 4] = (byte) ((intValue & 0xff000000) >> 24);
@@ -341,7 +342,7 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
     ////////////////////////////////////////////////////////////////////////////////
 
     private ResponseCode decodeResponseCode(DataTransportErrorCode dataTransportErrorCode) {
-        if(dataTransportErrorCode != null) {
+        if (dataTransportErrorCode != null) {
             switch (dataTransportErrorCode) {
                 case OK:
                     return ResponseCode.OK;
@@ -354,25 +355,26 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
         return ResponseCode.INTERNAL_ERROR;
     }
 
-    private List<Object> decodeData(Class<?> datatype, byte[] s7Data) {
-        if(s7Data.length == 0) {
+    @SuppressWarnings("unchecked")
+    private <T> List<T> decodeData(Class<T> datatype, byte[] s7Data) {
+        if (s7Data.length == 0) {
             return null;
         }
         List<Object> result = new LinkedList<>();
-        for(int i = 0; i < s7Data.length; i++) {
+        for (int i = 0; i < s7Data.length; i++) {
             if (datatype == Boolean.class) {
                 result.add((s7Data[i] & 0x01) == 0x01);
-                i+=1;
+                i += 1;
             } else if (datatype == Byte.class) {
                 result.add(s7Data[i]);
-                i+=1;
+                i += 1;
             } else if (datatype == Short.class) {
-                result.add((short) (((s7Data[i] & 0xff) << 8) | (s7Data[i+1] & 0xff)));
-                i+=2;
+                result.add((short) (((s7Data[i] & 0xff) << 8) | (s7Data[i + 1] & 0xff)));
+                i += 2;
             } else if (datatype == Integer.class) {
                 result.add((((s7Data[i] & 0xff) << 24) | ((s7Data[i + 1] & 0xff) << 16) |
                     ((s7Data[i + 2] & 0xff) << 8) | (s7Data[i + 3] & 0xff)));
-                i+=4;
+                i += 4;
             } else if (datatype == Float.class) {
                 // Description of the Real number format:
                 // https://www.sps-lehrgang.de/zahlenformate-step7/#c144
@@ -380,10 +382,10 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
                 int intValue = (((s7Data[i] & 0xff) << 24) | ((s7Data[i + 1] & 0xff) << 16) |
                     ((s7Data[i + 2] & 0xff) << 8) | (s7Data[i + 3] & 0xff));
                 result.add(Float.intBitsToFloat(intValue));
-                i+=4;
+                i += 4;
             }
         }
-        return result;
+        return (List<T>) result;
     }
 
 }
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcReaderSample.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcReaderSample.java
index 8af53d5..06cce9d 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcReaderSample.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcReaderSample.java
@@ -22,9 +22,9 @@ import org.apache.plc4x.java.PlcDriverManager;
 import org.apache.plc4x.java.api.connection.PlcConnection;
 import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.items.ReadResponseItem;
 import org.apache.plc4x.java.api.model.Address;
-import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,7 +44,7 @@ public class S7PlcReaderSample {
     public static void main(String[] args) throws Exception {
         // Create a connection to the S7 PLC (s7://{hostname/ip}/{racknumber}/{slotnumber})
         logger.info("Connecting");
-        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://192.168.0.1/0/0")){
+        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://192.168.0.1/0/0")) {
             logger.info("Connected");
 
             Optional<PlcReader> reader = plcConnection.getReader();
@@ -63,8 +63,8 @@ public class S7PlcReaderSample {
                 // Read synchronously ...
                 // NOTICE: the ".get()" immediately lets this thread pause till
                 // the response is processed and available.
-                PlcReadResponse plcReadResponse = plcReader.read(new PlcReadRequest(Byte.class, inputs)).get();
-                List<ReadResponseItem> responseItems = plcReadResponse.getResponseItems();
+                PlcReadResponse<Byte> plcReadResponse = plcReader.read(new PlcReadRequest<>(Byte.class, inputs)).get();
+                List<ReadResponseItem<Byte>> responseItems = plcReadResponse.getResponseItems();
                 System.out.println("Inputs: " + responseItems.get(0).getValues().get(0));
 
                 //////////////////////////////////////////////////////////
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcScanner.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcScanner.java
index 2e6b720..65a9812 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcScanner.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcScanner.java
@@ -43,7 +43,7 @@ public class S7PlcScanner {
     public static void main(String[] args) throws Exception {
         // Create a connection to the S7 PLC (s7://{hostname/ip}/{racknumber}/{slotnumber})
         logger.info("Connecting");
-        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://192.168.0.1/0/0")){
+        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://192.168.0.1/0/0")) {
             logger.info("Connected");
 
             Optional<PlcReader> reader = plcConnection.getReader();
@@ -54,18 +54,18 @@ public class S7PlcScanner {
                 for (MemoryArea memoryArea : MemoryArea.values()) {
                     System.out.println(memoryArea);
                     System.out.println("------------------------------------------");
-                    for(int i = 0; i < 8959; i++) {
+                    for (int i = 0; i < 8959; i++) {
                         try {
                             Address address;
-                            if(memoryArea == MemoryArea.DATA_BLOCKS) {
+                            if (memoryArea == MemoryArea.DATA_BLOCKS) {
                                 address = plcConnection.parseAddress("DATA_BLOCKS/1/" + i);
                             } else {
                                 address = plcConnection.parseAddress(memoryArea.name() + "/" + i);
                             }
-                            PlcReadResponse plcReadResponse = plcReader.read(
-                                new PlcReadRequest(Byte.class, address)).get();
-                            Byte data = (Byte) plcReadResponse.getResponseItems().get(0).getValues().get(0);
-                            if(data != null && data != 0) {
+                            PlcReadResponse<Byte> plcReadResponse = plcReader.read(
+                                new PlcReadRequest<>(Byte.class, address)).get();
+                            Byte data = plcReadResponse.getResponseItems().get(0).getValues().get(0);
+                            if (data != null && data != 0) {
                                 System.out.println(String.format(
                                     "Response: Memory Area: %s Index: %d Value: %02X", memoryArea.name(), i, data));
                             }
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcTestConsole.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcTestConsole.java
index a19bb22..c425dcf 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcTestConsole.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcTestConsole.java
@@ -44,7 +44,7 @@ public class S7PlcTestConsole {
     public static void main(String[] args) throws Exception {
         // Create a connection to the S7 PLC (s7://{hostname/ip}/{racknumber}/{slotnumber})
         logger.info("Connecting");
-        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://192.168.0.1/0/0")){
+        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://192.168.0.1/0/0")) {
             logger.info("Connected");
 
             Optional<PlcReader> reader = plcConnection.getReader();
@@ -54,13 +54,13 @@ public class S7PlcTestConsole {
 
                 Scanner scanner = new Scanner(System.in);
                 String line;
-                while(!"exit".equalsIgnoreCase(line = scanner.next())) {
+                while (!"exit".equalsIgnoreCase(line = scanner.next())) {
                     try {
                         Address address = plcConnection.parseAddress(line);
-                        PlcReadResponse plcReadResponse = plcReader.read(new PlcReadRequest(Byte.class, address)).get();
-                        List<Object> data = plcReadResponse.getResponseItems().get(0).getValues();
+                        PlcReadResponse<Byte> plcReadResponse = plcReader.read(new PlcReadRequest<>(Byte.class, address)).get();
+                        List<Byte> data = plcReadResponse.getResponseItems().get(0).getValues();
                         System.out.println("Response: " + data.get(0));
-                    } catch(Exception e) {
+                    } catch (Exception e) {
                         e.printStackTrace();
                     }
                 }
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcWriterSample.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcWriterSample.java
index dd4b3b2..d77b258 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcWriterSample.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/S7PlcWriterSample.java
@@ -21,7 +21,8 @@ package org.apache.plc4x.java.s7;
 import org.apache.plc4x.java.PlcDriverManager;
 import org.apache.plc4x.java.api.connection.PlcConnection;
 import org.apache.plc4x.java.api.connection.PlcWriter;
-import org.apache.plc4x.java.api.messages.*;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteResponse;
 import org.apache.plc4x.java.api.model.Address;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,7 +42,7 @@ public class S7PlcWriterSample {
     public static void main(String[] args) throws Exception {
         // Create a connection to the S7 PLC (s7://{hostname/ip}/{racknumber}/{slotnumber})
         logger.info("Connecting");
-        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://192.168.0.1/0/0")){
+        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://192.168.0.1/0/0")) {
             logger.info("Connected");
 
             Optional<PlcWriter> writer = plcConnection.getWriter();
@@ -53,8 +54,8 @@ public class S7PlcWriterSample {
                 // Write synchronously ...
                 // NOTICE: the ".get()" immediately lets this thread pause till
                 // the response is processed and available.
-                PlcWriteResponse plcWriteResponse = plcWriter.write(
-                    new PlcWriteRequest(Float.class, inputs, 2.0f)).get();
+                PlcWriteResponse<Float> plcWriteResponse = plcWriter.write(
+                    new PlcWriteRequest<>(Float.class, inputs, 2.0f)).get();
                 System.out.println("Written: " + plcWriteResponse.getResponseItems().get(0).getResponseCode().name());
             }
         }

-- 
To stop receiving notification emails like this one, please contact
"commits@plc4x.apache.org" <co...@plc4x.apache.org>.