You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2018/08/29 16:57:51 UTC
[incubator-plc4x] branch feature/api-redesign-chris-c updated: -
Adjusted the camel integration - Continued work on the Edgent integration -
Started implementing the api changes in driver base
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/api-redesign-chris-c
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git
The following commit(s) were added to refs/heads/feature/api-redesign-chris-c by this push:
new abbf96c - Adjusted the camel integration - Continued work on the Edgent integration - Started implementing the api changes in driver base
abbf96c is described below
commit abbf96caa04b240ec26f6af2086c85fd2add98a2
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Aug 29 18:57:42 2018 +0200
- Adjusted the camel integration
- Continued work on the Edgent integration
- Started implementing the api changes in driver base
---
.../java/org/apache/plc4x/camel/Constants.java | 3 +-
.../java/org/apache/plc4x/camel/Plc4XConsumer.java | 64 ++--
.../apache/plc4x/camel/Plc4XPollingConsumer.java | 32 +-
.../java/org/apache/plc4x/camel/Plc4XProducer.java | 21 +-
.../plc4x/camel/ResponseItemTypeConverter.java | 34 ---
.../services/org/apache/camel/TypeConverter | 19 --
.../apache/plc4x/edgent/PlcConnectionAdapter.java | 1 -
.../plc4x/edgent/PlcConnectionAdapterTest.java | 22 --
.../apache/plc4x/edgent/mock/MockConnection.java | 10 +
.../plc4x/java/api/connection/PlcConnection.java | 11 -
.../plc4x/java/api/connection/PlcSubscriber.java | 4 +-
.../plc4x/java/api/messages/PlcFieldRequest.java | 5 -
.../plc4x/java/api/messages/PlcReadRequest.java | 2 -
.../java/api/messages/PlcSubscriptionEvent.java | 2 +-
.../java/api/messages/PlcSubscriptionRequest.java | 36 +++
.../java/api/messages/PlcSubscriptionResponse.java | 4 +
.../api/messages/PlcUnsubscriptionRequest.java | 29 +-
.../plc4x/java/api/messages/PlcWriteRequest.java | 6 +-
.../base/connection/AbstractPlcConnection.java | 2 +-
.../java/base/connection/PlcFieldHandler.java} | 18 +-
.../java/base/messages/DefaultPlcReadRequest.java | 83 ++++++
.../java/base/messages/DefaultPlcReadResponse.java | 324 +++++++++++++++++++++
.../java/base/messages/DefaultPlcWriteRequest.java | 180 ++++++++++++
.../base/messages/DefaultPlcWriteResponse.java} | 30 +-
.../plc4x/java/base/connection/MockConnection.java | 5 -
.../plc4x/java/base/util/Junit5Backport.java | 1 +
.../plc4x/java/s7/connection/S7PlcConnection.java | 45 ++-
.../org/apache/plc4x/java/s7/model/S7BitField.java | 58 ----
.../plc4x/java/s7/model/S7DataBlockField.java | 57 ----
.../org/apache/plc4x/java/s7/model/S7Field.java | 66 ++++-
.../plc4x/java/s7/netty/Plc4XS7Protocol.java | 13 +-
.../org/apache/plc4x/java/s7/types/S7DataType.java | 37 +--
.../java/s7/connection/S7PlcConnectionTests.java | 2 -
.../apache/plc4x/java/s7/model/S7FieldTests.java | 5 +
.../plc4x/java/s7/netty/Plc4XS7ProtocolTest.java | 2 -
35 files changed, 853 insertions(+), 380 deletions(-)
diff --git a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Constants.java b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Constants.java
index ca9dedd..eefde57 100644
--- a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Constants.java
+++ b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Constants.java
@@ -20,7 +20,8 @@ package org.apache.plc4x.camel;
public class Constants {
- public static final String ADDRESS_HEADER = "address";
+ public static final String FIELD_NAME_HEADER = "fieldName";
+ public static final String FIELD_QUERY_HEADER = "fieldQuery";
private Constants() {
throw new IllegalStateException("Utility class!");
diff --git a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XConsumer.java b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XConsumer.java
index 8ce7dcd..510690a 100644
--- a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XConsumer.java
+++ b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XConsumer.java
@@ -26,31 +26,26 @@ import org.apache.camel.util.AsyncProcessorConverterHelper;
import org.apache.plc4x.java.api.connection.PlcConnection;
import org.apache.plc4x.java.api.connection.PlcSubscriber;
import org.apache.plc4x.java.api.exceptions.PlcException;
-import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
-import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse;
-import org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest;
-import org.apache.plc4x.java.api.messages.items.SubscriptionEventItem;
-import org.apache.plc4x.java.api.messages.items.SubscriptionRequestCyclicItem;
-import org.apache.plc4x.java.api.messages.items.SubscriptionResponseItem;
-import org.apache.plc4x.java.api.messages.items.UnsubscriptionRequestItem;
-import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.api.messages.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util.function.Consumer<SubscriptionEventItem> {
+public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util.function.Consumer<PlcSubscriptionEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(Plc4XConsumer.class);
private Plc4XEndpoint endpoint;
private AsyncProcessor processor;
private ExceptionHandler exceptionHandler;
private PlcConnection plcConnection;
- private PlcField field;
+ private String fieldQuery;
private Class<?> dataType;
private PlcSubscriptionResponse subscriptionResponse;
@@ -62,7 +57,7 @@ public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util
this.exceptionHandler = new LoggingExceptionHandler(endpoint.getCamelContext(), getClass());
String plc4xURI = endpoint.getEndpointUri().replaceFirst("plc4x:/?/?", "");
this.plcConnection = endpoint.getPlcDriverManager().getConnection(plc4xURI);
- this.field = plcConnection.prepareField(endpoint.getAddress());
+ this.fieldQuery = endpoint.getAddress();
}
@Override
@@ -84,22 +79,29 @@ public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util
}
@Override
- protected void doStart() throws InterruptedException, ExecutionException, TimeoutException {
- PlcSubscriptionRequest request = new PlcSubscriptionRequest();
- @SuppressWarnings("unchecked")
- SubscriptionRequestCyclicItem subscriptionRequestCyclicItem = new SubscriptionRequestCyclicItem(dataType, field, TimeUnit.SECONDS, 3, this);
- request.addItem(subscriptionRequestCyclicItem);
+ protected void doStart() throws InterruptedException, ExecutionException, TimeoutException, PlcException {
+ PlcSubscriber plcSubscriber = plcConnection.getSubscriber().orElseThrow(
+ () -> new PlcException("Connection doesn't support subscriptions."));
+ // TODO: Is it correct to only support one field?
+ PlcSubscriptionRequest request = plcSubscriber.subscriptionRequestBuilder()
+ .addCyclicField("default", fieldQuery, Duration.of(3, ChronoUnit.SECONDS)).build();
CompletableFuture<PlcSubscriptionResponse> subscriptionFuture = getSubscriber().subscribe(request);
subscriptionResponse = subscriptionFuture.get(5, TimeUnit.SECONDS);
}
@Override
- protected void doStop() {
- PlcUnsubscriptionRequest request = new PlcUnsubscriptionRequest();
- subscriptionResponse.getResponseItems().stream()
- .map(SubscriptionResponseItem::getSubscriptionHandle)
- .map(UnsubscriptionRequestItem::new)
- .forEach(request::addItem);
+ protected void doStop() throws InterruptedException, ExecutionException, TimeoutException, PlcException {
+ PlcSubscriber plcSubscriber = plcConnection.getSubscriber().orElseThrow(
+ () -> new PlcException("Connection doesn't support subscriptions."));
+ PlcUnsubscriptionRequest.Builder builder = plcSubscriber.unsubscriptionRequestBuilder();
+ // For every field we subscribed for, now unsubscribe.
+ subscriptionResponse.getFieldNames().forEach(fieldName -> {
+ builder.addField(fieldName, subscriptionResponse.getSubscriptionHandle(fieldName));
+ });
+ PlcUnsubscriptionRequest request = builder.build();
+ CompletableFuture<PlcUnsubscriptionResponse> unsubscriptionFuture = plcSubscriber.unsubscribe(request);
+ PlcUnsubscriptionResponse unsubscriptionResponse = unsubscriptionFuture.get(5, TimeUnit.SECONDS);
+ // TODO: Handle the response ...
try {
plcConnection.close();
} catch (Exception e) {
@@ -112,25 +114,25 @@ public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util
}
@Override
- public void accept(SubscriptionEventItem subscriptionEventItem) {
- LOGGER.debug("Received {}", subscriptionEventItem);
+ public void accept(PlcSubscriptionEvent plcSubscriptionEvent) {
+ LOGGER.debug("Received {}", plcSubscriptionEvent);
try {
Exchange exchange = endpoint.createExchange();
- exchange.getIn().setBody(unwrapIfSingle(subscriptionEventItem.getValues()));
+ exchange.getIn().setBody(unwrapIfSingle(plcSubscriptionEvent.getAllObjects("default")));
processor.process(exchange);
} catch (Exception e) {
exceptionHandler.handleException(e);
}
}
- private Object unwrapIfSingle(List list) {
- if (list.isEmpty()) {
+ private Object unwrapIfSingle(Collection collection) {
+ if (collection.isEmpty()) {
return null;
}
- if (list.size() == 1) {
- return list.get(0);
+ if (collection.size() == 1) {
+ return collection.iterator().next();
}
- return list;
+ return collection;
}
}
diff --git a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XPollingConsumer.java b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XPollingConsumer.java
index 57be55e..cb4e548 100644
--- a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XPollingConsumer.java
+++ b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XPollingConsumer.java
@@ -29,11 +29,10 @@ import org.apache.plc4x.java.api.connection.PlcReader;
import org.apache.plc4x.java.api.exceptions.PlcException;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
-import org.apache.plc4x.java.api.model.PlcField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
+import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@@ -45,17 +44,18 @@ public class Plc4XPollingConsumer extends ServiceSupport implements PollingConsu
private Plc4XEndpoint endpoint;
private ExceptionHandler exceptionHandler;
private PlcConnection plcConnection;
- private PlcField field;
+ private PlcReader plcReader;
+ private PlcReadRequest readRequest;
private Class dataType;
-
public Plc4XPollingConsumer(Plc4XEndpoint endpoint) throws PlcException {
this.endpoint = endpoint;
this.dataType = endpoint.getDataType();
this.exceptionHandler = new LoggingExceptionHandler(endpoint.getCamelContext(), getClass());
String plc4xURI = endpoint.getEndpointUri().replaceFirst("plc4x:/?/?", "");
this.plcConnection = endpoint.getPlcDriverManager().getConnection(plc4xURI);
- this.field = plcConnection.prepareField(endpoint.getAddress());
+ this.plcReader = plcConnection.getReader().orElseThrow(() -> new PlcException("This connection doesn't support reading."));
+ readRequest = plcReader.readRequestBuilder().addItem("default", endpoint.getAddress()).build();
}
@Override
@@ -79,10 +79,10 @@ public class Plc4XPollingConsumer extends ServiceSupport implements PollingConsu
@Override
public Exchange receive() {
Exchange exchange = endpoint.createExchange();
- CompletableFuture<? extends PlcReadResponse> read = getReader().read(new PlcReadRequest(dataType, field));
+ CompletableFuture<PlcReadResponse> read = plcReader.read(readRequest);
try {
PlcReadResponse plcReadResponse = read.get();
- exchange.getIn().setBody(unwrapIfSingle(plcReadResponse.getResponseItems()));
+ exchange.getIn().setBody(unwrapIfSingle(plcReadResponse.getAllObjects("default")));
} catch (InterruptedException | ExecutionException e) {
exchange.setException(e);
}
@@ -97,20 +97,16 @@ public class Plc4XPollingConsumer extends ServiceSupport implements PollingConsu
@Override
public Exchange receive(long timeout) {
Exchange exchange = endpoint.createExchange();
- CompletableFuture<? extends PlcReadResponse> read = getReader().read(new PlcReadRequest(dataType, field));
+ CompletableFuture<PlcReadResponse> read = plcReader.read(readRequest);
try {
PlcReadResponse plcReadResponse = read.get(timeout, TimeUnit.MILLISECONDS);
- exchange.getIn().setBody(unwrapIfSingle(plcReadResponse.getResponseItems()));
+ exchange.getIn().setBody(unwrapIfSingle(plcReadResponse.getAllObjects("default")));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
exchange.setException(e);
}
return exchange;
}
- public PlcReader getReader() {
- return plcConnection.getReader().orElseThrow(() -> new RuntimeException("No reader avaiable"));
- }
-
@Override
protected void doStart() {
// We don't seem to need to do anything special here.
@@ -125,14 +121,14 @@ public class Plc4XPollingConsumer extends ServiceSupport implements PollingConsu
}
}
- private Object unwrapIfSingle(List list) {
- if (list.isEmpty()) {
+ private Object unwrapIfSingle(Collection collection) {
+ if (collection.isEmpty()) {
return null;
}
- if (list.size() == 1) {
- return list.get(0);
+ if (collection.size() == 1) {
+ return collection.iterator().next();
}
- return list;
+ return collection;
}
}
diff --git a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XProducer.java b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XProducer.java
index 0995a24..3619d61 100644
--- a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XProducer.java
+++ b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XProducer.java
@@ -27,43 +27,38 @@ import org.apache.plc4x.java.api.connection.PlcWriter;
import org.apache.plc4x.java.api.exceptions.PlcException;
import org.apache.plc4x.java.api.messages.PlcWriteRequest;
import org.apache.plc4x.java.api.messages.PlcWriteResponse;
-import org.apache.plc4x.java.api.messages.items.PlcWriteRequestItem;
-import org.apache.plc4x.java.api.model.PlcField;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
public class Plc4XProducer extends DefaultAsyncProducer {
- @SuppressWarnings("unused")
- private Plc4XEndpoint endpoint;
private PlcConnection plcConnection;
+ private PlcWriter plcWriter;
private AtomicInteger openRequests;
public Plc4XProducer(Plc4XEndpoint endpoint) throws PlcException {
super(endpoint);
- this.endpoint = endpoint;
String plc4xURI = endpoint.getEndpointUri().replaceFirst("plc4x:/?/?", "");
plcConnection = endpoint.getPlcDriverManager().getConnection(plc4xURI);
+ plcWriter = plcConnection.getWriter().orElseThrow(() -> new PlcException("This connection doesn't support writing."));
openRequests = new AtomicInteger();
}
- @SuppressWarnings("unchecked")
@Override
public void process(Exchange exchange) throws Exception {
Message in = exchange.getIn();
- PlcField field = in.getHeader(Constants.ADDRESS_HEADER, PlcField.class);
+ String fieldName = in.getHeader(Constants.FIELD_NAME_HEADER, String.class);
+ String fieldQuery = in.getHeader(Constants.FIELD_QUERY_HEADER, String.class);
Object body = in.getBody();
- PlcWriteRequest.Builder builder = PlcWriteRequest.builder();
+ PlcWriteRequest.Builder builder = plcWriter.writeRequestBuilder();
if (body instanceof List) {
List<?> bodyList = in.getBody(List.class);
- bodyList
- .stream()
- .map(o -> (PlcWriteRequestItem<?>) new PlcWriteRequestItem(o.getClass(), field, o))
- .forEach(builder::addItem);
+ Object[] values = bodyList.toArray();
+ builder.addItem(fieldName, fieldQuery, values);
} else {
Object value = in.getBody(Object.class);
- builder.addItem(field, value);
+ builder.addItem(fieldName, fieldQuery, value);
}
PlcWriter plcWriter = plcConnection.getWriter().orElseThrow(() -> new IllegalArgumentException("Writer for driver not found"));
CompletableFuture<? extends PlcWriteResponse> completableFuture = plcWriter.write(builder.build());
diff --git a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/ResponseItemTypeConverter.java b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/ResponseItemTypeConverter.java
deleted file mode 100644
index 467768c..0000000
--- a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/ResponseItemTypeConverter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-package org.apache.plc4x.camel;
-
-import org.apache.camel.Converter;
-import org.apache.plc4x.java.api.messages.items.PlcReadResponseItem;
-
-import java.util.stream.Collectors;
-
-@Converter
-public class ResponseItemTypeConverter {
-
- @Converter
- public static String toString(PlcReadResponseItem<?> responseItem) {
- return responseItem.getValues().stream().map(String::valueOf).collect(Collectors.joining(","));
- }
-
-}
diff --git a/integrations/apache-camel/src/main/resources/META-INF/services/org/apache/camel/TypeConverter b/integrations/apache-camel/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
deleted file mode 100644
index e1897d1..0000000
--- a/integrations/apache-camel/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-org.apache.plc4x.camel.ResponseItemTypeConverter
\ No newline at end of file
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 06975f3..9e76e2a 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
@@ -154,7 +154,6 @@ public class PlcConnectionAdapter implements AutoCloseable {
PlcField field = null;
try {
connection = getConnection();
- field = connection.prepareField(fieldQuery);
PlcReader reader = connection.getReader()
.orElseThrow(() -> new PlcException("This connection doesn't support reading"));
PlcReadRequest readRequest = reader.readRequestBuilder().addItem(FIELD_NAME, fieldQuery).build();
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 8272b7b..cd903f3 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
@@ -90,28 +90,6 @@ public class PlcConnectionAdapterTest {
adapter.close();
}
- @Test
- @Category(FastTests.class)
- public void testCheckDatatype() {
- 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);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testLongDataTypeIsInvalid() {
- PlcConnectionAdapter.checkDatatype(Long.class);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testDoubleDataTypeIsInvalid() {
- PlcConnectionAdapter.checkDatatype(Double.class);
- }
-
private <T> void checkRead(MockConnection connection, TypeSafePlcReadRequest<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
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 ed60240..0357bfd 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
@@ -70,6 +70,11 @@ public class MockConnection extends org.apache.plc4x.java.base.connection.MockCo
}
@Override
+ public PlcReadRequest.Builder readRequestBuilder() {
+ return null;
+ }
+
+ @Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
curReadCnt++;
if (readExceptionTriggerCount > 0 && curReadCnt == readExceptionTriggerCount) {
@@ -97,6 +102,11 @@ public class MockConnection extends org.apache.plc4x.java.base.connection.MockCo
return CompletableFuture.completedFuture(response);
}
+ @Override
+ public PlcWriteRequest.Builder writeRequestBuilder() {
+ return null;
+ }
+
@SuppressWarnings("unchecked")
@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
index c09c08a..c508217 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
@@ -19,8 +19,6 @@ under the License.
package org.apache.plc4x.java.api.connection;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
-import org.apache.plc4x.java.api.model.PlcField;
import java.util.Optional;
@@ -55,15 +53,6 @@ public interface PlcConnection extends AutoCloseable {
@Override
void close() throws Exception;
- /**
- * Parses a PLC/protocol dependent field string into an PlcField object.
- *
- * @param fieldString String representation of an address for the current type of PLC/protocol.
- * @return PlcField object identifying a field for the current type of PLC/protocol.
- * @throws PlcInvalidFieldException an exception if there was a problem parsing the address string.
- */
- PlcField prepareField(String fieldString) throws PlcInvalidFieldException;
-
Optional<PlcReader> getReader();
Optional<PlcWriter> getWriter();
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcSubscriber.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcSubscriber.java
index a46126d..65ef3f4 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcSubscriber.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcSubscriber.java
@@ -44,8 +44,8 @@ public interface PlcSubscriber {
*/
CompletableFuture<PlcUnsubscriptionResponse> unsubscribe(PlcUnsubscriptionRequest unsubscriptionRequest);
- PlcMessageBuilder<PlcSubscriptionRequest> subsciptionRequestBuilder();
+ PlcSubscriptionRequest.Builder subscriptionRequestBuilder();
- PlcMessageBuilder<PlcUnsubscriptionRequest> unsubsciptionRequestBuilder();
+ PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder();
}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcFieldRequest.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcFieldRequest.java
index f9bd49b..c1b378f 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcFieldRequest.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcFieldRequest.java
@@ -21,16 +21,11 @@ package org.apache.plc4x.java.api.messages;
import org.apache.plc4x.java.api.model.PlcField;
import java.util.Collection;
-import java.util.Map;
public interface PlcFieldRequest extends PlcRequest {
- Map<String, PlcField> getFields();
-
Collection<String> getFieldNames();
PlcField getField(String name);
-
-
}
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 af9d29d..2b9a7d5 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
@@ -23,8 +23,6 @@ package org.apache.plc4x.java.api.messages;
*/
public interface PlcReadRequest extends PlcFieldRequest {
- PlcMessageBuilder<PlcReadRequest> builder();
-
interface Builder extends PlcMessageBuilder<PlcReadRequest> {
Builder addItem(String name, String fieldQuery);
}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionEvent.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionEvent.java
index 30535be..4c333cf 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionEvent.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionEvent.java
@@ -18,6 +18,6 @@ under the License.
*/
package org.apache.plc4x.java.api.messages;
-public interface PlcSubscriptionEvent {
+public interface PlcSubscriptionEvent extends PlcReadResponse {
}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionRequest.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionRequest.java
index 4a501ab..fc95e00 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionRequest.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionRequest.java
@@ -18,8 +18,44 @@ under the License.
*/
package org.apache.plc4x.java.api.messages;
+import java.time.Duration;
+
public interface PlcSubscriptionRequest extends PlcFieldRequest {
PlcMessageBuilder<PlcSubscriptionRequest> builder();
+ interface Builder extends PlcMessageBuilder<PlcSubscriptionRequest> {
+ /**
+ * Adds a new field to the to be constructed request which should be polled cyclically.
+ *
+ * @param name alias of the field.
+ * @param fieldQuery field query string for accessing the field.
+ * @param pollingInterval interval, in which the field should be polled.
+ * @return
+ */
+ PlcSubscriptionRequest.Builder addCyclicField(String name, String fieldQuery, Duration pollingInterval);
+
+ /**
+ * Adds a new field to the to be constructed request which should be updated as soon as
+ * a value changes in the PLC.
+ *
+ * @param name alias of the field.
+ * @param fieldQuery field query string for accessing the field.
+ * @return
+ */
+ PlcSubscriptionRequest.Builder addChangeOfStateField(String name, String fieldQuery);
+
+ /**
+ * Adds a new subscription to the to be constructed request which should be updated
+ * as soon as an event occurs.
+ *
+ * REMARK: We will have to see if this signature is correct as soon as we start using this type of subscription.
+ *
+ * @param name alias of the field.
+ * @param fieldQuery field query string for accessing the field.
+ * @return
+ */
+ PlcSubscriptionRequest.Builder addEventField(String name, String fieldQuery);
+ }
+
}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionResponse.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionResponse.java
index effb1d3..a868e28 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionResponse.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcSubscriptionResponse.java
@@ -18,6 +18,10 @@ under the License.
*/
package org.apache.plc4x.java.api.messages;
+import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
+
public interface PlcSubscriptionResponse extends PlcFieldResponse<PlcSubscriptionRequest> {
+ PlcSubscriptionHandle getSubscriptionHandle(String name);
+
}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcUnsubscriptionRequest.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcUnsubscriptionRequest.java
index e8171f1..57a69b6 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcUnsubscriptionRequest.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcUnsubscriptionRequest.java
@@ -18,7 +18,7 @@ under the License.
*/
package org.apache.plc4x.java.api.messages;
-import java.time.Duration;
+import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
public interface PlcUnsubscriptionRequest extends PlcFieldRequest {
@@ -27,33 +27,10 @@ public interface PlcUnsubscriptionRequest extends PlcFieldRequest {
* Adds a new field to the to be constructed request which should be polled cyclically.
*
* @param name alias of the field.
- * @param fieldQuery field query string for accessing the field.
- * @param pollingInterval interval, in which the field should be polled.
+ * @param handle subscription handle containing information about the subscription.
* @return
*/
- PlcReadRequest.Builder addCyclicField(String name, String fieldQuery, Duration pollingInterval);
-
- /**
- * Adds a new field to the to be constructed request which should be updated as soon as
- * a value changes in the PLC.
- *
- * @param name alias of the field.
- * @param fieldQuery field query string for accessing the field.
- * @return
- */
- PlcReadRequest.Builder addChangeOfStateField(String name, String fieldQuery);
-
- /**
- * Adds a new subscription to the to be constructed request which should be updated
- * as soon as an event occurs.
- *
- * REMARK: We will have to see if this signature is correct as soon as we start using this type of subscription.
- *
- * @param name alias of the field.
- * @param fieldQuery field query string for accessing the field.
- * @return
- */
- PlcReadRequest.Builder addEventField(String name, String fieldQuery);
+ PlcUnsubscriptionRequest.Builder addField(String name, PlcSubscriptionHandle handle);
}
}
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 4d08985..9ead9b0 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,11 +24,13 @@ import java.time.LocalTime;
public interface PlcWriteRequest extends PlcFieldRequest {
+ byte[][] getValues(String name);
+
interface Builder extends PlcMessageBuilder<PlcWriteRequest> {
- PlcReadRequest.Builder addItem(String name, String fieldQuery, byte[]... values);
+ PlcWriteRequest.Builder addItem(String name, String fieldQuery, byte[]... values);
- PlcReadRequest.Builder addItem(String name, String fieldQuery, Object... values);
+ PlcWriteRequest.Builder addItem(String name, String fieldQuery, Object... values);
PlcWriteRequest.Builder addItem(String name, String fieldQuery, Boolean... values);
diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java
index eee3f02..bb1b11f 100644
--- a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java
@@ -101,7 +101,7 @@ public abstract class AbstractPlcConnection implements PlcConnection {
}
@Override
- public Optional<PlcReader> getReader() {
+ public Optional<PlcReader>getReader() {
if (this instanceof PlcReader) {
return Optional.of((PlcReader) this);
}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcFieldRequest.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/PlcFieldHandler.java
similarity index 63%
copy from plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcFieldRequest.java
copy to plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/PlcFieldHandler.java
index f9bd49b..7bfc80b 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcFieldRequest.java
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/PlcFieldHandler.java
@@ -16,21 +16,17 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
-package org.apache.plc4x.java.api.messages;
+package org.apache.plc4x.java.base.connection;
+import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.api.types.PlcClientDatatype;
-import java.util.Collection;
-import java.util.Map;
-
-public interface PlcFieldRequest extends PlcRequest {
-
- Map<String, PlcField> getFields();
-
- Collection<String> getFieldNames();
-
- PlcField getField(String name);
+public interface PlcFieldHandler {
+ PlcField createField(String fieldQuery) throws PlcInvalidFieldException;
+ byte[][] encode(PlcField field, PlcClientDatatype clientDatatype, Object[] values);
+ Object[] decode(PlcField field, PlcClientDatatype clientDatatype, byte[][] rawData);
}
diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadRequest.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadRequest.java
new file mode 100644
index 0000000..a330097
--- /dev/null
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadRequest.java
@@ -0,0 +1,83 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.java.base.messages;
+
+import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.base.connection.PlcFieldHandler;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class DefaultPlcReadRequest implements PlcReadRequest {
+
+ private Map<String, PlcField> fields;
+
+ private DefaultPlcReadRequest() {
+ this.fields = new TreeMap<>();
+ }
+
+ private DefaultPlcReadRequest(Map<String, PlcField> fields) {
+ this.fields = fields;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return fields.keySet();
+ }
+
+ @Override
+ public PlcField getField(String name) {
+ return fields.get(name);
+ }
+
+ public static class DefaultPlcReadRequestBuilder implements PlcReadRequest.Builder {
+
+ private final PlcFieldHandler fieldHandler;
+ private final Map<String, String> fields;
+
+ public DefaultPlcReadRequestBuilder(PlcFieldHandler fieldHandler) {
+ this.fieldHandler = fieldHandler;
+ fields = new TreeMap<>();
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery) {
+ if(fields.containsKey(name)) {
+ throw new PlcRuntimeException("Duplicate field definition '" + name + "'");
+ }
+ fields.put(name, fieldQuery);
+ return this;
+ }
+
+ @Override
+ public PlcReadRequest build() {
+ Map<String, PlcField> parsedFields = new TreeMap<>();
+ fields.forEach((name, fieldQuery) -> {
+ PlcField parsedField = fieldHandler.createField(fieldQuery);
+ parsedFields.put(name, parsedField);
+ });
+ return new DefaultPlcReadRequest(parsedFields);
+ }
+
+ }
+
+}
diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadResponse.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadResponse.java
new file mode 100644
index 0000000..7053220
--- /dev/null
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadResponse.java
@@ -0,0 +1,324 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.java.base.messages;
+
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.api.types.PlcResponseCode;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Collection;
+import java.util.Map;
+
+public class DefaultPlcReadResponse implements PlcReadResponse {
+
+ @Override
+ public int getNumValues(String name) {
+ return 0;
+ }
+
+ @Override
+ public boolean isRaw(String name) {
+ return false;
+ }
+
+ @Override
+ public byte[] getRaw(String name) {
+ return new byte[0];
+ }
+
+ @Override
+ public byte[] getRaw(String name, int index) {
+ return new byte[0];
+ }
+
+ @Override
+ public Collection<byte[]> getAllRaws(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isObject(String name) {
+ return false;
+ }
+
+ @Override
+ public Object getObject(String name) {
+ return null;
+ }
+
+ @Override
+ public Object getObject(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<Object> getAllObjects(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isBoolean(String name) {
+ return false;
+ }
+
+ @Override
+ public Boolean getBoolean(String name) {
+ return null;
+ }
+
+ @Override
+ public Boolean getBoolean(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<Boolean> getAllBooleans(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isByte(String name) {
+ return false;
+ }
+
+ @Override
+ public Byte getByte(String name) {
+ return null;
+ }
+
+ @Override
+ public Byte getByte(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<Byte> getAllBytes(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isShort(String name) {
+ return false;
+ }
+
+ @Override
+ public Short getShort(String name) {
+ return null;
+ }
+
+ @Override
+ public Short getShort(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<Short> getAllShorts(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isInteger(String name) {
+ return false;
+ }
+
+ @Override
+ public Integer getInteger(String name) {
+ return null;
+ }
+
+ @Override
+ public Integer getInteger(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<Integer> getAllIntegers(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isLong(String name) {
+ return false;
+ }
+
+ @Override
+ public Long getLong(String name) {
+ return null;
+ }
+
+ @Override
+ public Long getLong(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<Long> getAllLongs(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isFloat(String name) {
+ return false;
+ }
+
+ @Override
+ public Float getFloat(String name) {
+ return null;
+ }
+
+ @Override
+ public Float getFloat(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<Float> getAllFloats(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isDouble(String name) {
+ return false;
+ }
+
+ @Override
+ public Double getDouble(String name) {
+ return null;
+ }
+
+ @Override
+ public Double getDouble(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<Double> getAllDoubles(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isString(String name) {
+ return false;
+ }
+
+ @Override
+ public String getString(String name) {
+ return null;
+ }
+
+ @Override
+ public String getString(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getAllStrings(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isTime(String name) {
+ return false;
+ }
+
+ @Override
+ public LocalTime getTime(String name) {
+ return null;
+ }
+
+ @Override
+ public LocalTime getTime(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<LocalTime> getAllTimes(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isDate(String name) {
+ return false;
+ }
+
+ @Override
+ public LocalDate getDate(String name) {
+ return null;
+ }
+
+ @Override
+ public LocalDate getDate(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<LocalDate> getAllDates(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isDateTime(String name) {
+ return false;
+ }
+
+ @Override
+ public LocalDateTime getDateTime(String name) {
+ return null;
+ }
+
+ @Override
+ public LocalDateTime getDateTime(String name, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<LocalDateTime> getAllDateTimes(String name) {
+ return null;
+ }
+
+ @Override
+ public Map<String, PlcField> getFields() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return null;
+ }
+
+ @Override
+ public PlcField getField(String name) {
+ return null;
+ }
+
+ @Override
+ public PlcResponseCode getResponseCode(String name) {
+ return null;
+ }
+
+ @Override
+ public PlcReadRequest getRequest() {
+ return null;
+ }
+
+}
diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java
new file mode 100644
index 0000000..d060218
--- /dev/null
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java
@@ -0,0 +1,180 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.java.base.messages;
+
+import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.api.types.PlcClientDatatype;
+import org.apache.plc4x.java.base.connection.PlcFieldHandler;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class DefaultPlcWriteRequest implements PlcWriteRequest {
+
+ private final Map<String, Item> fields;
+
+ private DefaultPlcWriteRequest(Map<String, Item> fields) {
+ this.fields = fields;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return fields.keySet();
+ }
+
+ @Override
+ public PlcField getField(String name) {
+ return fields.get(name).field;
+ }
+
+ @Override
+ public byte[][] getValues(String name) {
+ return fields.get(name).values;
+ }
+
+ public static class Builder implements PlcWriteRequest.Builder {
+
+ private final PlcFieldHandler fieldHandler;
+ private final Map<String, BuilderItem> fields;
+
+ public Builder(PlcFieldHandler fieldHandler) {
+ this.fieldHandler = fieldHandler;
+ fields = new TreeMap<>();
+ }
+
+ @Override
+ public PlcWriteRequest.Builder addItem(String name, String fieldQuery, byte[]... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.RAW);
+ }
+
+ @Override
+ public PlcWriteRequest.Builder addItem(String name, String fieldQuery, Object... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.OBJECT);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, Boolean... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.BOOLEAN);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, Byte... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.BYTE);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, Short... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.SHORT);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, Integer... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.INTEGER);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, Long... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.LONG);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, Float... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.FLOAT);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, Double... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.DOUBLE);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, String... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.STRING);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, LocalTime... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.TIME);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, LocalDate... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.DATE);
+ }
+
+ @Override
+ public Builder addItem(String name, String fieldQuery, LocalDateTime... values) {
+ return addItem(name, fieldQuery, values, PlcClientDatatype.DATE_TIME);
+ }
+
+ @Override
+ public PlcWriteRequest build() {
+ Map<String, DefaultPlcWriteRequest.Item> parsedFields = new TreeMap<>();
+ fields.forEach((name, builderItem) -> {
+ // Compile the query string.
+ PlcField parsedField = fieldHandler.createField(builderItem.fieldQuery);
+ // Encode the payload.
+ byte[][] rawData = fieldHandler.encode(parsedField, builderItem.clientDatatype, builderItem.values);
+ parsedFields.put(name, new DefaultPlcWriteRequest.Item(parsedField, rawData));
+ });
+ return new DefaultPlcWriteRequest(parsedFields);
+ }
+
+ private Builder addItem(String name, String fieldQuery, Object[] values, PlcClientDatatype clientDatatype) {
+ if(fields.containsKey(name)) {
+ throw new PlcRuntimeException("Duplicate field definition '" + name + "'");
+ }
+ fields.put(name, new BuilderItem(fieldQuery, clientDatatype, values));
+ return this;
+ }
+
+ private static class BuilderItem {
+
+ private final String fieldQuery;
+ private final PlcClientDatatype clientDatatype;
+ private final Object[] values;
+
+ private BuilderItem(String fieldQuery, PlcClientDatatype clientDatatype, Object[] values) {
+ this.fieldQuery = fieldQuery;
+ this.clientDatatype = clientDatatype;
+ this.values = values;
+ }
+ }
+
+ }
+
+ private static class Item {
+
+ private final PlcField field;
+ private final byte[][] values;
+
+ private Item(PlcField field, byte[][] values) {
+ this.field = field;
+ this.values = values;
+ }
+
+ }
+
+}
diff --git a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteResponse.java
similarity index 57%
copy from plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java
copy to plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteResponse.java
index f8897f7..ef1fd87 100644
--- a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteResponse.java
@@ -16,30 +16,40 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
-package org.apache.plc4x.java.base.connection;
+package org.apache.plc4x.java.base.messages;
-import io.netty.channel.ChannelHandler;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteResponse;
import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.api.types.PlcResponseCode;
-import java.util.concurrent.CompletableFuture;
+import java.util.Collection;
+import java.util.Map;
-public class MockConnection extends AbstractPlcConnection {
+public class DefaultPlcWriteResponse implements PlcWriteResponse {
- public MockConnection() {
- super(new TestChannelFactory());
+ @Override
+ public Map<String, PlcField> getFields() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return null;
}
- public MockConnection(boolean awaitSessionSetupComplete) {
- super(new TestChannelFactory(), awaitSessionSetupComplete);
+ @Override
+ public PlcField getField(String name) {
+ return null;
}
@Override
- protected ChannelHandler getChannelHandler(CompletableFuture<Void> sessionSetupCompleteFuture) {
+ public PlcResponseCode getResponseCode(String name) {
return null;
}
@Override
- public PlcField prepareField(String fieldString) {
+ public PlcWriteRequest getRequest() {
return null;
}
diff --git a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java b/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java
index f8897f7..3c64768 100644
--- a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java
+++ b/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java
@@ -38,9 +38,4 @@ public class MockConnection extends AbstractPlcConnection {
return null;
}
- @Override
- public PlcField prepareField(String fieldString) {
- return null;
- }
-
}
diff --git a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/util/Junit5Backport.java b/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/util/Junit5Backport.java
index 811df2f..84e6f26 100644
--- a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/util/Junit5Backport.java
+++ b/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/util/Junit5Backport.java
@@ -37,4 +37,5 @@ public class Junit5Backport {
public interface Acceptor<T extends Exception> {
void accept() throws T;
}
+
}
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
index 13ff259..86b7a7d 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.java.s7.connection;
import io.netty.channel.*;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.SystemConfiguration;
+import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.apache.plc4x.java.api.connection.PlcReader;
import org.apache.plc4x.java.api.connection.PlcWriter;
@@ -31,11 +32,15 @@ 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.model.PlcField;
+import org.apache.plc4x.java.api.types.PlcClientDatatype;
import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
import org.apache.plc4x.java.base.connection.ChannelFactory;
+import org.apache.plc4x.java.base.connection.PlcFieldHandler;
import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
import org.apache.plc4x.java.base.events.ConnectEvent;
import org.apache.plc4x.java.base.events.ConnectedEvent;
+import org.apache.plc4x.java.base.messages.DefaultPlcReadRequest;
+import org.apache.plc4x.java.base.messages.DefaultPlcWriteRequest;
import org.apache.plc4x.java.base.messages.PlcRequestContainer;
import org.apache.plc4x.java.isoontcp.netty.IsoOnTcpProtocol;
import org.apache.plc4x.java.isotp.netty.IsoTPProtocol;
@@ -43,8 +48,6 @@ import org.apache.plc4x.java.isotp.netty.model.tpdus.DisconnectRequestTpdu;
import org.apache.plc4x.java.isotp.netty.model.types.DeviceGroup;
import org.apache.plc4x.java.isotp.netty.model.types.DisconnectReason;
import org.apache.plc4x.java.isotp.netty.model.types.TpduSize;
-import org.apache.plc4x.java.s7.model.S7BitField;
-import org.apache.plc4x.java.s7.model.S7DataBlockField;
import org.apache.plc4x.java.s7.model.S7Field;
import org.apache.plc4x.java.s7.netty.Plc4XS7Protocol;
import org.apache.plc4x.java.s7.netty.S7Protocol;
@@ -78,7 +81,7 @@ import java.util.concurrent.TimeoutException;
* where the {bit-offset} is optional.
* All Available Memory Areas for this mode are defined in the {@link MemoryArea} enum.
*/
-public class S7PlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
+public class S7PlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter, PlcFieldHandler {
private static final int ISO_ON_TCP_PORT = 102;
@@ -241,17 +244,32 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
}
@Override
- public PlcField prepareField(String fieldString) throws PlcInvalidFieldException {
- if(S7DataBlockField.matches(fieldString)) {
- return S7DataBlockField.of(fieldString);
+ public PlcField createField(String fieldQuery) throws PlcInvalidFieldException {
+ if(S7DataBlockField.matches(fieldQuery)) {
+ return S7DataBlockField.of(fieldQuery);
}
- if(S7BitField.matches(fieldString)) {
- return S7BitField.of(fieldString);
+ if(S7BitField.matches(fieldQuery)) {
+ return S7BitField.of(fieldQuery);
}
- if(S7Field.matches(fieldString)) {
- return S7Field.of(fieldString);
+ if(S7Field.matches(fieldQuery)) {
+ return S7Field.of(fieldQuery);
}
- throw new PlcInvalidFieldException(fieldString);
+ throw new PlcInvalidFieldException(fieldQuery);
+ }
+
+ @Override
+ public byte[][] encode(PlcField field, PlcClientDatatype clientDatatype, Object[] values) {
+ throw new NotImplementedException("Not implemented ...");
+ }
+
+ @Override
+ public Object[] decode(PlcField field, PlcClientDatatype clientDatatype, byte[][] rawData) {
+ throw new NotImplementedException("Not implemented ...");
+ }
+
+ @Override
+ public PlcReadRequest.Builder readRequestBuilder() {
+ return new DefaultPlcReadRequest.DefaultPlcReadRequestBuilder(this);
}
@Override
@@ -266,6 +284,11 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
}
@Override
+ public PlcWriteRequest.Builder writeRequestBuilder() {
+ return new DefaultPlcWriteRequest.Builder(this);
+ }
+
+ @Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
CompletableFuture<PlcWriteResponse> future = new CompletableFuture<>();
PlcRequestContainer<PlcWriteRequest, PlcWriteResponse> container =
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7BitField.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7BitField.java
deleted file mode 100644
index 27a9d5e..0000000
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7BitField.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-package org.apache.plc4x.java.s7.model;
-
-import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
-import org.apache.plc4x.java.s7.netty.model.types.MemoryArea;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class S7BitField extends S7Field {
-
- private static final Pattern ADDRESS_PATTERN =
- Pattern.compile("^(?<memoryArea>.*?)/(?<byteOffset>\\d{1,4})/(?<bitOffset>\\d)");
-
- public static boolean matches(String addressString) {
- return ADDRESS_PATTERN.matcher(addressString).matches();
- }
-
- public static S7BitField of(String fieldString) throws PlcInvalidFieldException {
- Matcher matcher = ADDRESS_PATTERN.matcher(fieldString);
- if (!matcher.matches()) {
- throw new PlcInvalidFieldException(fieldString, ADDRESS_PATTERN);
- }
- MemoryArea memoryArea = MemoryArea.valueOf(matcher.group("memoryArea"));
- short byteOffset = Short.parseShort(matcher.group("byteOffset"));
- byte bitOffset = Byte.valueOf(matcher.group("bitOffset"));
- return new S7BitField(memoryArea, byteOffset, bitOffset);
- }
-
- private final byte bitOffset;
-
- public S7BitField(MemoryArea memoryArea, short byteOffset, byte bitOffset) {
- super(memoryArea, byteOffset);
- this.bitOffset = bitOffset;
- }
-
- public byte getBitOffset() {
- return bitOffset;
- }
-
-}
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7DataBlockField.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7DataBlockField.java
deleted file mode 100644
index 12526ab..0000000
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7DataBlockField.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-package org.apache.plc4x.java.s7.model;
-
-import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
-import org.apache.plc4x.java.s7.netty.model.types.MemoryArea;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class S7DataBlockField extends S7Field {
-
- private static final Pattern ADDRESS_PATTERN =
- Pattern.compile("^DATA_BLOCKS/(?<blockNumber>\\d{1,4})/(?<byteOffset>\\d{1,4})");
-
- public static boolean matches(String fieldString) {
- return ADDRESS_PATTERN.matcher(fieldString).matches();
- }
-
- public static S7DataBlockField of(String fieldString) throws PlcInvalidFieldException {
- Matcher matcher = ADDRESS_PATTERN.matcher(fieldString);
- if (!matcher.matches()) {
- throw new PlcInvalidFieldException(fieldString, ADDRESS_PATTERN);
- }
- int datablockNumber = Integer.parseInt(matcher.group("blockNumber"));
- int datablockByteOffset = Integer.parseInt(matcher.group("byteOffset"));
- return new S7DataBlockField((short) datablockNumber, (short) datablockByteOffset);
- }
-
- private final short dataBlockNumber;
-
- public S7DataBlockField(short dataBlockNumber, short byteOffset) {
- super(MemoryArea.DATA_BLOCKS, byteOffset);
- this.dataBlockNumber = dataBlockNumber;
- }
-
- public short getDataBlockNumber() {
- return dataBlockNumber;
- }
-
-}
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
index 620c057..20b12d6 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
@@ -21,35 +21,79 @@ package org.apache.plc4x.java.s7.model;
import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
import org.apache.plc4x.java.api.model.PlcField;
import org.apache.plc4x.java.s7.netty.model.types.MemoryArea;
+import org.apache.plc4x.java.s7.types.S7DataType;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class S7Field implements PlcField {
+ // %I0.1:BOOL <-- Digital Input
+ // %IW64:REAL <-- Analog Input
+ // %Q0.4:BOOL <-- Digital Output
+ // %DB1.DBX38.1:BOOL <-- Memory block DB1
+
private static final Pattern ADDRESS_PATTERN =
- Pattern.compile("^(?<memoryArea>.*?)/(?<byteOffset>\\d{1,4})?");
+ Pattern.compile("^%(?<memoryArea>.)(?<transferSizeCode>.?)(?<byteOffset>\\d{1,4})(.(?<bitOffset>[0-7]))?:(?<dataType>.+)");
+ private static final Pattern DATA_BLOCK_ADDRESS_PATTERN =
+ Pattern.compile("^%DB(?<blockNumber>\\d{1,4}).DB(?<transferSizeCode>.?)(?<byteOffset>\\d{1,4})(.(?<bitOffset>[0-7]))?:(?<dataType>.+)");
public static boolean matches(String fieldString) {
- return ADDRESS_PATTERN.matcher(fieldString).matches();
+ return DATA_BLOCK_ADDRESS_PATTERN.matcher(fieldString).matches() ||
+ ADDRESS_PATTERN.matcher(fieldString).matches();
}
public static S7Field of(String fieldString) throws PlcInvalidFieldException {
- Matcher matcher = ADDRESS_PATTERN.matcher(fieldString);
- if (!matcher.matches()) {
- throw new PlcInvalidFieldException(fieldString, ADDRESS_PATTERN);
+ Matcher matcher = DATA_BLOCK_ADDRESS_PATTERN.matcher(fieldString);
+ if(matcher.matches()) {
+ S7DataType dataType = S7DataType.valueOf(matcher.group("dataType"));
+ String transferSizeCode = matcher.group("transferSizeCode");
+ if(!transferSizeCode.isEmpty() && !dataType.getSizeCode().equals(transferSizeCode)) {
+ throw new PlcInvalidFieldException("Transfer size code '" + transferSizeCode +
+ "' doesn't match specified data type '" + dataType.name() + "'");
+ }
+ MemoryArea memoryArea = MemoryArea.INSTANCE_DATA_BLOCKS;
+ short byteOffset = Short.parseShort(matcher.group("byteOffset"));
+ short bitOffset = 0;
+ if(matcher.group("bitOffset") != null) {
+ bitOffset = Short.parseShort(matcher.group("bitOffset"));
+ }
+ return new S7Field(dataType, memoryArea, byteOffset, bitOffset);
+ } else {
+ matcher = ADDRESS_PATTERN.matcher(fieldString);
+ if (matcher.matches()) {
+ S7DataType dataType = S7DataType.valueOf(matcher.group("dataType"));
+ String transferSizeCode = matcher.group("transferSizeCode");
+ if(!transferSizeCode.isEmpty() && !dataType.getSizeCode().equals(transferSizeCode)) {
+ throw new PlcInvalidFieldException("Transfer size code '" + transferSizeCode +
+ "' doesn't match specified data type '" + dataType.name() + "'");
+ }
+ MemoryArea memoryArea = MemoryArea.valueOf(matcher.group("memoryArea"));
+ short byteOffset = Short.parseShort(matcher.group("byteOffset"));
+ short bitOffset = 0;
+ if(matcher.group("bitOffset") != null) {
+ bitOffset = Short.parseShort(matcher.group("bitOffset"));
+ }
+ return new S7Field(dataType, memoryArea, byteOffset, bitOffset);
+ }
}
- MemoryArea memoryArea = MemoryArea.valueOf(matcher.group("memoryArea"));
- short byteOffset = Short.parseShort(matcher.group("byteOffset"));
- return new S7Field(memoryArea, byteOffset);
+ throw new PlcInvalidFieldException("Unable to parse address: " + fieldString);
}
+ private final S7DataType dataType;
private final MemoryArea memoryArea;
private final short byteOffset;
+ private final short bitOffset;
- public S7Field(MemoryArea memoryArea, short byteOffset) {
+ public S7Field(S7DataType dataType, MemoryArea memoryArea, short byteOffset, short bitOffset) {
+ this.dataType = dataType;
this.memoryArea = memoryArea;
this.byteOffset = byteOffset;
+ this.bitOffset = bitOffset;
+ }
+
+ public S7DataType getDataType() {
+ return dataType;
}
public MemoryArea getMemoryArea() {
@@ -60,4 +104,8 @@ public class S7Field implements PlcField {
return byteOffset;
}
+ public short getBitOffset() {
+ return bitOffset;
+ }
+
}
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 b4a3a8b..88f56e4 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
@@ -34,9 +34,7 @@ import org.apache.plc4x.java.api.types.PlcResponseCode;
import org.apache.plc4x.java.base.PlcMessageToMessageCodec;
import org.apache.plc4x.java.base.events.ConnectedEvent;
import org.apache.plc4x.java.base.messages.PlcRequestContainer;
-import org.apache.plc4x.java.s7.model.S7DataBlockField;
import org.apache.plc4x.java.s7.model.S7Field;
-import org.apache.plc4x.java.s7.model.S7BitField;
import org.apache.plc4x.java.s7.netty.events.S7ConnectedEvent;
import org.apache.plc4x.java.s7.netty.model.messages.S7Message;
import org.apache.plc4x.java.s7.netty.model.messages.S7RequestMessage;
@@ -168,10 +166,17 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
List<VarPayloadItem> payloadItems = new LinkedList<>();
PlcWriteRequest writeRequest = (PlcWriteRequest) msg.getRequest();
- for (PlcWriteRequestItem requestItem : writeRequest.getRequestItems()) {
+ for (String fieldName : writeRequest.getFieldNames()) {
+ PlcField field = writeRequest.getField(fieldName);
+ if(!(field instanceof S7Field)) {
+ throw new PlcException("The field should have been of type S7Field");
+ }
+
+ S7Field s7Field = (S7Field) field;
+
// Try to get the correct S7 transport size for the given data type.
// (Map PLC4X data type to S7 data type)
- TransportSize transportSize = encodeTransportSize(requestItem.getDatatype());
+ TransportSize transportSize = encodeTransportSize(s7Field.getDatatype());
if (transportSize == null) {
throw new PlcException("Unknown transport size for datatype " + requestItem.getDatatype());
}
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/types/S7DataType.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/types/S7DataType.java
index a5f8fae..30b40a6 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/types/S7DataType.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/types/S7DataType.java
@@ -117,39 +117,32 @@ public enum S7DataType {
* that matches the provided size-code.
* - If a sub-type was provided, all we do, is check if the size-code matches
*
- * @param javaType java type used in the request item
* @param s7Type type or sub-type provided (optional)
* @param sizeCode size-code provided (optional)
* @return best matching type.
* @throws IllegalArgumentException no type with matching type and size-code was found.
*/
- static S7DataType findMatchingType(Class<?> javaType, S7DataType s7Type, String sizeCode) throws IllegalArgumentException {
+ public static S7DataType findMatchingType(S7DataType s7Type, String sizeCode) throws IllegalArgumentException {
assert s7Type != null;
- if (javaType != null) {
-
- if (sizeCode != null) {
- // If this is a base type, we will try to check if we can select a better fitting sub-type.
- if (s7Type.isBaseType()) {
- S7DataType subType = s7Type.getSubType(sizeCode);
- if (subType == null) {
- throw new IllegalArgumentException(String.format(
- "Selected base type %s does not have a sub-type for provided size code %s", s7Type, sizeCode));
- }
- s7Type = subType;
+ if (sizeCode != null) {
+ // If this is a base type, we will try to check if we can select a better fitting sub-type.
+ if (s7Type.isBaseType()) {
+ S7DataType subType = s7Type.getSubType(sizeCode);
+ if (subType == null) {
+ throw new IllegalArgumentException(String.format(
+ "Selected base type %s does not have a sub-type for provided size code %s", s7Type, sizeCode));
}
- // If this is not a base type, we have to check if the sizeCode matches the selected sub-type.
- else {
- if (!s7Type.getSizeCode().equals(sizeCode)) {
- throw new IllegalArgumentException(
- String.format("Selected data type %s does not match provided size code %s", s7Type, sizeCode));
- }
+ s7Type = subType;
+ }
+ // If this is not a base type, we have to check if the sizeCode matches the selected sub-type.
+ else {
+ if (!s7Type.getSizeCode().equals(sizeCode)) {
+ throw new IllegalArgumentException(
+ String.format("Selected data type %s does not match provided size code %s", s7Type, sizeCode));
}
}
-
}
- // TODO: Check compatibility with the java-type.
- return s7Type;
}
}
\ No newline at end of file
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionTests.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionTests.java
index 883001b..235644a 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionTests.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionTests.java
@@ -22,9 +22,7 @@ package org.apache.plc4x.java.s7.connection;
import org.apache.plc4x.java.api.exceptions.PlcException;
import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
import org.apache.plc4x.java.isotp.netty.model.types.TpduSize;
-import org.apache.plc4x.java.s7.model.S7DataBlockField;
import org.apache.plc4x.java.s7.model.S7Field;
-import org.apache.plc4x.java.s7.model.S7BitField;
import org.apache.plc4x.java.s7.netty.model.types.MemoryArea;
import org.junit.After;
import org.junit.Before;
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/model/S7FieldTests.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/model/S7FieldTests.java
index d7738dd..deddabc 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/model/S7FieldTests.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/model/S7FieldTests.java
@@ -29,6 +29,11 @@ import static org.junit.Assert.assertThat;
public class S7FieldTests {
+ // %I0.1:BOOL <-- Digital Input
+ // %IW64:REAL <-- Analog Input
+ // %Q0.4:BOOL <-- Digital Output
+ // %DB1.DBX38.1:BOOL <-- Memory block DB1
+
@Test
@Category(FastTests.class)
public void testS7Field() {
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java
index c86152e..4efaff0 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java
@@ -25,8 +25,6 @@ import org.apache.plc4x.java.api.messages.specific.TypeSafePlcReadRequest;
import org.apache.plc4x.java.api.messages.specific.TypeSafePlcWriteRequest;
import org.apache.plc4x.java.base.messages.PlcRequestContainer;
import org.apache.plc4x.java.netty.NettyTestBase;
-import org.apache.plc4x.java.s7.model.S7BitField;
-import org.apache.plc4x.java.s7.model.S7DataBlockField;
import org.apache.plc4x.java.s7.model.S7Field;
import org.apache.plc4x.java.s7.netty.model.messages.S7ResponseMessage;
import org.apache.plc4x.java.s7.netty.model.params.VarParameter;