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 2020/10/22 15:29:25 UTC

[plc4x] branch feature/plc4go updated: - Finished a first version of a working Modbus Go driver

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

cdutz pushed a commit to branch feature/plc4go
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/feature/plc4go by this push:
     new 7301e08  - Finished a first version of a working Modbus Go driver
7301e08 is described below

commit 7301e089fdf76a12d181fcd50e4443cfa57232b2
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Oct 22 17:29:16 2020 +0200

    - Finished a first version of a working Modbus Go driver
---
 .../BaseFreemarkerLanguageTemplateHelper.java      |  33 ++
 .../resources/templates/c/data-io-template-c.ftlh  |   3 +-
 .../language/go/GoLanguageTemplateHelper.java      |  16 +-
 .../resources/templates/go/data-io-template.ftlh   |  86 ++--
 .../main/resources/templates/go/enum-template.ftlh |   2 +-
 .../resources/templates/java/data-io-template.ftlh |   4 +-
 .../main/resources/templates/java/io-template.ftlh |   2 +-
 .../plugins/codegenerator/language/mspec/MSpec.g4  |   6 +-
 .../mspec/parser/MessageFormatListener.java        |   4 +-
 .../java/modbus/protocol/ModbusProtocolLogic.java  |  11 +-
 .../java/spi/generation/EvaluationHelper.java      |   5 +
 .../resources/protocols/knxnetip/knxnetip.mspec    |   4 +-
 .../main/resources/protocols/modbus/modbus.mspec   |  70 +--
 .../s7/src/main/resources/protocols/s7/s7.mspec    |   4 +-
 .../generated-sources/modbus/include/data_item.h   |   2 +-
 .../plc4c/generated-sources/modbus/src/data_item.c |  71 +--
 sandbox/plc4c/generated-sources/s7/src/data_item.c |   5 +-
 sandbox/plc4go/cmd/main/drivers/modbus_test.go     |  12 +-
 sandbox/plc4go/go.mod                              |   1 -
 .../knxnetip/readwrite/model/KnxDatapoint.go       | 559 +++++++++++++++++++++
 .../readwrite/model/KnxStaticHelper.go}            |  32 +-
 .../internal/plc4go/modbus/ModbusFieldHandler.go   |  20 +-
 .../plc4go/internal/plc4go/modbus/ModbusReader.go  |  30 +-
 .../internal/plc4go/modbus/ModbusValueHandler.go   |   4 +-
 .../plc4go/modbus/readwrite/model/DataItem.go      | 107 ++--
 .../plc4go/model/DefaultPlcReadResponse.go         |   6 +
 .../plc4go/model/values/{iec61131 => }/BOOL.go     |   8 +-
 .../plc4go/model/values/{iec61131 => }/BYTE.go     |   6 +-
 .../plc4go/model/values/{iec61131 => }/CHAR.go     |   6 +-
 .../plc4go/model/values/{iec61131 => }/DATE.go     |   7 +-
 .../model/values/{iec61131 => }/DATE_AND_TIME.go   |   7 +-
 .../plc4go/model/values/{iec61131 => }/DINT.go     |   7 +-
 .../plc4go/model/values/{iec61131 => }/DWORD.go    |   6 +-
 .../values/{iec61131 => }/IEC61131ValueHandler.go  |   4 +-
 .../plc4go/model/values/{iec61131 => }/INT.go      |   7 +-
 .../plc4go/model/values/{iec61131 => }/LINT.go     |   7 +-
 .../plc4go/model/values/{iec61131 => }/LREAL.go    |   7 +-
 .../plc4go/model/values/{iec61131 => }/LTIME.go    |   7 +-
 .../plc4go/model/values/{iec61131 => }/LWORD.go    |   6 +-
 .../plc4go/model/values/{iec61131 => }/NULL.go     |   6 +-
 .../plc4go/model/values/{iec61131 => }/REAL.go     |   7 +-
 .../plc4go/model/values/{iec61131 => }/SINT.go     |   6 +-
 .../plc4go/model/values/{iec61131 => }/STRING.go   |   6 +-
 .../plc4go/model/values/{iec61131 => }/TIME.go     |   7 +-
 .../model/values/{iec61131 => }/TIME_OF_DAY.go     |   7 +-
 .../plc4go/model/values/{iec61131 => }/UDINT.go    |   7 +-
 .../plc4go/model/values/{iec61131 => }/UINT.go     |   7 +-
 .../plc4go/model/values/{iec61131 => }/ULINT.go    |   7 +-
 .../plc4go/model/values/{iec61131 => }/USINT.go    |   7 +-
 .../plc4go/model/values/{iec61131 => }/WCHAR.go    |   7 +-
 .../plc4go/model/values/{iec61131 => }/WORD.go     |   6 +-
 .../plc4go/model/values/{iec61131 => }/WSTRING.go  |   7 +-
 .../internal/plc4go/s7/readwrite/model/DataItem.go |  93 +++-
 .../plc4go/s7/readwrite/model/S7StaticHelper.go    | 137 +++++
 54 files changed, 1147 insertions(+), 354 deletions(-)

diff --git a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
index dca2e60..c74d5a0 100644
--- a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
+++ b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
 import org.apache.plc4x.plugins.codegenerator.types.fields.*;
 import org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference;
+import org.apache.plc4x.plugins.codegenerator.types.references.StringTypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.terms.*;
 
@@ -777,4 +778,36 @@ public abstract class BaseFreemarkerLanguageTemplateHelper implements Freemarker
         return false;
     }
 
+    public boolean discriminatorValueNeedsStringEqualityCheck(Term term) {
+        if(term instanceof VariableLiteral) {
+            VariableLiteral variableLiteral = (VariableLiteral) term;
+            // If this literal references an Enum type, then we have to output it differently.
+            if (getTypeDefinitions().get(variableLiteral.getName()) instanceof EnumTypeDefinition) {
+                return false;
+            }
+
+            if(getThisTypeDefinition() instanceof ComplexTypeDefinition) {
+                Field referencedField = ((ComplexTypeDefinition) getThisTypeDefinition()).getFields().stream().filter(field -> ((field instanceof NamedField) && ((NamedField) field).getName().equals(variableLiteral.getName()))).findFirst().orElse(null);
+                if(referencedField != null) {
+                    if(referencedField instanceof TypedField) {
+                        TypedField typedField = (TypedField) referencedField;
+                        if(typedField.getType() instanceof StringTypeReference) {
+                            return true;
+                        }
+                    }
+                }
+            }
+            if(getThisTypeDefinition().getParserArguments() != null) {
+                for (Argument parserArgument : getThisTypeDefinition().getParserArguments()) {
+                    if (parserArgument.getName().equals(variableLiteral.getName())) {
+                        if(parserArgument.getType() instanceof StringTypeReference) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
 }
diff --git a/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh b/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh
index 602bb14..487ee37 100644
--- a/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh
@@ -62,6 +62,7 @@
 */
 
 #include <stdio.h>
+#include <string.h>
 #include <time.h>
 #include <plc4c/data.h>
 #include <plc4c/spi/evaluation_helper.h>
@@ -75,7 +76,7 @@ plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer*
     plc4c_return_code _res = OK;
 
     <#list type.switchField.cases as case>
-        <#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue><#if case.discriminatorValues?size &gt; 1>(</#if>${helper.toParseExpression(type, null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)} == ${discriminatorValue}<#if case.discriminatorValues?size &gt; 1>)</#if><#sep> && </#sep></#list>) </#if>{ /* ${case.name} */
+        <#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue><#if case.discriminatorValues?size &gt; 1>(</#if><#if helper.discriminatorValueNeedsStringEqualityCheck(type.switchField.discriminatorExpressions[discriminatorValue?index])>strcmp(${helper.toParseExpression(type, null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, "${discriminatorValue}") == 0<#else>${helper.toParseExpression(type, null [...]
 <#--        (*_message)->_type = ${helper.getCTypeName(type.name)}_type_${helper.getCTypeName(case.name)};-->
         <#assign skipReturn=false>
         <#list case.fields as field>
diff --git a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
index 1f5e873..2a48456 100644
--- a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
+++ b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
@@ -459,10 +459,16 @@ public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
                 throw new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral");
             }
             // Get the class and method name
-            String methodName = ((StringLiteral) vl.getArgs().get(0)).getValue();
-            // Cut off the double-quptes
-            methodName = methodName.substring(1, methodName.length() - 1);
-            sb.append(methodName).append("(");
+            String staticCall = ((StringLiteral) vl.getArgs().get(0)).getValue();
+            // Cut off the double-quotes
+            staticCall = staticCall.substring(1, staticCall.length() - 1);
+            // Remove all the previous parts prior to the Class name (Which starts with an uppercase letter)
+            while(staticCall.contains(".") && !StringUtils.isAllUpperCase(staticCall.substring(0,1))) {
+                staticCall = staticCall.substring(staticCall.indexOf(".") + 1);
+            }
+            String className = staticCall.substring(0, staticCall.indexOf("."));
+            String methodName = staticCall.substring(staticCall.indexOf(".") + 1);
+            sb.append(className).append(StringUtils.capitalize(methodName)).append("(");
             for (int i = 1; i < vl.getArgs().size(); i++) {
                 Term arg = vl.getArgs().get(i);
                 if (i > 1) {
@@ -700,7 +706,7 @@ public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
             imports.add("\"math\"");
         }
 
-        imports.add("\"plc4x.apache.org/plc4go-modbus-driver/0.8.0/internal/plc4go/spi\"");
+        imports.add("\"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi\"");
 
         // "Fields with complex type": "reflect"
         if(((ComplexTypeDefinition) getThisTypeDefinition()).getFields().stream().anyMatch(field ->
diff --git a/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
index 6570889..cc21075 100644
--- a/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
+++ b/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
@@ -64,16 +64,16 @@ package model
 
 import (
     "errors"
-    "plc4x.apache.org/plc4go-modbus-driver/0.8.0/internal/plc4go/model/values"
-    "plc4x.apache.org/plc4go-modbus-driver/0.8.0/internal/plc4go/model/values/iec61131"
-    "plc4x.apache.org/plc4go-modbus-driver/0.8.0/internal/plc4go/spi"
-    api "plc4x.apache.org/plc4go-modbus-driver/0.8.0/pkg/plc4go/values"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
 )
 
 func ${type.name}Parse(io *spi.ReadBuffer<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${parserArgument.name} <#if helper.isComplexTypeReference(parserArgument.type)>I</#if>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#sep>, </#sep></#list></#if>) (api.PlcValue, error) {
     switch {
     <#list type.switchField.cases as case>
-        case <#if case.discriminatorValues?has_content><#list case.discriminatorValues as discriminatorValue>${helper.toParseExpression(null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)} == ${discriminatorValue}<#sep> && </#sep></#list></#if>: // ${case.name}
+        case <#if case.discriminatorValues?has_content><#list case.discriminatorValues as discriminatorValue>${helper.toParseExpression(null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)} == <#if helper.discriminatorValueNeedsStringEqualityCheck(type.switchField.discriminatorExpressions[discriminatorValue?index])>"${discriminatorValue}"<#else>${discriminatorValue}</#if><#sep> && </#sep></#list></#if>: // ${case.name}
+        <#assign valueDefined=false>
         <#if case.name == "Struct">
             _map := map[string]interface{}{}
         </#if>
@@ -84,10 +84,27 @@ func ${type.name}Parse(io *spi.ReadBuffer<#if type.parserArguments?has_content>,
 
             // Array Field (${field.name})
             var ${field.name} []api.PlcValue
+                    <#if field.name == "value">
+                        <#assign valueDefined=true>
+                    </#if>
+                    <#break>
+                <#case "manual">
+                    <#assign arrayField = field>
+
+            // Manual Field (${field.name})
+            ${field.name}, _${field.name}Err := ${helper.toParseExpression(field, field.parseExpression, type.parserArguments)}
+            if _${field.name}Err != nil {
+                return nil, errors.New("Error parsing '${field.name}' field " + _${field.name}Err.Error())
+            }
+                    <#if field.name == "value">
+                        <#assign valueDefined=true>
+                    </#if>
                     <#break>
                 <#case "reserved">
                     <#assign reservedField = field>
 
+            // Reserved Field (Just skip the bytes)
+            ${helper.getReadBufferReadMethodCall(field.type)}
                     <#break>
                 <#case "simple">
                     <#assign simpleField = field>
@@ -97,39 +114,44 @@ func ${type.name}Parse(io *spi.ReadBuffer<#if type.parserArguments?has_content>,
             if _${field.name}Err != nil {
                 return nil, errors.New("Error parsing '${field.name}' field " + _${field.name}Err.Error())
             }
-            <#if case.name == "Struct">
+                    <#if case.name == "Struct">
             _map["${case.name}"] = ${field.name}
-            </#if>
-                <#break>
+                    </#if>
+                    <#if field.name == "value">
+                        <#assign valueDefined=true>
+                    </#if>
+                    <#break>
             </#switch>
         </#list>
-        <#switch case.name>
-            <#case "Time">
-            //return new PlcTime(LocalTime.of((int) hours, (int) minutes, (int) seconds))
-                <#break>
-            <#case "Date">
-            //return new PlcDate(LocalDate.of((int) year, (int) month, (int) day))
-                <#break>
-            <#case "DateTime">
-            //return new PlcDateTime(LocalDateTime.of((int) year, (int) month, (int) day, (int) hours, (int) minutes, (int) seconds))
-                <#break>
-            <#case "Struct">
+        <#if valueDefined>
+            <#switch case.name>
+                <#case "Time">
+            return values.NewPlcTIME(value), nil
+                    <#break>
+                <#case "Date">
+            return values.NewPlcTIME(value), nil
+                    <#break>
+                <#case "DateTime">
+            return values.NewPlcTIME(value), nil
+                    <#break>
+                <#case "Struct">
             return values.NewPlcStruct(_map), nil
-                <#break>
-            <#case "List">
+                    <#break>
+                <#case "List">
             return values.NewPlcList(value), nil
-                <#break>
-            <#-- Disable this for now as Strings will only be parsed as manual fields -
-            <#case "STRING">
-            return values.NewPlcSTRING(value), nil
-                <#break-->
-            <#default>
-                <#if helper.isCountArrayField(case.fields[0])>
+                    <#break>
+            <#-- Disable this for now as Strings will only be parsed as manual fields
+                <#case "STRING">
+            //return values.NewPlcSTRING(value), nil
+                    <#break-->
+                <#default>
+                    <#if helper.isCountArrayField(case.fields[0])>
             return values.NewPlcList(value), nil
-                <#else>
-            return iec61131.NewPlc${case.name}(value), nil
-                </#if>
-        </#switch>
+                    <#else>
+            return values.NewPlc${case.name}(value), nil
+                    </#if>
+            </#switch>
+        </#if>
     </#list>
     }
     return nil, errors.New("unsupported type")
diff --git a/build-utils/language-go/src/main/resources/templates/go/enum-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/enum-template.ftlh
index 822e7a2..0a1cf59 100644
--- a/build-utils/language-go/src/main/resources/templates/go/enum-template.ftlh
+++ b/build-utils/language-go/src/main/resources/templates/go/enum-template.ftlh
@@ -47,7 +47,7 @@ ${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/m
 //
 package model
 
-import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/internal/plc4go/spi"
+import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
 
 type ${type.name} <#if type.type?has_content>${helper.getLanguageTypeNameForTypeReference(type.type)}<#else>string</#if>
 
diff --git a/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
index 6ed691d..1c63222 100644
--- a/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
@@ -88,7 +88,7 @@ public class ${type.name}IO {
     private static final Logger LOGGER = LoggerFactory.getLogger(${type.name}IO.class);
 
     public static PlcValue staticParse(ReadBuffer io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws ParseException {
-        <#list type.switchField.cases as case><#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, ${discriminatorValue})<#sep> && </#sep></#list>) </#if>{ // ${case.name}
+        <#list type.switchField.cases as case><#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, <#if helper.discriminatorValueNeedsStringEqualityCheck(type.switchField.discriminatorExpressions[discriminatorValue?index])>"${discriminatorValue}"<#else>${discriminatorValue}</#if>)<#sep> && </#se [...]
             <#assign skipReturn=false>
             <#list case.fields as field>
                 <#switch field.typeName>
@@ -258,7 +258,7 @@ public class ${type.name}IO {
     }
 
     public static WriteBuffer staticSerialize(PlcValue _value<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>, boolean littleEndian) throws ParseException {
-        <#list type.switchField.cases as case><#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, ${discriminatorValue})<#sep> && </#sep></#list>) </#if>{ // ${case.name}
+        <#list type.switchField.cases as case><#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, <#if helper.discriminatorValueNeedsStringEqualityCheck(type.switchField.discriminatorExpressions[discriminatorValue?index])>"${discriminatorValue}"<#else>${discriminatorValue}</#if>)<#sep> && </#se [...]
             WriteBuffer io = new WriteBuffer((int) Math.ceil(((float) ${helper.getSizeInBits(case, type.parserArguments)}) / 8.0f), littleEndian);
 
             <#list case.fields as field>
diff --git a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
index 558471a..5b00414 100644
--- a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
@@ -369,7 +369,7 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
         // Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
         ${type.name}Builder builder = null;
         <#list switchField.cases as case>
-        <#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, ${discriminatorValue})<#sep> && </#sep></#list>) </#if>{
+        <#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, <#if helper.discriminatorValueNeedsStringEqualityCheck(switchField.discriminatorExpressions[discriminatorValue?index])>"${discriminatorValue}"<#else>${discriminatorValue}</#if>)<#sep> && </#sep></#list>) </#if>{
             builder = ${case.name}IO.staticParse(io<#if case.parserArguments?has_content>, <#list case.parserArguments as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>);
         }<#sep> else </#sep>
         </#list>
diff --git a/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4 b/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
index 76eefbb..0a4cfe5 100644
--- a/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
+++ b/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
@@ -142,11 +142,7 @@ dataType
  | base='uint' size=INTEGER_LITERAL
  | base='float' exponent=INTEGER_LITERAL '.' mantissa=INTEGER_LITERAL
  | base='ufloat' exponent=INTEGER_LITERAL '.' mantissa=INTEGER_LITERAL
-/* For the following types the parsing/serialization has to be handled manually */
- /* Fixed length string parsing */
- | base='string' size=INTEGER_LITERAL encoding=idExpression
- /* Variable length string parsing */
- | base='string' encoding=idExpression
+ | base='string' (size=INTEGER_LITERAL)? (encoding=idExpression)?
  | base='time'
  | base='date'
  | base='dateTime'
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
index 2c58f2c..3729929 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
@@ -432,9 +432,9 @@ public class MessageFormatListener extends MSpecBaseListener {
         SimpleTypeReference.SimpleBaseType simpleBaseType =
             SimpleTypeReference.SimpleBaseType.valueOf(ctx.base.getText().toUpperCase());
         // String types need an additional "encoding" field and an optional size.
-        if (ctx.encoding != null) {
+        if(simpleBaseType == SimpleTypeReference.SimpleBaseType.STRING) {
             int size = (ctx.size != null) ? Integer.parseInt(ctx.size.getText()) : -1;
-            String encoding = ctx.encoding.getText();
+            String encoding = (ctx.encoding != null) ? ctx.encoding.getText() : "UTF-8";
             return new DefaultStringTypeReference(simpleBaseType, size, encoding);
         }
         // If a size it specified its a simple integer length based type.
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
index c07b649..6b4f4ce 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
@@ -337,7 +337,6 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
     }
 
     private PlcValue toPlcValue(ModbusPDU request, ModbusPDU response, String dataType) throws ParseException {
-        Short fieldDataType = ModbusDataType.valueOf(dataType).getValue();
         Short fieldDataTypeSize = ModbusDataType.valueOf(dataType).getDataTypeSize();
 
         if (request instanceof ModbusPDUReadDiscreteInputsRequest) {
@@ -364,7 +363,7 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
             ModbusPDUReadInputRegistersRequest req = (ModbusPDUReadInputRegistersRequest) request;
             ModbusPDUReadInputRegistersResponse resp = (ModbusPDUReadInputRegistersResponse) response;
             ReadBuffer io = new ReadBuffer(resp.getValue());
-            return DataItemIO.staticParse(io, fieldDataType, (short) Math.round(req.getQuantity()/(fieldDataTypeSize/2.0f)));
+            return DataItemIO.staticParse(io, dataType, (short) Math.round(req.getQuantity()/(fieldDataTypeSize/2.0f)));
         } else if (request instanceof ModbusPDUReadHoldingRegistersRequest) {
             if (!(response instanceof ModbusPDUReadHoldingRegistersResponse)) {
                 throw new PlcRuntimeException("Unexpected response type. " +
@@ -373,7 +372,7 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
             ModbusPDUReadHoldingRegistersRequest req = (ModbusPDUReadHoldingRegistersRequest) request;
             ModbusPDUReadHoldingRegistersResponse resp = (ModbusPDUReadHoldingRegistersResponse) response;
             ReadBuffer io = new ReadBuffer(resp.getValue());
-            return DataItemIO.staticParse(io, fieldDataType, (short) Math.round(req.getQuantity()/(fieldDataTypeSize/2.0f)));
+            return DataItemIO.staticParse(io, dataType, (short) Math.round(req.getQuantity()/(fieldDataTypeSize/2.0f)));
         } else if (request instanceof ModbusPDUReadFileRecordRequest) {
             if (!(response instanceof ModbusPDUReadFileRecordResponse)) {
                 throw new PlcRuntimeException("Unexpected response type. " +
@@ -397,13 +396,13 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
                   "Expected " + req.getItems().length + ", but got " + resp.getItems().length);
             }
 
-            return DataItemIO.staticParse(io, fieldDataType, (short) Math.round((dataLength/2.0f)/(fieldDataTypeSize/2.0f)));
+            return DataItemIO.staticParse(io, dataType, (short) Math.round((dataLength/2.0f)/(fieldDataTypeSize/2.0f)));
         }
         return null;
     }
 
     private byte[] fromPlcValue(PlcField field, PlcValue plcValue) {
-        Short fieldDataType = ModbusDataType.valueOf(((ModbusField) field).getDataType()).getValue();
+        String fieldDataType = ((ModbusField) field).getDataType();
         try {
             WriteBuffer buffer;
             if(plcValue instanceof PlcList) {
@@ -447,7 +446,7 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
     private PlcValue readBooleanList(int count, byte[] data) throws ParseException {
         ReadBuffer io = new ReadBuffer(data);
         if(count == 1) {
-            return DataItemIO.staticParse(io, (short) 1, (short) 1);
+            return DataItemIO.staticParse(io, "IEC61131_BOOL", (short) 1);
         }
         // Make sure we read in all the bytes. Unfortunately when requesting 9 bytes
         // they are ordered like this: 8 7 6 5 4 3 2 1 | 0 0 0 0 0 0 0 9
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/EvaluationHelper.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/EvaluationHelper.java
index 0b490a5..c8426fe 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/EvaluationHelper.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/EvaluationHelper.java
@@ -38,6 +38,11 @@ public class EvaluationHelper {
             Boolean boolean2 = (Boolean) val2;
             return boolean1.equals(boolean2);
         }
+        if(val1 instanceof String && val2 instanceof String) {
+            String string1 = (String) val1;
+            String string2 = (String) val2;
+            return string1.equals(string2);
+        }
         if(val1.getClass().isEnum() && val2.getClass().isEnum()) {
             return val1.equals(val2);
         }
diff --git a/protocols/knxnetip/src/main/resources/protocols/knxnetip/knxnetip.mspec b/protocols/knxnetip/src/main/resources/protocols/knxnetip/knxnetip.mspec
index d738775..6a09dd7 100644
--- a/protocols/knxnetip/src/main/resources/protocols/knxnetip/knxnetip.mspec
+++ b/protocols/knxnetip/src/main/resources/protocols/knxnetip/knxnetip.mspec
@@ -471,11 +471,11 @@
         ]
         ['4' STRING
             [reserved uint   8 '0x0']
-            [simple   string 8 'UTF-8' 'value']
+            [simple   string 8 'value']
         ]
         ['16' STRING
             [reserved uint   8   '0x0']
-            [simple   string 112 'UTF-8' 'value']
+            [simple   string 112 'value']
         ]
         ['10' Time
             [simple   uint 3 'day']
diff --git a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
index 32df2d2..e7e05f0 100644
--- a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
+++ b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
@@ -270,109 +270,109 @@
     [array      int 8      'recordData'     length  'recordLength']
 ]
 
-[dataIo 'DataItem' [uint 8 'dataType', uint 8 'numberOfValues']
+[dataIo 'DataItem' [string 'dataType', uint 8 'numberOfValues']
     [typeSwitch 'dataType','numberOfValues'
-        ['1','1' BOOL
+        ['IEC61131_BOOL','1' BOOL
             [reserved uint 7 '0x00']
             [simple   bit    'value']
         ]
-        ['1' BOOL
+        ['IEC61131_BOOL' BOOL
             [array bit 'value' count 'numberOfValues']
         ]
-        ['10','1' BYTE
+        ['IEC61131_BYTE','1' BYTE
             [simple uint 8 'value']
         ]
-        ['10' BYTE
+        ['IEC61131_BYTE' BYTE
             [array uint 8 'value' count 'numberOfValues']
         ]
-        ['11','1' WORD
+        ['IEC61131_WORD','1' WORD
             [simple uint 16 'value']
         ]
-        ['11' WORD
+        ['IEC61131_WORD' WORD
             [array uint 16 'value' count 'numberOfValues']
         ]
-        ['12','1' DWORD
+        ['IEC61131_DWORD','1' DWORD
             [simple uint 32 'value']
         ]
-        ['12' DWORD
+        ['IEC61131_DWORD' DWORD
             [array uint 32 'value' count 'numberOfValues']
         ]
-        ['13','1' LWORD
+        ['IEC61131_LWORD','1' LWORD
             [simple uint 64 'value']
         ]
-        ['13' LWORD
+        ['IEC61131_LWORD' LWORD
             [array uint 64 'value' count 'numberOfValues']
         ]
-        ['20','1' SINT
+        ['IEC61131_SINT','1' SINT
             [simple int 8 'value']
         ]
-        ['20' SINT
+        ['IEC61131_SINT' SINT
             [array int 8 'value' count 'numberOfValues']
         ]
-        ['21','1' INT
+        ['IEC61131_INT','1' INT
             [simple int 16 'value']
         ]
-        ['21' INT
+        ['IEC61131_INT' INT
             [array int 16 'value' count 'numberOfValues']
         ]
-        ['22','1' DINT
+        ['IEC61131_DINT','1' DINT
             [simple int 32 'value']
         ]
-        ['22' DINT
+        ['IEC61131_DINT' DINT
             [array int 32 'value' count 'numberOfValues']
         ]
-        ['23','1' LINT
+        ['IEC61131_LINT','1' LINT
             [simple int 64 'value']
         ]
-        ['23' LINT
+        ['IEC61131_LINT' LINT
             [array int 64 'value' count 'numberOfValues']
         ]
-        ['24','1' USINT
+        ['IEC61131_USINT','1' USINT
             [simple uint 8 'value']
         ]
-        ['24' USINT
+        ['IEC61131_USINT' USINT
             [array uint 8 'value' count 'numberOfValues']
         ]
-        ['25','1' UINT
+        ['IEC61131_UINT','1' UINT
             [simple uint 16 'value']
         ]
-        ['25' UINT
+        ['IEC61131_UINT' UINT
             [array uint 16 'value' count 'numberOfValues']
         ]
-        ['26','1' UDINT
+        ['IEC61131_UDINT','1' UDINT
             [simple uint 32 'value']
         ]
-        ['26' UDINT
+        ['IEC61131_UDINT' UDINT
             [array uint 32 'value' count 'numberOfValues']
         ]
-        ['27','1' ULINT
+        ['IEC61131_ULINT','1' ULINT
             [simple uint 64 'value']
         ]
-        ['27' ULINT
+        ['IEC61131_ULINT' ULINT
             [array uint 64 'value' count 'numberOfValues']
         ]
-        ['30','1' REAL
+        ['IEC61131_REAL','1' REAL
             [simple float 8.23  'value']
         ]
-        ['30' REAL
+        ['IEC61131_REAL' REAL
             [array float 8.23 'value' count 'numberOfValues']
         ]
-        ['31','1' LREAL
+        ['IEC61131_LREAL','1' LREAL
             [simple float 11.52  'value']
         ]
-        ['31' LREAL
+        ['IEC61131_LREAL' LREAL
             [array float 11.52 'value' count 'numberOfValues']
         ]
-        ['80','1' CHAR
+        ['IEC61131_CHAR','1' CHAR
             [simple uint 8 'value']
         ]
-        ['80' CHAR
+        ['IEC61131_CHAR' CHAR
             [array uint 8 'value' count 'numberOfValues']
         ]
-        ['81','1' WCHAR
+        ['IEC61131_WCHAR','1' WCHAR
             [simple uint 16 'value']
         ]
-        ['81' WCHAR
+        ['IEC61131_WCHAR' WCHAR
             [array uint 16 'value' count 'numberOfValues']
         ]
     ]
diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index 9aa9298..914c53e 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -334,8 +334,10 @@
         // Characters & Strings
         // -----------------------------------------
         ['41' STRING
+            [manual string 'UTF-8' 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseS7String", io, stringLength, _type.encoding)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeS7String", io, _value, '1', _type.encoding)' '1']
         ]
         ['42' STRING
+            [manual string 'UTF-16' 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseS7String", io, stringLength, _type.encoding)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeS7String", io, _value, '1', _type.encoding)' '2']
         ]
         ['43' STRING
             [manual string 'UTF-8' 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseS7String", io, stringLength, _type.encoding)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeS7String", io, _value, stringLength, _type.encoding)' '_value.length + 2']
@@ -442,7 +444,7 @@
     ['0x0F' DATE_AND_TIME    ['X'              , '12'                , 'null'                  , 'null'                               , '56'                   , 'true'                , 'true'                , 'false'                , 'true'                 , 'false'             ]]
 ]
 
-[enum uint 8 'MemoryArea'             [string 24 'utf8' 'shortName']
+[enum uint 8 'MemoryArea'             [string 24 'shortName']
     ['0x1C' COUNTERS                 ['C']]
     ['0x1D' TIMERS                   ['T']]
     ['0x80' DIRECT_PERIPHERAL_ACCESS ['D']]
diff --git a/sandbox/plc4c/generated-sources/modbus/include/data_item.h b/sandbox/plc4c/generated-sources/modbus/include/data_item.h
index 4a7353a..d26c489 100644
--- a/sandbox/plc4c/generated-sources/modbus/include/data_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/data_item.h
@@ -29,7 +29,7 @@
 extern "C" {
 #endif
 
-plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer* buf, uint8_t dataType, uint8_t numberOfValues, plc4c_data** data_item);
+plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer* buf, char* dataType, uint8_t numberOfValues, plc4c_data** data_item);
 
 plc4c_return_code plc4c_modbus_read_write_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_data** data_item);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/src/data_item.c b/sandbox/plc4c/generated-sources/modbus/src/data_item.c
index ff8d068..a801284 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/data_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/data_item.c
@@ -18,6 +18,7 @@
 */
 
 #include <stdio.h>
+#include <string.h>
 #include <time.h>
 #include <plc4c/data.h>
 #include <plc4c/spi/evaluation_helper.h>
@@ -25,12 +26,12 @@
 #include "data_item.h"
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer* io, uint8_t dataType, uint8_t numberOfValues, plc4c_data** data_item) {
+plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer* io, char* dataType, uint8_t numberOfValues, plc4c_data** data_item) {
     uint16_t startPos = plc4c_spi_read_get_pos(io);
     uint16_t curPos;
     plc4c_return_code _res = OK;
 
-        if((dataType == 1) && (numberOfValues == 1)) { /* BOOL */
+        if((strcmp(dataType, "IEC61131_BOOL") == 0) && (numberOfValues == 1)) { /* BOOL */
 
                 // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
                 {
@@ -54,11 +55,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_bool_data(value);
 
         } else 
-        if(dataType == 1) { /* BOOL */
+        if(strcmp(dataType, "IEC61131_BOOL") == 0) { /* BOOL */
 
                     // Array field (value)
         } else 
-        if((dataType == 10) && (numberOfValues == 1)) { /* BYTE */
+        if((strcmp(dataType, "IEC61131_BYTE") == 0) && (numberOfValues == 1)) { /* BYTE */
 
                 // Simple Field (value)
                 uint8_t value = 0;
@@ -70,11 +71,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint8_t_data(value);
 
         } else 
-        if(dataType == 10) { /* BYTE */
+        if(strcmp(dataType, "IEC61131_BYTE") == 0) { /* BYTE */
 
                     // Array field (value)
         } else 
-        if((dataType == 11) && (numberOfValues == 1)) { /* WORD */
+        if((strcmp(dataType, "IEC61131_WORD") == 0) && (numberOfValues == 1)) { /* WORD */
 
                 // Simple Field (value)
                 uint16_t value = 0;
@@ -86,11 +87,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint16_t_data(value);
 
         } else 
-        if(dataType == 11) { /* WORD */
+        if(strcmp(dataType, "IEC61131_WORD") == 0) { /* WORD */
 
                     // Array field (value)
         } else 
-        if((dataType == 12) && (numberOfValues == 1)) { /* DWORD */
+        if((strcmp(dataType, "IEC61131_DWORD") == 0) && (numberOfValues == 1)) { /* DWORD */
 
                 // Simple Field (value)
                 uint32_t value = 0;
@@ -102,11 +103,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint32_t_data(value);
 
         } else 
-        if(dataType == 12) { /* DWORD */
+        if(strcmp(dataType, "IEC61131_DWORD") == 0) { /* DWORD */
 
                     // Array field (value)
         } else 
-        if((dataType == 13) && (numberOfValues == 1)) { /* LWORD */
+        if((strcmp(dataType, "IEC61131_LWORD") == 0) && (numberOfValues == 1)) { /* LWORD */
 
                 // Simple Field (value)
                 uint64_t value = 0;
@@ -118,11 +119,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint64_t_data(value);
 
         } else 
-        if(dataType == 13) { /* LWORD */
+        if(strcmp(dataType, "IEC61131_LWORD") == 0) { /* LWORD */
 
                     // Array field (value)
         } else 
-        if((dataType == 20) && (numberOfValues == 1)) { /* SINT */
+        if((strcmp(dataType, "IEC61131_SINT") == 0) && (numberOfValues == 1)) { /* SINT */
 
                 // Simple Field (value)
                 int8_t value = 0;
@@ -134,11 +135,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_int8_t_data(value);
 
         } else 
-        if(dataType == 20) { /* SINT */
+        if(strcmp(dataType, "IEC61131_SINT") == 0) { /* SINT */
 
                     // Array field (value)
         } else 
-        if((dataType == 21) && (numberOfValues == 1)) { /* INT */
+        if((strcmp(dataType, "IEC61131_INT") == 0) && (numberOfValues == 1)) { /* INT */
 
                 // Simple Field (value)
                 int16_t value = 0;
@@ -150,11 +151,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_int16_t_data(value);
 
         } else 
-        if(dataType == 21) { /* INT */
+        if(strcmp(dataType, "IEC61131_INT") == 0) { /* INT */
 
                     // Array field (value)
         } else 
-        if((dataType == 22) && (numberOfValues == 1)) { /* DINT */
+        if((strcmp(dataType, "IEC61131_DINT") == 0) && (numberOfValues == 1)) { /* DINT */
 
                 // Simple Field (value)
                 int32_t value = 0;
@@ -166,11 +167,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_int32_t_data(value);
 
         } else 
-        if(dataType == 22) { /* DINT */
+        if(strcmp(dataType, "IEC61131_DINT") == 0) { /* DINT */
 
                     // Array field (value)
         } else 
-        if((dataType == 23) && (numberOfValues == 1)) { /* LINT */
+        if((strcmp(dataType, "IEC61131_LINT") == 0) && (numberOfValues == 1)) { /* LINT */
 
                 // Simple Field (value)
                 int64_t value = 0;
@@ -182,11 +183,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_int64_t_data(value);
 
         } else 
-        if(dataType == 23) { /* LINT */
+        if(strcmp(dataType, "IEC61131_LINT") == 0) { /* LINT */
 
                     // Array field (value)
         } else 
-        if((dataType == 24) && (numberOfValues == 1)) { /* USINT */
+        if((strcmp(dataType, "IEC61131_USINT") == 0) && (numberOfValues == 1)) { /* USINT */
 
                 // Simple Field (value)
                 uint8_t value = 0;
@@ -198,11 +199,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint8_t_data(value);
 
         } else 
-        if(dataType == 24) { /* USINT */
+        if(strcmp(dataType, "IEC61131_USINT") == 0) { /* USINT */
 
                     // Array field (value)
         } else 
-        if((dataType == 25) && (numberOfValues == 1)) { /* UINT */
+        if((strcmp(dataType, "IEC61131_UINT") == 0) && (numberOfValues == 1)) { /* UINT */
 
                 // Simple Field (value)
                 uint16_t value = 0;
@@ -214,11 +215,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint16_t_data(value);
 
         } else 
-        if(dataType == 25) { /* UINT */
+        if(strcmp(dataType, "IEC61131_UINT") == 0) { /* UINT */
 
                     // Array field (value)
         } else 
-        if((dataType == 26) && (numberOfValues == 1)) { /* UDINT */
+        if((strcmp(dataType, "IEC61131_UDINT") == 0) && (numberOfValues == 1)) { /* UDINT */
 
                 // Simple Field (value)
                 uint32_t value = 0;
@@ -230,11 +231,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint32_t_data(value);
 
         } else 
-        if(dataType == 26) { /* UDINT */
+        if(strcmp(dataType, "IEC61131_UDINT") == 0) { /* UDINT */
 
                     // Array field (value)
         } else 
-        if((dataType == 27) && (numberOfValues == 1)) { /* ULINT */
+        if((strcmp(dataType, "IEC61131_ULINT") == 0) && (numberOfValues == 1)) { /* ULINT */
 
                 // Simple Field (value)
                 uint64_t value = 0;
@@ -246,11 +247,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint64_t_data(value);
 
         } else 
-        if(dataType == 27) { /* ULINT */
+        if(strcmp(dataType, "IEC61131_ULINT") == 0) { /* ULINT */
 
                     // Array field (value)
         } else 
-        if((dataType == 30) && (numberOfValues == 1)) { /* REAL */
+        if((strcmp(dataType, "IEC61131_REAL") == 0) && (numberOfValues == 1)) { /* REAL */
 
                 // Simple Field (value)
                 float value = 0.0;
@@ -262,11 +263,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_float_data(value);
 
         } else 
-        if(dataType == 30) { /* REAL */
+        if(strcmp(dataType, "IEC61131_REAL") == 0) { /* REAL */
 
                     // Array field (value)
         } else 
-        if((dataType == 31) && (numberOfValues == 1)) { /* LREAL */
+        if((strcmp(dataType, "IEC61131_LREAL") == 0) && (numberOfValues == 1)) { /* LREAL */
 
                 // Simple Field (value)
                 double value = 0.0;
@@ -278,11 +279,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_double_data(value);
 
         } else 
-        if(dataType == 31) { /* LREAL */
+        if(strcmp(dataType, "IEC61131_LREAL") == 0) { /* LREAL */
 
                     // Array field (value)
         } else 
-        if((dataType == 80) && (numberOfValues == 1)) { /* CHAR */
+        if((strcmp(dataType, "IEC61131_CHAR") == 0) && (numberOfValues == 1)) { /* CHAR */
 
                 // Simple Field (value)
                 uint8_t value = 0;
@@ -294,11 +295,11 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint8_t_data(value);
 
         } else 
-        if(dataType == 80) { /* CHAR */
+        if(strcmp(dataType, "IEC61131_CHAR") == 0) { /* CHAR */
 
                     // Array field (value)
         } else 
-        if((dataType == 81) && (numberOfValues == 1)) { /* WCHAR */
+        if((strcmp(dataType, "IEC61131_WCHAR") == 0) && (numberOfValues == 1)) { /* WCHAR */
 
                 // Simple Field (value)
                 uint16_t value = 0;
@@ -310,7 +311,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                 *data_item = plc4c_data_create_uint16_t_data(value);
 
         } else 
-        if(dataType == 81) { /* WCHAR */
+        if(strcmp(dataType, "IEC61131_WCHAR") == 0) { /* WCHAR */
 
                     // Array field (value)
         }
diff --git a/sandbox/plc4c/generated-sources/s7/src/data_item.c b/sandbox/plc4c/generated-sources/s7/src/data_item.c
index ae82761..9cfb060 100644
--- a/sandbox/plc4c/generated-sources/s7/src/data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/data_item.c
@@ -18,6 +18,7 @@
 */
 
 #include <stdio.h>
+#include <string.h>
 #include <time.h>
 #include <plc4c/data.h>
 #include <plc4c/spi/evaluation_helper.h>
@@ -190,10 +191,6 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                 *data_item = plc4c_data_create_double_data(value);
 
         } else 
-        if(dataProtocolId == 41) { /* STRING */
-        } else 
-        if(dataProtocolId == 42) { /* STRING */
-        } else 
         if(dataProtocolId == 43) { /* STRING */
 
                     // Manual Field (value)
diff --git a/sandbox/plc4go/cmd/main/drivers/modbus_test.go b/sandbox/plc4go/cmd/main/drivers/modbus_test.go
index 097c059..a96e8b0 100644
--- a/sandbox/plc4go/cmd/main/drivers/modbus_test.go
+++ b/sandbox/plc4go/cmd/main/drivers/modbus_test.go
@@ -20,7 +20,6 @@ package drivers
 
 import (
     "encoding/hex"
-    "encoding/json"
     "fmt"
     "net"
     "os"
@@ -146,7 +145,7 @@ func TestPlc4goDriver(t *testing.T) {
 
 	// Prepare a read-request
 	rrb := connection.ReadRequestBuilder()
-	rrb.AddItem("field", "holding-register:1:REAL[2]")
+	rrb.AddItem("field", "holding-register:0:UINT[2]")
 	readRequest, err := rrb.Build()
 	if err != nil {
 		t.Errorf("error preparing read-request: %s", connectionResult.Err.Error())
@@ -164,10 +163,7 @@ func TestPlc4goDriver(t *testing.T) {
 	}
 
 	// Do something with the response
-	readResponseJson, err := json.Marshal(rrr.Response)
-	if err != nil {
-		t.Errorf("error serializing read-response: %s", err.Error())
-		return
-	}
-	fmt.Printf("Result: %s\n", string(readResponseJson))
+    value := rrr.Response.GetValue("field")
+
+	fmt.Printf("\n\nResult: %d\n", value.GetInt32())
 }
diff --git a/sandbox/plc4go/go.mod b/sandbox/plc4go/go.mod
index 417cc48..12ff77e 100644
--- a/sandbox/plc4go/go.mod
+++ b/sandbox/plc4go/go.mod
@@ -23,6 +23,5 @@ go 1.15
 require github.com/sirupsen/logrus v1.7.0
 
 require (
-	github.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259
 	github.com/icza/bitio v1.0.0
 )
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxDatapoint.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxDatapoint.go
new file mode 100644
index 0000000..a6a6ef3
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxDatapoint.go
@@ -0,0 +1,559 @@
+//
+// 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 model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
+)
+
+func KnxDatapointParse(io *spi.ReadBuffer, mainNumber uint16, subNumber uint16) (api.PlcValue, error) {
+    switch {
+        case mainNumber == 1: // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(7)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadBit()
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcBOOL(value), nil
+        case mainNumber == 2: // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(6)
+
+            // Simple Field (control)
+            _, _controlErr := io.ReadBit()
+            if _controlErr != nil {
+                return nil, errors.New("Error parsing 'control' field " + _controlErr.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadBit()
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcBOOL(value), nil
+        case mainNumber == 21: // Struct
+            _map := map[string]interface{}{}
+
+            // Simple Field (b7)
+            b7, _b7Err := io.ReadBit()
+            if _b7Err != nil {
+                return nil, errors.New("Error parsing 'b7' field " + _b7Err.Error())
+            }
+            _map["Struct"] = b7
+
+            // Simple Field (b6)
+            b6, _b6Err := io.ReadBit()
+            if _b6Err != nil {
+                return nil, errors.New("Error parsing 'b6' field " + _b6Err.Error())
+            }
+            _map["Struct"] = b6
+
+            // Simple Field (b5)
+            b5, _b5Err := io.ReadBit()
+            if _b5Err != nil {
+                return nil, errors.New("Error parsing 'b5' field " + _b5Err.Error())
+            }
+            _map["Struct"] = b5
+
+            // Simple Field (b4)
+            b4, _b4Err := io.ReadBit()
+            if _b4Err != nil {
+                return nil, errors.New("Error parsing 'b4' field " + _b4Err.Error())
+            }
+            _map["Struct"] = b4
+
+            // Simple Field (b3)
+            b3, _b3Err := io.ReadBit()
+            if _b3Err != nil {
+                return nil, errors.New("Error parsing 'b3' field " + _b3Err.Error())
+            }
+            _map["Struct"] = b3
+
+            // Simple Field (b2)
+            b2, _b2Err := io.ReadBit()
+            if _b2Err != nil {
+                return nil, errors.New("Error parsing 'b2' field " + _b2Err.Error())
+            }
+            _map["Struct"] = b2
+
+            // Simple Field (b1)
+            b1, _b1Err := io.ReadBit()
+            if _b1Err != nil {
+                return nil, errors.New("Error parsing 'b1' field " + _b1Err.Error())
+            }
+            _map["Struct"] = b1
+
+            // Simple Field (b0)
+            b0, _b0Err := io.ReadBit()
+            if _b0Err != nil {
+                return nil, errors.New("Error parsing 'b0' field " + _b0Err.Error())
+            }
+            _map["Struct"] = b0
+        case mainNumber == 3: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(4)
+
+            // Simple Field (control)
+            _, _controlErr := io.ReadBit()
+            if _controlErr != nil {
+                return nil, errors.New("Error parsing 'control' field " + _controlErr.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(3)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case mainNumber == 18: // USINT
+
+            // Simple Field (control)
+            _, _controlErr := io.ReadBit()
+            if _controlErr != nil {
+                return nil, errors.New("Error parsing 'control' field " + _controlErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(1)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(6)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case mainNumber == 17: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(2)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(6)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case mainNumber == 5: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case mainNumber == 7: // UINT
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUINT(value), nil
+        case mainNumber == 12: // UDINT
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUDINT(value), nil
+        case mainNumber == 6 && subNumber == 20: // SINT
+
+            // Simple Field (a)
+            _, _aErr := io.ReadBit()
+            if _aErr != nil {
+                return nil, errors.New("Error parsing 'a' field " + _aErr.Error())
+            }
+
+            // Simple Field (b)
+            _, _bErr := io.ReadBit()
+            if _bErr != nil {
+                return nil, errors.New("Error parsing 'b' field " + _bErr.Error())
+            }
+
+            // Simple Field (c)
+            _, _cErr := io.ReadBit()
+            if _cErr != nil {
+                return nil, errors.New("Error parsing 'c' field " + _cErr.Error())
+            }
+
+            // Simple Field (d)
+            _, _dErr := io.ReadBit()
+            if _dErr != nil {
+                return nil, errors.New("Error parsing 'd' field " + _dErr.Error())
+            }
+
+            // Simple Field (e)
+            _, _eErr := io.ReadBit()
+            if _eErr != nil {
+                return nil, errors.New("Error parsing 'e' field " + _eErr.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSINT(value), nil
+        case mainNumber == 6: // SINT
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSINT(value), nil
+        case mainNumber == 8: // INT
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcINT(value), nil
+        case mainNumber == 13: // DINT
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcDINT(value), nil
+        case mainNumber == 9: // REAL
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Manual Field (value)
+            value, _valueErr := KnxHelperBytesToF16(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcREAL(value), nil
+        case mainNumber == 14: // REAL
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadFloat32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcREAL(value), nil
+        case mainNumber == 4: // STRING
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadString(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSTRING(value), nil
+        case mainNumber == 16: // STRING
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(8)
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadString(112)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSTRING(value), nil
+        case mainNumber == 10: // Time
+
+            // Simple Field (day)
+            _, _dayErr := io.ReadUint8(3)
+            if _dayErr != nil {
+                return nil, errors.New("Error parsing 'day' field " + _dayErr.Error())
+            }
+
+            // Simple Field (hours)
+            _, _hoursErr := io.ReadUint8(5)
+            if _hoursErr != nil {
+                return nil, errors.New("Error parsing 'hours' field " + _hoursErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(2)
+
+            // Simple Field (minutes)
+            _, _minutesErr := io.ReadUint8(6)
+            if _minutesErr != nil {
+                return nil, errors.New("Error parsing 'minutes' field " + _minutesErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(2)
+
+            // Simple Field (seconds)
+            _, _secondsErr := io.ReadUint8(6)
+            if _secondsErr != nil {
+                return nil, errors.New("Error parsing 'seconds' field " + _secondsErr.Error())
+            }
+        case mainNumber == 11: // Date
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(3)
+
+            // Simple Field (day)
+            _, _dayErr := io.ReadUint8(5)
+            if _dayErr != nil {
+                return nil, errors.New("Error parsing 'day' field " + _dayErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(4)
+
+            // Simple Field (month)
+            _, _monthErr := io.ReadUint8(4)
+            if _monthErr != nil {
+                return nil, errors.New("Error parsing 'month' field " + _monthErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(1)
+
+            // Simple Field (year)
+            _, _yearErr := io.ReadUint8(6)
+            if _yearErr != nil {
+                return nil, errors.New("Error parsing 'year' field " + _yearErr.Error())
+            }
+        case mainNumber == 19: // DateTime
+
+            // Simple Field (year)
+            _, _yearErr := io.ReadUint8(8)
+            if _yearErr != nil {
+                return nil, errors.New("Error parsing 'year' field " + _yearErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(4)
+
+            // Simple Field (month)
+            _, _monthErr := io.ReadUint8(4)
+            if _monthErr != nil {
+                return nil, errors.New("Error parsing 'month' field " + _monthErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(3)
+
+            // Simple Field (day)
+            _, _dayErr := io.ReadUint8(5)
+            if _dayErr != nil {
+                return nil, errors.New("Error parsing 'day' field " + _dayErr.Error())
+            }
+
+            // Simple Field (dayOfWeek)
+            _, _dayOfWeekErr := io.ReadUint8(3)
+            if _dayOfWeekErr != nil {
+                return nil, errors.New("Error parsing 'dayOfWeek' field " + _dayOfWeekErr.Error())
+            }
+
+            // Simple Field (hours)
+            _, _hoursErr := io.ReadUint8(5)
+            if _hoursErr != nil {
+                return nil, errors.New("Error parsing 'hours' field " + _hoursErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(2)
+
+            // Simple Field (minutes)
+            _, _minutesErr := io.ReadUint8(6)
+            if _minutesErr != nil {
+                return nil, errors.New("Error parsing 'minutes' field " + _minutesErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(2)
+
+            // Simple Field (seconds)
+            _, _secondsErr := io.ReadUint8(6)
+            if _secondsErr != nil {
+                return nil, errors.New("Error parsing 'seconds' field " + _secondsErr.Error())
+            }
+
+            // Simple Field (fault)
+            _, _faultErr := io.ReadBit()
+            if _faultErr != nil {
+                return nil, errors.New("Error parsing 'fault' field " + _faultErr.Error())
+            }
+
+            // Simple Field (workingDay)
+            _, _workingDayErr := io.ReadBit()
+            if _workingDayErr != nil {
+                return nil, errors.New("Error parsing 'workingDay' field " + _workingDayErr.Error())
+            }
+
+            // Simple Field (workingDayValid)
+            _, _workingDayValidErr := io.ReadBit()
+            if _workingDayValidErr != nil {
+                return nil, errors.New("Error parsing 'workingDayValid' field " + _workingDayValidErr.Error())
+            }
+
+            // Simple Field (yearValid)
+            _, _yearValidErr := io.ReadBit()
+            if _yearValidErr != nil {
+                return nil, errors.New("Error parsing 'yearValid' field " + _yearValidErr.Error())
+            }
+
+            // Simple Field (dayAndMonthValid)
+            _, _dayAndMonthValidErr := io.ReadBit()
+            if _dayAndMonthValidErr != nil {
+                return nil, errors.New("Error parsing 'dayAndMonthValid' field " + _dayAndMonthValidErr.Error())
+            }
+
+            // Simple Field (dayOfWeekValid)
+            _, _dayOfWeekValidErr := io.ReadBit()
+            if _dayOfWeekValidErr != nil {
+                return nil, errors.New("Error parsing 'dayOfWeekValid' field " + _dayOfWeekValidErr.Error())
+            }
+
+            // Simple Field (timeValid)
+            _, _timeValidErr := io.ReadBit()
+            if _timeValidErr != nil {
+                return nil, errors.New("Error parsing 'timeValid' field " + _timeValidErr.Error())
+            }
+
+            // Simple Field (standardSummerTime)
+            _, _standardSummerTimeErr := io.ReadBit()
+            if _standardSummerTimeErr != nil {
+                return nil, errors.New("Error parsing 'standardSummerTime' field " + _standardSummerTimeErr.Error())
+            }
+
+            // Simple Field (clockQuality)
+            _, _clockQualityErr := io.ReadBit()
+            if _clockQualityErr != nil {
+                return nil, errors.New("Error parsing 'clockQuality' field " + _clockQualityErr.Error())
+            }
+        case mainNumber == 15: // Struct
+            _map := map[string]interface{}{}
+
+            // Simple Field (D6)
+            D6, _D6Err := io.ReadUint8(4)
+            if _D6Err != nil {
+                return nil, errors.New("Error parsing 'D6' field " + _D6Err.Error())
+            }
+            _map["Struct"] = D6
+
+            // Simple Field (D5)
+            D5, _D5Err := io.ReadUint8(4)
+            if _D5Err != nil {
+                return nil, errors.New("Error parsing 'D5' field " + _D5Err.Error())
+            }
+            _map["Struct"] = D5
+
+            // Simple Field (D4)
+            D4, _D4Err := io.ReadUint8(4)
+            if _D4Err != nil {
+                return nil, errors.New("Error parsing 'D4' field " + _D4Err.Error())
+            }
+            _map["Struct"] = D4
+
+            // Simple Field (D3)
+            D3, _D3Err := io.ReadUint8(4)
+            if _D3Err != nil {
+                return nil, errors.New("Error parsing 'D3' field " + _D3Err.Error())
+            }
+            _map["Struct"] = D3
+
+            // Simple Field (D2)
+            D2, _D2Err := io.ReadUint8(4)
+            if _D2Err != nil {
+                return nil, errors.New("Error parsing 'D2' field " + _D2Err.Error())
+            }
+            _map["Struct"] = D2
+
+            // Simple Field (D1)
+            D1, _D1Err := io.ReadUint8(4)
+            if _D1Err != nil {
+                return nil, errors.New("Error parsing 'D1' field " + _D1Err.Error())
+            }
+            _map["Struct"] = D1
+
+            // Simple Field (BE)
+            BE, _BEErr := io.ReadBit()
+            if _BEErr != nil {
+                return nil, errors.New("Error parsing 'BE' field " + _BEErr.Error())
+            }
+            _map["Struct"] = BE
+
+            // Simple Field (BP)
+            BP, _BPErr := io.ReadBit()
+            if _BPErr != nil {
+                return nil, errors.New("Error parsing 'BP' field " + _BPErr.Error())
+            }
+            _map["Struct"] = BP
+
+            // Simple Field (BD)
+            BD, _BDErr := io.ReadBit()
+            if _BDErr != nil {
+                return nil, errors.New("Error parsing 'BD' field " + _BDErr.Error())
+            }
+            _map["Struct"] = BD
+
+            // Simple Field (BC)
+            BC, _BCErr := io.ReadBit()
+            if _BCErr != nil {
+                return nil, errors.New("Error parsing 'BC' field " + _BCErr.Error())
+            }
+            _map["Struct"] = BC
+
+            // Simple Field (index)
+            index, _indexErr := io.ReadUint8(4)
+            if _indexErr != nil {
+                return nil, errors.New("Error parsing 'index' field " + _indexErr.Error())
+            }
+            _map["Struct"] = index
+    }
+    return nil, errors.New("unsupported type")
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxStaticHelper.go
similarity index 56%
copy from sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go
copy to sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxStaticHelper.go
index 360c8e9..7956658 100644
--- a/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxStaticHelper.go
@@ -19,16 +19,28 @@
 package model
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/model"
-    "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
+    "math"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
 )
 
-type DefaultPlcReadResponse struct {
-	values map[string]values.PlcValue
-	model.PlcReadResponse
+func KnxHelperBytesToF16(io *spi.ReadBuffer) (float32, error) {
+    negative, err := io.ReadBit()
+    if err != nil {
+        return 0.0, err
+    }
+    exponent, err := io.ReadUint64(4)
+    if err != nil {
+        return 0.0, err
+    }
+    mantissa, err := io.ReadUint64(11)
+    if err != nil {
+        return 0.0, err
+    }
+    mantissaPart := 0.01 * float32(mantissa)
+    powPart := math.Pow(float64(2), float64(exponent))
+    if negative {
+        return -1 * mantissaPart * float32(powPart), nil
+    } else {
+        return mantissaPart * float32(powPart), nil
+    }
 }
-
-func (m DefaultPlcReadResponse) GetValue(name string) values.PlcValue {
-    return m.values[name]
-}
-
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusFieldHandler.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusFieldHandler.go
index 3781d92..746b6a2 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusFieldHandler.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusFieldHandler.go
@@ -67,25 +67,25 @@ func NewFieldHandler() FieldHandler {
 
 func (m FieldHandler) ParseQuery(query string) (model.PlcField, error) {
 	if match := utils.GetSubgropMatches(m.plc4xCoilPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_COIL, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_COIL, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.numericCoilPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_COIL, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_COIL, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.plc4xDiscreteInputPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_DISCRETE_INPUT, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_DISCRETE_INPUT, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.numericDiscreteInputPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_DISCRETE_INPUT, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_DISCRETE_INPUT, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.plc4xInputRegisterPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_INPUT_REGISTER, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_INPUT_REGISTER, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.numericInputRegisterPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_INPUT_REGISTER, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_INPUT_REGISTER, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.plc4xHoldingRegisterPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_HOLDING_REGISTER, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_HOLDING_REGISTER, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.numericHoldingRegisterPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_HOLDING_REGISTER, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_HOLDING_REGISTER, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.plc4xExtendedRegisterPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_EXTENDED_REGISTER, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_EXTENDED_REGISTER, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	} else if match := utils.GetSubgropMatches(m.numericExtendedRegisterPattern, query); match != nil {
-		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_EXTENDED_REGISTER, match["address"], match["quantity"], match["datatype"])
+		return NewModbusPlcFieldFromStrings(MODBUS_FIELD_EXTENDED_REGISTER, match["address"], match["quantity"], "IEC61131_" + match["datatype"])
 	}
 	return nil, errors.New("Invalid address format for address '" + query + "'")
 }
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
index 9e58c8d..1413327 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
@@ -26,6 +26,7 @@ import (
     plc4goModel "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model"
     "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
     "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/model"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
     "sync/atomic"
 )
 
@@ -134,11 +135,18 @@ func (m ModbusReader) Read(readRequest model.PlcReadRequest) <-chan model.PlcRea
             // Convert the response into an ADU
             responseAdu := modbusModel.CastModbusTcpADU(response)
             // Convert the modbus response into a PLC4X response
-            readResponse := toPlc4xResponse(requestAdu, responseAdu, readRequest)
+            readResponse, err := toPlc4xResponse(requestAdu, responseAdu, readRequest)
 
-            result <- model.PlcReadRequestResult{
-                Request: readRequest,
-                Response: readResponse,
+            if err != nil {
+                result <- model.PlcReadRequestResult{
+                    Request: readRequest,
+                    Err: errors.New("Error decoding response: " + err.Error()),
+                }
+            } else {
+                result <- model.PlcReadRequestResult{
+                    Request:  readRequest,
+                    Response: readResponse,
+                }
             }
         }()
     } else {
@@ -152,7 +160,7 @@ func (m ModbusReader) Read(readRequest model.PlcReadRequest) <-chan model.PlcRea
 	return result
 }
 
-func toPlc4xResponse(requestAdu modbusModel.ModbusTcpADU, responseAdu modbusModel.ModbusTcpADU, readRequest model.PlcReadRequest) model.PlcReadResponse {
+func toPlc4xResponse(requestAdu modbusModel.ModbusTcpADU, responseAdu modbusModel.ModbusTcpADU, readRequest model.PlcReadRequest) (model.PlcReadResponse,error) {
     switch responseAdu.Pdu.(type) {
     case modbusModel.ModbusPDUReadDiscreteInputsResponse:
         pdu := modbusModel.CastModbusPDUReadDiscreteInputsResponse(responseAdu.Pdu)
@@ -176,10 +184,14 @@ func toPlc4xResponse(requestAdu modbusModel.ModbusTcpADU, responseAdu modbusMode
         fieldName := readRequest.GetFieldNames()[0]
         field := readRequest.GetField(fieldName)
 
-        modbusModel.DataItemParse(rb, )
-        fmt.Printf("ModbusPDUReadHoldingRegistersResponse %d", pdu)
-        // DataIo ...
+        value, err := modbusModel.DataItemParse(rb, field.GetTypeName(), 1)
+        if err != nil {
+            return nil, err
+        }
+        values := map[string]values.PlcValue{}
+        values[fieldName] = value
+        return plc4goModel.NewDefaultPlcReadResponse(values), nil
     }
-    return plc4goModel.DefaultPlcReadResponse{}
+    return nil, errors.New("unsupported response type")
 }
 
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusValueHandler.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusValueHandler.go
index 212f827..c307424 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusValueHandler.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusValueHandler.go
@@ -19,11 +19,11 @@
 package modbus
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values/iec61131"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
 )
 
 type ValueHandler struct {
-	iec61131.IEC61131ValueHandler
+    values.IEC61131ValueHandler
 }
 
 func NewValueHandler() ValueHandler {
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go
index 771ff8e..3329e41 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go
@@ -21,231 +21,232 @@ package model
 import (
     "errors"
     "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values/iec61131"
     "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
     api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
 )
 
-func DataItemParse(io *spi.ReadBuffer, dataType uint8, numberOfValues uint8) (api.PlcValue, error) {
+func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (api.PlcValue, error) {
     switch {
-        case dataType == 1 && numberOfValues == 1: // BOOL
+        case dataType == "IEC61131_BOOL" && numberOfValues == 1: // BOOL
 
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(7)
 
             // Simple Field (value)
             value, _valueErr := io.ReadBit()
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcBOOL(value), nil
-        case dataType == 1: // BOOL
+            return values.NewPlcBOOL(value), nil
+        case dataType == "IEC61131_BOOL": // BOOL
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 10 && numberOfValues == 1: // BYTE
+        case dataType == "IEC61131_BYTE" && numberOfValues == 1: // BYTE
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint8(8)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcBYTE(value), nil
-        case dataType == 10: // BYTE
+            return values.NewPlcBYTE(value), nil
+        case dataType == "IEC61131_BYTE": // BYTE
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 11 && numberOfValues == 1: // WORD
+        case dataType == "IEC61131_WORD" && numberOfValues == 1: // WORD
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint16(16)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcWORD(value), nil
-        case dataType == 11: // WORD
+            return values.NewPlcWORD(value), nil
+        case dataType == "IEC61131_WORD": // WORD
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 12 && numberOfValues == 1: // DWORD
+        case dataType == "IEC61131_DWORD" && numberOfValues == 1: // DWORD
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint32(32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcDWORD(value), nil
-        case dataType == 12: // DWORD
+            return values.NewPlcDWORD(value), nil
+        case dataType == "IEC61131_DWORD": // DWORD
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 13 && numberOfValues == 1: // LWORD
+        case dataType == "IEC61131_LWORD" && numberOfValues == 1: // LWORD
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint64(64)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcLWORD(value), nil
-        case dataType == 13: // LWORD
+            return values.NewPlcLWORD(value), nil
+        case dataType == "IEC61131_LWORD": // LWORD
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 20 && numberOfValues == 1: // SINT
+        case dataType == "IEC61131_SINT" && numberOfValues == 1: // SINT
 
             // Simple Field (value)
             value, _valueErr := io.ReadInt8(8)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcSINT(value), nil
-        case dataType == 20: // SINT
+            return values.NewPlcSINT(value), nil
+        case dataType == "IEC61131_SINT": // SINT
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 21 && numberOfValues == 1: // INT
+        case dataType == "IEC61131_INT" && numberOfValues == 1: // INT
 
             // Simple Field (value)
             value, _valueErr := io.ReadInt16(16)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcINT(value), nil
-        case dataType == 21: // INT
+            return values.NewPlcINT(value), nil
+        case dataType == "IEC61131_INT": // INT
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 22 && numberOfValues == 1: // DINT
+        case dataType == "IEC61131_DINT" && numberOfValues == 1: // DINT
 
             // Simple Field (value)
             value, _valueErr := io.ReadInt32(32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcDINT(value), nil
-        case dataType == 22: // DINT
+            return values.NewPlcDINT(value), nil
+        case dataType == "IEC61131_DINT": // DINT
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 23 && numberOfValues == 1: // LINT
+        case dataType == "IEC61131_LINT" && numberOfValues == 1: // LINT
 
             // Simple Field (value)
             value, _valueErr := io.ReadInt64(64)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcLINT(value), nil
-        case dataType == 23: // LINT
+            return values.NewPlcLINT(value), nil
+        case dataType == "IEC61131_LINT": // LINT
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 24 && numberOfValues == 1: // USINT
+        case dataType == "IEC61131_USINT" && numberOfValues == 1: // USINT
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint8(8)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcUSINT(value), nil
-        case dataType == 24: // USINT
+            return values.NewPlcUSINT(value), nil
+        case dataType == "IEC61131_USINT": // USINT
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 25 && numberOfValues == 1: // UINT
+        case dataType == "IEC61131_UINT" && numberOfValues == 1: // UINT
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint16(16)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcUINT(value), nil
-        case dataType == 25: // UINT
+            return values.NewPlcUINT(value), nil
+        case dataType == "IEC61131_UINT": // UINT
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 26 && numberOfValues == 1: // UDINT
+        case dataType == "IEC61131_UDINT" && numberOfValues == 1: // UDINT
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint32(32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcUDINT(value), nil
-        case dataType == 26: // UDINT
+            return values.NewPlcUDINT(value), nil
+        case dataType == "IEC61131_UDINT": // UDINT
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 27 && numberOfValues == 1: // ULINT
+        case dataType == "IEC61131_ULINT" && numberOfValues == 1: // ULINT
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint64(64)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcULINT(value), nil
-        case dataType == 27: // ULINT
+            return values.NewPlcULINT(value), nil
+        case dataType == "IEC61131_ULINT": // ULINT
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 30 && numberOfValues == 1: // REAL
+        case dataType == "IEC61131_REAL" && numberOfValues == 1: // REAL
 
             // Simple Field (value)
             value, _valueErr := io.ReadFloat32(32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcREAL(value), nil
-        case dataType == 30: // REAL
+            return values.NewPlcREAL(value), nil
+        case dataType == "IEC61131_REAL": // REAL
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 31 && numberOfValues == 1: // LREAL
+        case dataType == "IEC61131_LREAL" && numberOfValues == 1: // LREAL
 
             // Simple Field (value)
             value, _valueErr := io.ReadFloat64(64)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcLREAL(value), nil
-        case dataType == 31: // LREAL
+            return values.NewPlcLREAL(value), nil
+        case dataType == "IEC61131_LREAL": // LREAL
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 80 && numberOfValues == 1: // CHAR
+        case dataType == "IEC61131_CHAR" && numberOfValues == 1: // CHAR
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint8(8)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcCHAR(value), nil
-        case dataType == 80: // CHAR
+            return values.NewPlcCHAR(value), nil
+        case dataType == "IEC61131_CHAR": // CHAR
 
             // Array Field (value)
             var value []api.PlcValue
             return values.NewPlcList(value), nil
-        case dataType == 81 && numberOfValues == 1: // WCHAR
+        case dataType == "IEC61131_WCHAR" && numberOfValues == 1: // WCHAR
 
             // Simple Field (value)
             value, _valueErr := io.ReadUint16(16)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcWCHAR(value), nil
-        case dataType == 81: // WCHAR
+            return values.NewPlcWCHAR(value), nil
+        case dataType == "IEC61131_WCHAR": // WCHAR
 
             // Array Field (value)
             var value []api.PlcValue
diff --git a/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go b/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go
index 360c8e9..2a68bfb 100644
--- a/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go
+++ b/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go
@@ -28,6 +28,12 @@ type DefaultPlcReadResponse struct {
 	model.PlcReadResponse
 }
 
+func NewDefaultPlcReadResponse(values map[string]values.PlcValue) DefaultPlcReadResponse {
+    return DefaultPlcReadResponse {
+        values: values,
+    }
+}
+
 func (m DefaultPlcReadResponse) GetValue(name string) values.PlcValue {
     return m.values[name]
 }
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/BOOL.go b/sandbox/plc4go/internal/plc4go/model/values/BOOL.go
similarity index 90%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/BOOL.go
rename to sandbox/plc4go/internal/plc4go/model/values/BOOL.go
index 2f33809..48c1a6b 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/BOOL.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/BOOL.go
@@ -16,15 +16,11 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-)
+package values
 
 type PlcBOOL struct {
 	value bool
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcBOOL(value bool) PlcBOOL {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/BYTE.go b/sandbox/plc4go/internal/plc4go/model/values/BYTE.go
similarity index 91%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/BYTE.go
rename to sandbox/plc4go/internal/plc4go/model/values/BYTE.go
index a0f34f0..41e9ea6 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/BYTE.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/BYTE.go
@@ -16,13 +16,11 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+package values
 
 type PlcBYTE struct {
 	value uint8
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcBYTE(value uint8) PlcBYTE {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/CHAR.go b/sandbox/plc4go/internal/plc4go/model/values/CHAR.go
similarity index 89%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/CHAR.go
rename to sandbox/plc4go/internal/plc4go/model/values/CHAR.go
index c0a3ac2..37c0751 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/CHAR.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/CHAR.go
@@ -16,13 +16,11 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+package values
 
 type PlcCHAR struct {
 	value []byte
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcCHAR(value uint8) PlcCHAR {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/DATE.go b/sandbox/plc4go/internal/plc4go/model/values/DATE.go
similarity index 90%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/DATE.go
rename to sandbox/plc4go/internal/plc4go/model/values/DATE.go
index babee04..f6274a6 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/DATE.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/DATE.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-	"time"
+    "time"
 )
 
 type PlcDATE struct {
 	value time.Time
-	values.PlcValueAdapter
+    PlcValueAdapter
 }
 
 func NewPlcDATE(value time.Time) PlcDATE {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/DATE_AND_TIME.go b/sandbox/plc4go/internal/plc4go/model/values/DATE_AND_TIME.go
similarity index 89%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/DATE_AND_TIME.go
rename to sandbox/plc4go/internal/plc4go/model/values/DATE_AND_TIME.go
index d3c89db..665a941 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/DATE_AND_TIME.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/DATE_AND_TIME.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-	"time"
+    "time"
 )
 
 type PlcDATEANDTIME struct {
 	value time.Time
-	values.PlcValueAdapter
+    PlcValueAdapter
 }
 
 func NewPlcDATEANDTIME(value time.Time) PlcDATEANDTIME {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/DINT.go b/sandbox/plc4go/internal/plc4go/model/values/DINT.go
similarity index 94%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/DINT.go
rename to sandbox/plc4go/internal/plc4go/model/values/DINT.go
index 7964f86..80ff2cb 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/DINT.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/DINT.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcDINT struct {
 	value int32
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcDINT(value int32) PlcDINT {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/DWORD.go b/sandbox/plc4go/internal/plc4go/model/values/DWORD.go
similarity index 93%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/DWORD.go
rename to sandbox/plc4go/internal/plc4go/model/values/DWORD.go
index 2671b33..e50ad54 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/DWORD.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/DWORD.go
@@ -16,13 +16,11 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+package values
 
 type PlcDWORD struct {
 	value uint32
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcDWORD(value uint32) PlcDWORD {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/IEC61131ValueHandler.go b/sandbox/plc4go/internal/plc4go/model/values/IEC61131ValueHandler.go
similarity index 99%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/IEC61131ValueHandler.go
rename to sandbox/plc4go/internal/plc4go/model/values/IEC61131ValueHandler.go
index 5eec6c1..78b89a7 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/IEC61131ValueHandler.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/IEC61131ValueHandler.go
@@ -16,10 +16,10 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"errors"
+    "errors"
 	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
 	"plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
 	"reflect"
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/INT.go b/sandbox/plc4go/internal/plc4go/model/values/INT.go
similarity index 94%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/INT.go
rename to sandbox/plc4go/internal/plc4go/model/values/INT.go
index 586af29..27faf7e 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/INT.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/INT.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcINT struct {
 	value int16
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcINT(value int16) PlcINT {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/LINT.go b/sandbox/plc4go/internal/plc4go/model/values/LINT.go
similarity index 95%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/LINT.go
rename to sandbox/plc4go/internal/plc4go/model/values/LINT.go
index 82c7c67..62d3f51 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/LINT.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/LINT.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcLINT struct {
 	value int64
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcLINT(value int64) PlcLINT {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/LREAL.go b/sandbox/plc4go/internal/plc4go/model/values/LREAL.go
similarity index 95%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/LREAL.go
rename to sandbox/plc4go/internal/plc4go/model/values/LREAL.go
index 7ab1170..3ed9ffa 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/LREAL.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/LREAL.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcLREAL struct {
 	value float64
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcLREAL(value float64) PlcLREAL {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/LTIME.go b/sandbox/plc4go/internal/plc4go/model/values/LTIME.go
similarity index 89%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/LTIME.go
rename to sandbox/plc4go/internal/plc4go/model/values/LTIME.go
index 4e8a647..0125f0f 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/LTIME.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/LTIME.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-	"time"
+    "time"
 )
 
 type PlcLTIME struct {
 	value uint64
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcLTIME(value uint64) PlcLTIME {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/LWORD.go b/sandbox/plc4go/internal/plc4go/model/values/LWORD.go
similarity index 95%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/LWORD.go
rename to sandbox/plc4go/internal/plc4go/model/values/LWORD.go
index 9633340..f43bb50 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/LWORD.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/LWORD.go
@@ -16,13 +16,11 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+package values
 
 type PlcLWORD struct {
 	value uint64
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcLWORD(value uint64) PlcLWORD {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/NULL.go b/sandbox/plc4go/internal/plc4go/model/values/NULL.go
similarity index 87%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/NULL.go
rename to sandbox/plc4go/internal/plc4go/model/values/NULL.go
index 81b13c5..eb45ac6 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/NULL.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/NULL.go
@@ -16,12 +16,10 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+package values
 
 type PlcNULL struct {
-	values.PlcValueAdapter
+    PlcValueAdapter
 }
 
 func NewPlcNULL() PlcNULL {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/REAL.go b/sandbox/plc4go/internal/plc4go/model/values/REAL.go
similarity index 95%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/REAL.go
rename to sandbox/plc4go/internal/plc4go/model/values/REAL.go
index 0338943..a662446 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/REAL.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/REAL.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcREAL struct {
 	value float32
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcREAL(value float32) PlcREAL {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/SINT.go b/sandbox/plc4go/internal/plc4go/model/values/SINT.go
similarity index 94%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/SINT.go
rename to sandbox/plc4go/internal/plc4go/model/values/SINT.go
index bdcd80a..ba57a7f 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/SINT.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/SINT.go
@@ -16,13 +16,11 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+package values
 
 type PlcSINT struct {
 	value int8
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcSINT(value int8) PlcSINT {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/STRING.go b/sandbox/plc4go/internal/plc4go/model/values/STRING.go
similarity index 89%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/STRING.go
rename to sandbox/plc4go/internal/plc4go/model/values/STRING.go
index 61cac5e..ab7f598 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/STRING.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/STRING.go
@@ -16,13 +16,11 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+package values
 
 type PlcSTRING struct {
 	value string
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcSTRING(value string) PlcSTRING {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/TIME.go b/sandbox/plc4go/internal/plc4go/model/values/TIME.go
similarity index 89%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/TIME.go
rename to sandbox/plc4go/internal/plc4go/model/values/TIME.go
index e190715..54c5ad4 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/TIME.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/TIME.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-	"time"
+    "time"
 )
 
 type PlcTIME struct {
 	value uint32
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcTIME(value uint32) PlcTIME {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/TIME_OF_DAY.go b/sandbox/plc4go/internal/plc4go/model/values/TIME_OF_DAY.go
similarity index 90%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/TIME_OF_DAY.go
rename to sandbox/plc4go/internal/plc4go/model/values/TIME_OF_DAY.go
index 8544e3c..e9b73e6 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/TIME_OF_DAY.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/TIME_OF_DAY.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-	"time"
+    "time"
 )
 
 type PlcTIMEOFDAY struct {
 	value time.Time
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcTIMEOFDAY(value time.Time) PlcTIMEOFDAY {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/UDINT.go b/sandbox/plc4go/internal/plc4go/model/values/UDINT.go
similarity index 94%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/UDINT.go
rename to sandbox/plc4go/internal/plc4go/model/values/UDINT.go
index 5bdc9c6..3104c18 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/UDINT.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/UDINT.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcUDINT struct {
 	value uint32
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcUDINT(value uint32) PlcUDINT {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/UINT.go b/sandbox/plc4go/internal/plc4go/model/values/UINT.go
similarity index 93%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/UINT.go
rename to sandbox/plc4go/internal/plc4go/model/values/UINT.go
index 6d86330..8b59e47 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/UINT.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/UINT.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcUINT struct {
 	value uint16
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcUINT(value uint16) PlcUINT {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/ULINT.go b/sandbox/plc4go/internal/plc4go/model/values/ULINT.go
similarity index 94%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/ULINT.go
rename to sandbox/plc4go/internal/plc4go/model/values/ULINT.go
index 445fbf4..d4f9a63 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/ULINT.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/ULINT.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcULINT struct {
 	value uint64
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcULINT(value uint64) PlcULINT {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/USINT.go b/sandbox/plc4go/internal/plc4go/model/values/USINT.go
similarity index 93%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/USINT.go
rename to sandbox/plc4go/internal/plc4go/model/values/USINT.go
index df8bcb4..25a935e 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/USINT.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/USINT.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"math"
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "math"
 )
 
 type PlcUSINT struct {
 	value uint8
-	values.PlcSimpleNumericValueAdapter
+    PlcSimpleNumericValueAdapter
 }
 
 func NewPlcUSINT(value uint8) PlcUSINT {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/WCHAR.go b/sandbox/plc4go/internal/plc4go/model/values/WCHAR.go
similarity index 88%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/WCHAR.go
rename to sandbox/plc4go/internal/plc4go/model/values/WCHAR.go
index 40d9147..f8e9186 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/WCHAR.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/WCHAR.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-	"unicode/utf16"
+    "unicode/utf16"
 )
 
 type PlcWCHAR struct {
 	value []rune
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcWCHAR(value uint16) PlcWCHAR {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/WORD.go b/sandbox/plc4go/internal/plc4go/model/values/WORD.go
similarity index 92%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/WORD.go
rename to sandbox/plc4go/internal/plc4go/model/values/WORD.go
index e46e139..f53eef1 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/WORD.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/WORD.go
@@ -16,13 +16,11 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
-
-import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+package values
 
 type PlcWORD struct {
 	value uint16
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcWORD(value uint16) PlcWORD {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/iec61131/WSTRING.go b/sandbox/plc4go/internal/plc4go/model/values/WSTRING.go
similarity index 88%
rename from sandbox/plc4go/internal/plc4go/model/values/iec61131/WSTRING.go
rename to sandbox/plc4go/internal/plc4go/model/values/WSTRING.go
index 2be9176..ed631de 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/iec61131/WSTRING.go
+++ b/sandbox/plc4go/internal/plc4go/model/values/WSTRING.go
@@ -16,16 +16,15 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package iec61131
+package values
 
 import (
-	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-	"unicode/utf16"
+    "unicode/utf16"
 )
 
 type PlcWSTRING struct {
 	value []rune
-	values.PlcSimpleValueAdapter
+    PlcSimpleValueAdapter
 }
 
 func NewPlcWSTRING(value []uint16) PlcWSTRING {
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
index 1d700c5..aa71a0f 100644
--- a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
@@ -21,7 +21,6 @@ package model
 import (
     "errors"
     "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
-    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values/iec61131"
     "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
     api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
 )
@@ -30,13 +29,15 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
     switch {
         case dataProtocolId == 01: // BOOL
 
+            // Reserved Field (Just skip the bytes)
+            io.ReadUint8(7)
 
             // Simple Field (value)
             value, _valueErr := io.ReadBit()
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcBOOL(value), nil
+            return values.NewPlcBOOL(value), nil
         case dataProtocolId == 11: // BOOL
 
             // Array Field (value)
@@ -64,7 +65,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcSINT(value), nil
+            return values.NewPlcSINT(value), nil
         case dataProtocolId == 22: // USINT
 
             // Simple Field (value)
@@ -72,7 +73,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcUSINT(value), nil
+            return values.NewPlcUSINT(value), nil
         case dataProtocolId == 23: // INT
 
             // Simple Field (value)
@@ -80,7 +81,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcINT(value), nil
+            return values.NewPlcINT(value), nil
         case dataProtocolId == 24: // UINT
 
             // Simple Field (value)
@@ -88,7 +89,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcUINT(value), nil
+            return values.NewPlcUINT(value), nil
         case dataProtocolId == 25: // DINT
 
             // Simple Field (value)
@@ -96,7 +97,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcDINT(value), nil
+            return values.NewPlcDINT(value), nil
         case dataProtocolId == 26: // UDINT
 
             // Simple Field (value)
@@ -104,7 +105,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcUDINT(value), nil
+            return values.NewPlcUDINT(value), nil
         case dataProtocolId == 27: // LINT
 
             // Simple Field (value)
@@ -112,7 +113,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcLINT(value), nil
+            return values.NewPlcLINT(value), nil
         case dataProtocolId == 28: // ULINT
 
             // Simple Field (value)
@@ -120,7 +121,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcULINT(value), nil
+            return values.NewPlcULINT(value), nil
         case dataProtocolId == 31: // REAL
 
             // Simple Field (value)
@@ -128,7 +129,7 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcREAL(value), nil
+            return values.NewPlcREAL(value), nil
         case dataProtocolId == 32: // LREAL
 
             // Simple Field (value)
@@ -136,27 +137,71 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
             if _valueErr != nil {
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
-            return iec61131.NewPlcLREAL(value), nil
-        case dataProtocolId == 41: // STRING
-            //return iec61131.NewPlcSTRING(value), nil
-        case dataProtocolId == 42: // STRING
-            //return iec61131.NewPlcSTRING(value), nil
+            return values.NewPlcLREAL(value), nil
         case dataProtocolId == 43: // STRING
-            //return iec61131.NewPlcSTRING(value), nil
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS7String(io, stringLength, "UTF-8")
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSTRING(value), nil
         case dataProtocolId == 44: // STRING
-            //return iec61131.NewPlcSTRING(value), nil
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS7String(io, stringLength, "UTF-16")
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSTRING(value), nil
         case dataProtocolId == 51: // Time
-            //return new PlcTime(LocalTime.of((int) hours, (int) minutes, (int) seconds))
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaTime(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
         case dataProtocolId == 52: // Time
-            //return new PlcTime(LocalTime.of((int) hours, (int) minutes, (int) seconds))
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS5Time(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
         case dataProtocolId == 53: // Time
-            //return new PlcTime(LocalTime.of((int) hours, (int) minutes, (int) seconds))
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaLTime(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
         case dataProtocolId == 54: // Date
-            //return new PlcDate(LocalDate.of((int) year, (int) month, (int) day))
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaDate(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
         case dataProtocolId == 55: // Time
-            //return new PlcTime(LocalTime.of((int) hours, (int) minutes, (int) seconds))
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaTimeOfDay(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
         case dataProtocolId == 56: // DateTime
-            //return new PlcDateTime(LocalDateTime.of((int) year, (int) month, (int) day, (int) hours, (int) minutes, (int) seconds))
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaDateTime(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
     }
     return nil, errors.New("unsupported type")
 }
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go
new file mode 100644
index 0000000..faf2305
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go
@@ -0,0 +1,137 @@
+//
+// 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 model
+
+import (
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
+)
+
+func StaticHelperParseTiaTime(io *spi.ReadBuffer) (uint32, error) {
+    /*try {
+        int millisSinceMidnight = io.readInt(32);
+        return LocalTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0).plus(
+        millisSinceMidnight, ChronoUnit.MILLIS);
+    } catch (ParseException e) {
+        return null;
+    }*/
+    return 0, nil
+}
+
+func StaticHelperSerializeTiaTime(io *spi.WriteBuffer, value values.PlcValue) error {
+    //throw new NotImplementedException("Serializing TIME not implemented");
+    return nil
+}
+
+func StaticHelperParseS5Time(io *spi.ReadBuffer) (uint32, error) {
+    /*try {
+        int stuff = io.readInt(16);
+        // TODO: Implement this correctly.
+        throw new NotImplementedException("S5TIME not implemented");
+    } catch (ParseException e) {
+        return null;
+    }*/
+    return 0, nil
+}
+
+func StaticHelperSerializeS5Time(io *spi.WriteBuffer, value values.PlcValue) error {
+    //throw new NotImplementedException("Serializing S5TIME not implemented");
+    return nil
+}
+
+func StaticHelperParseTiaLTime(io *spi.ReadBuffer) (uint32, error) {
+    //throw new NotImplementedException("LTIME not implemented");
+    return 0, nil
+}
+
+func StaticHelperSerializeTiaLTime(io *spi.WriteBuffer, value values.PlcValue) error {
+    //throw new NotImplementedException("Serializing LTIME not implemented");
+    return nil
+}
+
+func StaticHelperParseTiaTimeOfDay(io *spi.ReadBuffer) (uint32, error) {
+    /*try {
+        long millisSinceMidnight = io.readUnsignedLong(32);
+        return LocalTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0).plus(
+            millisSinceMidnight, ChronoUnit.MILLIS);
+    } catch (ParseException e) {
+        return null;
+    }*/
+    return 0, nil
+}
+
+func StaticHelperSerializeTiaTimeOfDay(io *spi.WriteBuffer, value values.PlcValue) error {
+    //throw new NotImplementedException("Serializing TIME_OF_DAY not implemented");
+    return nil
+}
+
+func StaticHelperParseTiaDate(io *spi.ReadBuffer) (uint32, error) {
+    /*try {
+        int daysSince1990 = io.readUnsignedInt(16);
+        return LocalDate.now().withYear(1990).withDayOfMonth(1).withMonth(1).plus(daysSince1990, ChronoUnit.DAYS);
+    } catch (ParseException e) {
+        return null;
+    }*/
+    return 0, nil
+}
+
+func StaticHelperSerializeTiaDate(io *spi.WriteBuffer, value values.PlcValue) error {
+    //throw new NotImplementedException("Serializing DATE not implemented");
+    return nil
+}
+
+func StaticHelperParseTiaDateTime(io *spi.ReadBuffer) (uint32, error) {
+    /*try {
+        int year = io.readUnsignedInt(16);
+        int month = io.readUnsignedInt(8);
+        int day = io.readUnsignedInt(8);
+        // Skip day-of-week
+        io.readByte(8);
+        int hour = io.readByte(8);
+        int minute = io.readByte(8);
+        int second = io.readByte(8);
+        int nanosecond = io.readUnsignedInt(24);
+
+        return LocalDateTime.of(year, month, day, hour, minute, second, nanosecond);
+    } catch (Exception e) {
+        return null;
+    }*/
+    return 0, nil
+}
+
+func StaticHelperSerializeTiaDateTime(io *spi.WriteBuffer, value values.PlcValue) error {
+    //throw new NotImplementedException("Serializing DATE_AND_TIME not implemented");
+    return nil
+}
+
+func StaticHelperParseS7String(io *spi.ReadBuffer, stringLength int32, encoding string) (string, error) {
+    /*try {
+        // This is the maximum number of bytes a string can be long.
+        short maxLength = io.readUnsignedShort(8);
+        // This is the total length of the string on the PLC (Not necessarily the number of characters read)
+        short totalStringLength = io.readShort(8);
+        // Read the full size of the string.
+        String str = io.readString(stringLength * 8, (String) encoding);
+        // Cut off the parts that don't belong to it.
+        return str.substring(0, totalStringLength);
+    } catch (ParseException e) {
+        return null;
+    }*/
+    return "", nil
+}