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/14 14:33:35 UTC
[incubator-plc4x] 01/02: Created a first version of a S7DataType
enum to help with the TIA portal type addresses.
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git
commit d2035b3e9d00b53e13b709d65a55c599c01a222d
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Tue Aug 14 13:14:40 2018 +0200
Created a first version of a S7DataType enum to help with the TIA portal type addresses.
---
.../plc4x/java/s7/types/S7ControllerType.java | 29 ++++
.../org/apache/plc4x/java/s7/types/S7DataType.java | 155 +++++++++++++++++++++
.../apache/plc4x/java/s7/types/S7DataTypeTest.java | 57 ++++++++
3 files changed, 241 insertions(+)
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/types/S7ControllerType.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/types/S7ControllerType.java
new file mode 100644
index 0000000..d8c68c7
--- /dev/null
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/types/S7ControllerType.java
@@ -0,0 +1,29 @@
+/*
+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.types;
+
+public enum S7ControllerType {
+
+ S7_ANY,
+ S7_300,
+ S7_400,
+ S7_1200,
+ S7_1500
+
+}
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
new file mode 100644
index 0000000..a5f8fae
--- /dev/null
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/types/S7DataType.java
@@ -0,0 +1,155 @@
+/*
+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.types;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public enum S7DataType {
+
+ /**
+ * TODO: For the types with code 0x00 we need to put some additional effort in reverse engineering the codes for these types.
+ */
+ BOOL(0x01, "X", null, S7ControllerType.S7_ANY),
+
+ BYTE(0x02, "B", null, S7ControllerType.S7_ANY),
+
+ CHAR(0x03, "B", null, S7ControllerType.S7_ANY),
+
+ WORD(0x04, "W", null, S7ControllerType.S7_ANY),
+ DWORD(0x06, "D", WORD, S7ControllerType.S7_ANY),
+ // Only got a basic TIA license (S7-1500 needed to find this out)
+ LWORD(0x00, null, null, S7ControllerType.S7_1200, S7ControllerType.S7_1500),
+
+ INT(0x05, "W", null, S7ControllerType.S7_ANY),
+ // Double Precision Int
+ DINT(0x07, "D", INT, S7ControllerType.S7_ANY),
+ // Unsigned Small Int
+ USINT(0x00, "B", INT, S7ControllerType.S7_1200, S7ControllerType.S7_1500),
+ // (Signed) Small Int
+ SINT(0x00, "B", INT, S7ControllerType.S7_1200, S7ControllerType.S7_1500),
+ // Unsigned Int
+ UINT(0x00, "W", INT, S7ControllerType.S7_1200, S7ControllerType.S7_1500),
+ // Unsigned Double Precision Int
+ UDINT(0x00, "D", INT, S7ControllerType.S7_1200, S7ControllerType.S7_1500),
+ // Only got a basic TIA license (S7-1500 needed to find this out)
+ UDLINT(0x00, null, INT, S7ControllerType.S7_1500),
+ // Only got a basic TIA license (S7-1500 needed to find this out)
+ LINT(0x00, null, INT, S7ControllerType.S7_1500),
+
+ REAL(0x08, "D", null, S7ControllerType.S7_ANY),
+ // Ok ... this is strange ...
+ LREAL(0x00, "X", REAL, S7ControllerType.S7_1200, S7ControllerType.S7_1500);
+
+ /* TO BE CONTINUED */
+
+ private byte typeCode;
+ private String sizeCode;
+ private Set<S7ControllerType> supportedControllerTypes;
+ private S7DataType baseType;
+
+ S7DataType(int typeCode, String sizeCode, S7DataType baseType, S7ControllerType... supportedControllerTypes) {
+ this.typeCode = (byte) typeCode;
+ this.sizeCode = sizeCode;
+ this.supportedControllerTypes = new HashSet<>(Arrays.asList(supportedControllerTypes));
+ this.baseType = baseType;
+ }
+
+ byte getTypeCode() {
+ return typeCode;
+ }
+
+ public String getSizeCode() {
+ return sizeCode;
+ }
+
+ boolean isBaseType() {
+ return baseType == null;
+ }
+
+ S7DataType getBaseType() {
+ // If this is a base-type itself, the baseType is null, in all
+ // other cases it is set.
+ if (baseType == null) {
+ return this;
+ } else {
+ return baseType;
+ }
+ }
+
+ S7DataType getSubType(String sizeCode) {
+ // Try to find a sub-type with this base type for which the size code matches.
+ for (S7DataType value : values()) {
+ if ((value.baseType == this) && (value.sizeCode != null) && (value.sizeCode.equals(sizeCode))) {
+ return value;
+ }
+ }
+ return null;
+ }
+
+ boolean isControllerTypeSupported(S7ControllerType controllerType) {
+ return supportedControllerTypes.contains(controllerType);
+ }
+
+ /**
+ * This finder method tries to find the correct sub-type for given input.
+ * The algorithm how types are selected is the following:
+ * - If the user provided just a type and no size-code, this type is returned.
+ * - If the user provided a base-type and a size-code, then the algorithm first checks if maybe the base-type
+ * was intentionally requested. Otherwise all sub-types for the same base-type are scanned in search for one
+ * 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 {
+ 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 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/types/S7DataTypeTest.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/types/S7DataTypeTest.java
new file mode 100644
index 0000000..3b22728
--- /dev/null
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/types/S7DataTypeTest.java
@@ -0,0 +1,57 @@
+/*
+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.types;
+
+import org.apache.plc4x.test.FastTests;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+public class S7DataTypeTest {
+
+ @Test
+ @Category(FastTests.class)
+ public void findMatchingTypeRedundantInformation() {
+ S7DataType result = S7DataType.findMatchingType(Integer.class, S7DataType.UINT, "W");
+ assertThat(result, equalTo(S7DataType.UINT));
+ }
+
+ @Test
+ @Category(FastTests.class)
+ public void findMatchingTypeMissingSizeCode() {
+ S7DataType result = S7DataType.findMatchingType(Integer.class, S7DataType.UINT, null);
+ assertThat(result, equalTo(S7DataType.UINT));
+ }
+
+ @Test
+ @Category(FastTests.class)
+ public void findMatchingTypeBaseTypeAndSizeCode() {
+ S7DataType result = S7DataType.findMatchingType(Integer.class, S7DataType.INT, "W");
+ assertThat(result, equalTo(S7DataType.UINT));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ @Category(FastTests.class)
+ public void findMatchingTypeBaseTypeAndWrongSizeCode() {
+ S7DataType result = S7DataType.findMatchingType(Integer.class, S7DataType.INT, "X");
+ assertThat(result, equalTo(S7DataType.UINT));
+ }
+
+}
\ No newline at end of file