You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2020/11/13 12:48:07 UTC

[plc4x] branch bug/simulated_device_data_types created (now 27192b7)

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

hutcheb pushed a change to branch bug/simulated_device_data_types
in repository https://gitbox.apache.org/repos/asf/plc4x.git.


      at 27192b7  [Broken State] Adding support for PlcValue datatypes for simulated devic

This branch includes the following new commits:

     new 27192b7  [Broken State] Adding support for PlcValue datatypes for simulated devic

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.



[plc4x] 01/01: [Broken State] Adding support for PlcValue datatypes for simulated devic

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

hutcheb pushed a commit to branch bug/simulated_device_data_types
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 27192b7668db0f5e86da7ff0df2198adf848efa7
Author: hutcheb <be...@gmail.com>
AuthorDate: Fri Nov 13 07:42:40 2020 -0500

    [Broken State] Adding support for PlcValue datatypes for simulated devic
    
    - Add mspec for simulated device. This allows us to test the staticParse
    and staticSerialize templates without a device.
    
    - Adding support for PlcValue datatypes in the simulated device.
---
 plc4j/drivers/simulated/pom.xml                    |  46 +++++-
 .../java/simulated/connection/SimulatedDevice.java |  52 ++-----
 .../plc4x/java/simulated/field/SimulatedField.java |  19 +--
 .../simulated/field/SimulatedFieldHandler.java     |  15 +-
 .../simulated/field/SimularedFieldHandlerTest.java |   2 +-
 protocols/pom.xml                                  |   3 +-
 protocols/simulated/pom.xml                        |  43 ++++++
 .../protocol/simulated/SimulatedProtocol.java      |  46 ++++++
 ...e.plc4x.plugins.codegenerator.protocol.Protocol |  19 +++
 .../resources/protocols/simulated/simulated.mspec  | 159 +++++++++++++++++++++
 10 files changed, 338 insertions(+), 66 deletions(-)

diff --git a/plc4j/drivers/simulated/pom.xml b/plc4j/drivers/simulated/pom.xml
index 3dd138c..7785bf1 100644
--- a/plc4j/drivers/simulated/pom.xml
+++ b/plc4j/drivers/simulated/pom.xml
@@ -33,6 +33,24 @@
 
   <build>
     <plugins>
+        <plugin>
+          <groupId>org.apache.plc4x.plugins</groupId>
+          <artifactId>plc4x-maven-plugin</artifactId>
+          <executions>
+            <execution>
+              <id>generate-driver</id>
+              <phase>generate-sources</phase>
+              <goals>
+                <goal>generate-driver</goal>
+              </goals>
+              <configuration>
+                <protocolName>simulated</protocolName>
+                <languageName>java</languageName>
+                <outputFlavor>read-write</outputFlavor>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
       <plugin>
         <groupId>org.apache.karaf.tooling</groupId>
         <artifactId>karaf-maven-plugin</artifactId>
@@ -76,6 +94,16 @@
           </instructions>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <configuration>
+          <usedDependencies combine.children="append">
+            <usedDependency>org.apache.plc4x:plc4x-build-utils-language-java</usedDependency>
+            <usedDependency>org.apache.plc4x:plc4x-protocols-simulated</usedDependency>
+          </usedDependencies>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 
@@ -107,6 +135,22 @@
       <version>0.8.0-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-language-java</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-protocols-simulated</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
   </dependencies>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedDevice.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedDevice.java
index fb91433..706550e 100644
--- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedDevice.java
+++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedDevice.java
@@ -23,6 +23,10 @@ import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.api.value.PlcValues;
 import org.apache.plc4x.java.simulated.field.SimulatedField;
+import org.apache.plc4x.java.simulated.readwrite.io.DataItemIO;
+import org.apache.plc4x.java.simulated.readwrite.types.SimulatedDataType;
+import org.apache.plc4x.java.spi.generation.ParseException;
+import org.apache.plc4x.java.spi.generation.ReadBuffer;
 import org.apache.plc4x.java.spi.model.InternalPlcSubscriptionHandle;
 
 import java.time.Duration;
@@ -62,7 +66,7 @@ public class SimulatedDevice {
             case STATE:
                 return Optional.ofNullable(state.get(field));
             case RANDOM:
-                return Optional.of(randomValue(field.getDataType()));
+                return Optional.of(randomValue(field));
             case STDOUT:
                 return Optional.empty();
         }
@@ -90,48 +94,22 @@ public class SimulatedDevice {
     }
 
     @SuppressWarnings("unchecked")
-    private PlcValue randomValue(Class<?> type) {
+    private PlcValue randomValue(SimulatedField field) {
         Object result = null;
 
-        if (type.equals(Byte.class)) {
-            return PlcValues.of((byte) random.nextInt(1 << 8));
-        }
-
-        if (type.equals(Short.class)) {
-            return PlcValues.of((short) random.nextInt(1 << 16));
-        }
+        Short fieldDataType = SimulatedDataType.valueOf(field.getPlcDataType()).getValue();
+        Short fieldDataTypeSize = SimulatedDataType.valueOf(field.getPlcDataType()).getDataTypeSize();
 
-        if (type.equals(Integer.class)) {
-            return PlcValues.of(random.nextInt());
-        }
+        byte[] b = new byte[fieldDataTypeSize];
+        new Random().nextBytes(b);
 
-        if (type.equals(Long.class)) {
-            return PlcValues.of(random.nextLong());
-        }
-
-        if (type.equals(Float.class)) {
-            return PlcValues.of(random.nextFloat());
-        }
-
-        if (type.equals(Double.class)) {
-            return PlcValues.of(random.nextDouble());
-        }
-
-        if (type.equals(Boolean.class)) {
-            return PlcValues.of(random.nextBoolean());
-        }
-
-        if (type.equals(String.class)) {
-            int length = random.nextInt(100);
-            StringBuilder sb = new StringBuilder(length);
-            for (int i = 0; i < length; i++) {
-                char c = (char) ('a' + random.nextInt(26));
-                sb.append(c);
-            }
-            return PlcValues.of(sb.toString());
+        ReadBuffer io = new ReadBuffer(b);
+        try {
+            return DataItemIO.staticParse(io, fieldDataType, (short) 1);
+        } catch (ParseException e) {
+            return null;
         }
 
-        return null;
     }
 
     @Override
diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/field/SimulatedField.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/field/SimulatedField.java
index bd96a39..d976ab1 100644
--- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/field/SimulatedField.java
+++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/field/SimulatedField.java
@@ -41,14 +41,14 @@ public class SimulatedField implements PlcField {
      * - {@code RANDOM/foo:INTEGER}
      * - {@code STDOUT/foo:STRING}
      */
-    private static final Pattern ADDRESS_PATTERN = Pattern.compile("^(?<type>\\w+)/(?<name>\\w+):(?<dataType>[a-zA-Z]++)(\\[(?<numElements>\\d+)])?$");
+    private static final Pattern ADDRESS_PATTERN = Pattern.compile("^(?<type>\\w+)/(?<name>\\w+):(?<dataType>[a-zA-Z0-9]++)(\\[(?<numElements>\\d+)])?$");
 
     private final SimulatedFieldType type;
     private final String name;
-    private final Class<?> dataType;
+    private final String dataType;
     private final int numElements;
 
-    private SimulatedField(SimulatedFieldType type, String name, Class<?> dataType, int numElements) {
+    private SimulatedField(SimulatedFieldType type, String name, String dataType, int numElements) {
         this.type = type;
         this.name = name;
         this.dataType = dataType;
@@ -65,13 +65,8 @@ public class SimulatedField implements PlcField {
             if (matcher.group("numElements") != null) {
                 numElements = Integer.parseInt(matcher.group("numElements"));
             }
-            try {
-                Class<?> dataType = Class.forName("java.lang." + dataTypeName);
-                return new SimulatedField(type, name, dataType, numElements);
-            } catch (ClassNotFoundException e) {
-                logger.error("Unsupported type: " + dataTypeName, e);
-                throw new PlcInvalidFieldException("Unsupported type: " + dataTypeName);
-            }
+
+            return new SimulatedField(type, name, dataTypeName, numElements);
         }
         throw new PlcInvalidFieldException("Unable to parse address: " + fieldString);
     }
@@ -85,14 +80,14 @@ public class SimulatedField implements PlcField {
     }
 
     public String getPlcDataType() {
-        return dataType.getSimpleName();
+        return dataType;
     }
 
     public String getName() {
         return name;
     }
 
-    public Class<?> getDataType() {
+    public String getDataType() {
         return dataType;
     }
 
diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/field/SimulatedFieldHandler.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/field/SimulatedFieldHandler.java
index 691b389..561f020 100644
--- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/field/SimulatedFieldHandler.java
+++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/field/SimulatedFieldHandler.java
@@ -41,20 +41,7 @@ public class SimulatedFieldHandler extends DefaultPlcFieldHandler {
         }
         throw new PlcInvalidFieldException(fieldQuery);
     }
-
-    @Override
-    public PlcValue encodeString(PlcField field, Object[] values) {
-        SimulatedField testField = (SimulatedField) field;
-        if (testField.getDataType() == String.class) {
-            if(values.length == 1) {
-                return new PlcString((String) values[0]);
-            } else {
-                return new PlcList(Arrays.asList(values));
-            }
-        }
-        throw new PlcRuntimeException("Invalid encoder for type " + testField.getDataType().getName());
-    }
-
+    
     @Override
     public PlcValue encodeTime(PlcField field, Object[] values) {
         SimulatedField testField = (SimulatedField) field;
diff --git a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/field/SimularedFieldHandlerTest.java b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/field/SimularedFieldHandlerTest.java
index 983fa26..f2cde43 100644
--- a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/field/SimularedFieldHandlerTest.java
+++ b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/field/SimularedFieldHandlerTest.java
@@ -102,7 +102,7 @@ class SimularedFieldHandlerTest implements WithAssertions {
 
     @Test
     void encodeString() {
-        when(plcField.getDataType()).thenReturn((Class) String.class);
+        when(plcField.getPlcDataType()).thenReturn("String");
         assertThat(SUT.encodeString(plcField, new String[0])).isNotNull();
     }
 
diff --git a/protocols/pom.xml b/protocols/pom.xml
index 1459800..6ae9fca 100644
--- a/protocols/pom.xml
+++ b/protocols/pom.xml
@@ -43,6 +43,7 @@
     <module>knxnetip</module>
     <module>modbus</module>
     <module>s7</module>
+    <module>simulated</module>
   </modules>
 
   <build>
@@ -216,4 +217,4 @@
     </profile>
   </profiles>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/protocols/simulated/pom.xml b/protocols/simulated/pom.xml
new file mode 100644
index 0000000..911a973
--- /dev/null
+++ b/protocols/simulated/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.plc4x</groupId>
+    <artifactId>plc4x-protocols</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>plc4x-protocols-simulated</artifactId>
+
+  <name>Protocols: Simulated</name>
+  <description>Base protocol specifications for the Simulated protocol</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-protocol-base-mspec</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/protocols/simulated/src/main/java/org/apache/plc4x/protocol/simulated/SimulatedProtocol.java b/protocols/simulated/src/main/java/org/apache/plc4x/protocol/simulated/SimulatedProtocol.java
new file mode 100644
index 0000000..608646c
--- /dev/null
+++ b/protocols/simulated/src/main/java/org/apache/plc4x/protocol/simulated/SimulatedProtocol.java
@@ -0,0 +1,46 @@
+/*
+ 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.protocol.simulated;
+
+import org.apache.plc4x.plugins.codegenerator.language.mspec.parser.MessageFormatParser;
+import org.apache.plc4x.plugins.codegenerator.protocol.Protocol;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
+import org.apache.plc4x.plugins.codegenerator.types.exceptions.GenerationException;
+
+import java.io.InputStream;
+import java.util.Map;
+
+public class SimulatedProtocol implements Protocol {
+
+    @Override
+    public String getName() {
+        return "simulated";
+    }
+
+    @Override
+    public Map<String, TypeDefinition> getTypeDefinitions() throws GenerationException {
+        InputStream schemaInputStream = SimulatedProtocol.class.getResourceAsStream("/protocols/simulated/simulated.mspec");
+        if(schemaInputStream == null) {
+            throw new GenerationException("Error loading message-format schema for protocol '" + getName() + "'");
+        }
+        return new MessageFormatParser().parse(schemaInputStream);
+    }
+
+}
diff --git a/protocols/simulated/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol b/protocols/simulated/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol
new file mode 100644
index 0000000..0a4a4c3
--- /dev/null
+++ b/protocols/simulated/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol
@@ -0,0 +1,19 @@
+#
+# 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.protocol.simulated.SimulatedProtocol
diff --git a/protocols/simulated/src/main/resources/protocols/simulated/simulated.mspec b/protocols/simulated/src/main/resources/protocols/simulated/simulated.mspec
new file mode 100644
index 0000000..559311e
--- /dev/null
+++ b/protocols/simulated/src/main/resources/protocols/simulated/simulated.mspec
@@ -0,0 +1,159 @@
+//
+// 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.
+//
+
+// Remark: The different fields are encoded in Big-endian.
+
+[dataIo 'DataItem' [uint 8 'dataType', uint 8 'numberOfValues']
+    [typeSwitch 'dataType','numberOfValues'
+        ['1','1' BOOL
+            [reserved uint 7 '0x00']
+            [simple   bit    'value']
+        ]
+        ['1' BOOL
+            [array bit 'value' count 'numberOfValues']
+        ]
+        ['10','1' BYTE
+            [simple uint 8 'value']
+        ]
+        ['10' BYTE
+            [array uint 8 'value' count 'numberOfValues']
+        ]
+        ['11','1' WORD
+            [simple uint 16 'value']
+        ]
+        ['11' WORD
+            [array uint 16 'value' count 'numberOfValues']
+        ]
+        ['12','1' DWORD
+            [simple uint 32 'value']
+        ]
+        ['12' DWORD
+            [array uint 32 'value' count 'numberOfValues']
+        ]
+        ['13','1' LWORD
+            [simple uint 64 'value']
+        ]
+        ['13' LWORD
+            [array uint 64 'value' count 'numberOfValues']
+        ]
+        ['20','1' SINT
+            [simple int 8 'value']
+        ]
+        ['20' SINT
+            [array int 8 'value' count 'numberOfValues']
+        ]
+        ['21','1' INT
+            [simple int 16 'value']
+        ]
+        ['21' INT
+            [array int 16 'value' count 'numberOfValues']
+        ]
+        ['22','1' DINT
+            [simple int 32 'value']
+        ]
+        ['22' DINT
+            [array int 32 'value' count 'numberOfValues']
+        ]
+        ['23','1' LINT
+            [simple int 64 'value']
+        ]
+        ['23' LINT
+            [array int 64 'value' count 'numberOfValues']
+        ]
+        ['24','1' USINT
+            [simple uint 8 'value']
+        ]
+        ['24' USINT
+            [array uint 8 'value' count 'numberOfValues']
+        ]
+        ['25','1' UINT
+            [simple uint 16 'value']
+        ]
+        ['25' UINT
+            [array uint 16 'value' count 'numberOfValues']
+        ]
+        ['26','1' UDINT
+            [simple uint 32 'value']
+        ]
+        ['26' UDINT
+            [array uint 32 'value' count 'numberOfValues']
+        ]
+        ['27','1' ULINT
+            [simple uint 64 'value']
+        ]
+        ['27' ULINT
+            [array uint 64 'value' count 'numberOfValues']
+        ]
+        ['30','1' REAL
+            [simple float 8.23  'value']
+        ]
+        ['30' REAL
+            [array float 8.23 'value' count 'numberOfValues']
+        ]
+        ['31','1' LREAL
+            [simple float 11.52  'value']
+        ]
+        ['31' LREAL
+            [array float 11.52 'value' count 'numberOfValues']
+        ]
+        ['80','1' CHAR
+            [simple uint 8 'value']
+        ]
+        ['80' CHAR
+            [array uint 8 'value' count 'numberOfValues']
+        ]
+        ['81','1' WCHAR
+            [simple uint 16 'value']
+        ]
+        ['81' WCHAR
+            [array uint 16 'value' count 'numberOfValues']
+        ]
+    ]
+]
+
+[enum uint 8 'SimulatedDataType' [uint 8 'dataTypeSize']
+    ['00' NULL ['0']]
+    ['01' BOOL ['1']]
+    ['10' BYTE ['1']]
+    ['11' WORD ['2']]
+    ['12' DWORD ['4']]
+    ['13' LWORD ['8']]
+    ['20' SINT ['1']]
+    ['21' INT ['2']]
+    ['22' DINT ['4']]
+    ['23' LINT ['8']]
+    ['24' USINT ['1']]
+    ['25' UINT ['2']]
+    ['26' UDINT ['4']]
+    ['27' ULINT ['8']]
+    ['30' REAL ['4']]
+    ['31' LREAL ['8']]
+    ['40' TIME ['8']]
+    ['41' LTIME ['8']]
+    ['50' DATE ['8']]
+    ['51' LDATE ['8']]
+    ['60' TIME_OF_DAY ['8']]
+    ['61' LTIME_OF_DAY ['8']]
+    ['70' DATE_AND_TIME ['8']]
+    ['71' LDATE_AND_TIME ['8']]
+    ['80' CHAR ['1']]
+    ['81' WCHAR ['2']]
+    ['82' STRING ['1']]
+    ['83' WSTRING ['2']]
+]