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 2021/12/15 21:24:34 UTC

[plc4x] branch feature/plc4net2 created (now 2775ec9)

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

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


      at 2775ec9  refactoring: Updated the plc4net branch to the latest changes on develop. new feature: Now the DataIo generation is almost finished.

This branch includes the following new commits:

     new c88b01d  - Work on PLC4net - Work on C# code generation
     new 00be64f  - Got the code generation for Reading working again.
     new 089e0cb  - Finish implementing the WriteBuffer
     new 1e474cc  - Implemented the BitString functionality ob BYTE, WORD, DWORD and LWORD
     new 8ce8821  - Updated the NuGet information of the .Net bundles
     new 7a4b8cb  - Added a first test for the decoder - Fixed issues in the float and double processing of the ReadBuffer - Made the PlcValues comparable for equality
     new 3e17453  - Added a check for the installation of `go` - Updated the dotnet check to check for at least version 4.5.2 - Added code generation for C# enums
     new 430cfbd  - Added the basic generation of model classes for the protocol types in C#
     new 2775ec9  refactoring: Updated the plc4net branch to the latest changes on develop. new feature: Now the DataIo generation is almost finished.

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


[plc4x] 08/09: - Added the basic generation of model classes for the protocol types in C#

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

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

commit 430cfbd069325c459adb943a7d9dbae85755a882
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Dec 3 22:36:54 2020 +0100

    - Added the basic generation of model classes for the protocol types in C#
---
 .../apache/plc4x/language/cs/CsLanguageOutput.java |   3 +-
 .../resources/templates/cs/model-template.ftlh     | 134 +++++++++++++++++++++
 .../knxnetip/src/knxnetip/readwrite/model/CEMI.cs  |  34 ++++++
 .../readwrite/model/CEMIAdditionalInformation.cs   |  34 ++++++
 .../CEMIAdditionalInformationBusmonitorInfo.cs     |  53 ++++++++
 .../CEMIAdditionalInformationRelativeTimestamp.cs  |  43 +++++++
 .../src/knxnetip/readwrite/model/CEMIBusmonInd.cs  |  44 +++++++
 .../src/knxnetip/readwrite/model/CEMIDataCon.cs    |  44 +++++++
 .../src/knxnetip/readwrite/model/CEMIDataFrame.cs  |  70 +++++++++++
 .../src/knxnetip/readwrite/model/CEMIDataInd.cs    |  44 +++++++
 .../src/knxnetip/readwrite/model/CEMIDataReq.cs    |  44 +++++++
 .../src/knxnetip/readwrite/model/CEMIFrame.cs      |  46 +++++++
 .../src/knxnetip/readwrite/model/CEMIFrameAck.cs   |  43 +++++++
 .../src/knxnetip/readwrite/model/CEMIFrameData.cs  |  67 +++++++++++
 .../knxnetip/readwrite/model/CEMIFrameDataExt.cs   |  69 +++++++++++
 .../readwrite/model/CEMIFramePollingData.cs        |  43 +++++++
 .../readwrite/model/CEMIFramePollingDataExt.cs     |  43 +++++++
 .../knxnetip/readwrite/model/CEMIMPropReadCon.cs   |  50 ++++++++
 .../knxnetip/readwrite/model/CEMIMPropReadReq.cs   |  48 ++++++++
 .../knxnetip/readwrite/model/CEMIPollDataCon.cs    |  36 ++++++
 .../knxnetip/readwrite/model/CEMIPollDataReq.cs    |  36 ++++++
 .../src/knxnetip/readwrite/model/CEMIRawCon.cs     |  36 ++++++
 .../src/knxnetip/readwrite/model/CEMIRawInd.cs     |  36 ++++++
 .../src/knxnetip/readwrite/model/CEMIRawReq.cs     |  36 ++++++
 .../knxnetip/readwrite/model/ConnectionRequest.cs  |  44 +++++++
 .../model/ConnectionRequestInformation.cs          |  34 ++++++
 ...ConnectionRequestInformationDeviceManagement.cs |  36 ++++++
 ...ConnectionRequestInformationTunnelConnection.cs |  40 ++++++
 .../knxnetip/readwrite/model/ConnectionResponse.cs |  46 +++++++
 .../readwrite/model/ConnectionResponseDataBlock.cs |  34 ++++++
 .../ConnectionResponseDataBlockDeviceManagement.cs |  36 ++++++
 .../ConnectionResponseDataBlockTunnelConnection.cs |  40 ++++++
 .../readwrite/model/ConnectionStateRequest.cs      |  42 +++++++
 .../readwrite/model/ConnectionStateResponse.cs     |  42 +++++++
 .../src/knxnetip/readwrite/model/DIBDeviceInfo.cs  |  52 ++++++++
 .../knxnetip/readwrite/model/DIBSuppSvcFamilies.cs |  38 ++++++
 .../knxnetip/readwrite/model/DescriptionRequest.cs |  40 ++++++
 .../readwrite/model/DescriptionResponse.cs         |  42 +++++++
 .../readwrite/model/DeviceConfigurationAck.cs      |  40 ++++++
 .../model/DeviceConfigurationAckDataBlock.cs       |  40 ++++++
 .../readwrite/model/DeviceConfigurationRequest.cs  |  42 +++++++
 .../model/DeviceConfigurationRequestDataBlock.cs   |  38 ++++++
 .../src/knxnetip/readwrite/model/DeviceStatus.cs   |  36 ++++++
 .../knxnetip/readwrite/model/DisconnectRequest.cs  |  42 +++++++
 .../knxnetip/readwrite/model/DisconnectResponse.cs |  42 +++++++
 .../readwrite/model/HPAIControlEndpoint.cs         |  40 ++++++
 .../knxnetip/readwrite/model/HPAIDataEndpoint.cs   |  40 ++++++
 .../readwrite/model/HPAIDiscoveryEndpoint.cs       |  40 ++++++
 .../src/knxnetip/readwrite/model/IPAddress.cs      |  36 ++++++
 .../src/knxnetip/readwrite/model/KnxAddress.cs     |  40 ++++++
 .../knxnetip/readwrite/model/KnxGroupAddress.cs    |  34 ++++++
 .../readwrite/model/KnxGroupAddress2Level.cs       |  42 +++++++
 .../readwrite/model/KnxGroupAddress3Level.cs       |  44 +++++++
 .../readwrite/model/KnxGroupAddressFreeLevel.cs    |  40 ++++++
 .../src/knxnetip/readwrite/model/KnxNetIpCore.cs   |  40 ++++++
 .../readwrite/model/KnxNetIpDeviceManagement.cs    |  40 ++++++
 .../knxnetip/readwrite/model/KnxNetIpMessage.cs    |  37 ++++++
 .../knxnetip/readwrite/model/KnxNetIpTunneling.cs  |  40 ++++++
 .../knxnetip/readwrite/model/KnxNetObjectServer.cs |  40 ++++++
 .../model/KnxNetRemoteConfigurationAndDiagnosis.cs |  40 ++++++
 .../readwrite/model/KnxNetRemoteLogging.cs         |  40 ++++++
 .../src/knxnetip/readwrite/model/MACAddress.cs     |  36 ++++++
 .../model/ProjectInstallationIdentifier.cs         |  38 ++++++
 .../knxnetip/readwrite/model/RelativeTimestamp.cs  |  36 ++++++
 .../knxnetip/readwrite/model/RoutingIndication.cs  |  36 ++++++
 .../src/knxnetip/readwrite/model/SearchRequest.cs  |  40 ++++++
 .../src/knxnetip/readwrite/model/SearchResponse.cs |  44 +++++++
 .../src/knxnetip/readwrite/model/ServiceId.cs      |  34 ++++++
 .../knxnetip/readwrite/model/TunnelingRequest.cs   |  42 +++++++
 .../readwrite/model/TunnelingRequestDataBlock.cs   |  38 ++++++
 .../knxnetip/readwrite/model/TunnelingResponse.cs  |  40 ++++++
 .../readwrite/model/TunnelingResponseDataBlock.cs  |  40 ++++++
 .../src/knxnetip/readwrite/model/UnknownMessage.cs |  40 ++++++
 73 files changed, 3078 insertions(+), 1 deletion(-)

diff --git a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
index a71b4dd..9009615 100644
--- a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
+++ b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
@@ -50,7 +50,8 @@ public class CsLanguageOutput extends FreemarkerLanguageOutput {
 
     @Override
     protected List<Template> getComplexTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
-        return Collections.emptyList();
+        return Collections.singletonList(
+            freemarkerConfiguration.getTemplate("templates/cs/model-template.ftlh"));
     }
 
     @Override
diff --git a/build-utils/language-cs/src/main/resources/templates/cs/model-template.ftlh b/build-utils/language-cs/src/main/resources/templates/cs/model-template.ftlh
new file mode 100644
index 0000000..795a979
--- /dev/null
+++ b/build-utils/language-cs/src/main/resources/templates/cs/model-template.ftlh
@@ -0,0 +1,134 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+<#-- Declare the name and type of variables declared locally inside the template -->
+<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
+<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
+<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
+<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
+<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
+<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
+<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
+<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
+<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
+<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
+<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
+<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
+<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
+<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
+<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
+<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/${type.name}.cs
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFlavor?replace("-", "")}.model
+{
+
+    public<#if helper.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${type.name}<#if type.parentType??> : ${type.parentType.name}</#if>
+    {
+    <#--
+        If this is a discriminated child type, we need to generate methods for accessing it's discriminator
+        values, as if they were normal java properties.
+    -->
+    <#if helper.isDiscriminatedChildTypeDefinition()>
+        <#assign discriminatedChildType = type>
+
+        <#-- @ftlvariable name="discriminatedChildType" type="org.apache.plc4x.plugins.codegenerator.types.definitions.DiscriminatedComplexTypeDefinition" -->
+        // Accessors for discriminator values.
+        <#list helper.getDiscriminatorValues(discriminatedChildType) as discriminatorName, discriminatorValue>
+        <#-- If the discriminator name matches that of another field, suppress the methods generation -->
+            <#if !helper.isNonDiscriminatorField(discriminatorName)>
+        public override ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])} Get${discriminatorName?cap_first}() {
+            return <#if discriminatorValue??>${discriminatorValue}<#else>${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if>;
+        }
+            </#if>
+        </#list>
+    </#if>
+    <#--
+        If this is a discriminated parent type, we need to generate the abstract methods for accessing it's
+        discriminator values instead.
+    -->
+    <#if helper.isDiscriminatedParentTypeDefinition()>
+        <#assign discriminatedParentType = type>
+
+    <#-- @ftlvariable name="discriminatedParentType" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+        // Abstract accessors for discriminator values.
+        <#list helper.getDiscriminatorTypes() as discriminatorName, discriminatorType>
+        <#-- If the discriminator name matches that of another field, suppress the methods generation -->
+            <#if !helper.isNonDiscriminatorField(discriminatorName)>
+        public abstract ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} Get${discriminatorName?cap_first}();
+            </#if>
+        </#list>
+    </#if>
+    <#-- If the current type contains "const" fields, generate some java constants for holing their values -->
+    <#if type.constFields?has_content>
+
+        // Constant values.
+        <#list type.constFields as field>
+        public const ${helper.getLanguageTypeNameForField(field)} ${field.name?upper_case} = ${field.referenceValue};
+        </#list>
+    </#if>
+    <#-- Prpoerty fields are fields that require a property in the pojo -->
+    <#if type.propertyFields?has_content>
+
+        // Properties.
+        <#list type.propertyFields as field>
+        public ${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> ${field.name?cap_first} { get; }
+        </#list>
+    </#if>
+
+    <#-- getAllPropertyFields() returns not only the property fields of this type but also of it's parents -->
+        public ${type.name}(<#list type.getAllPropertyFields() as field>${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> ${field.name}<#sep>, </#sep></#list>)
+    <#if type.getParentPropertyFields()?has_content>
+            : base(<#list type.getParentPropertyFields() as field>${field.name}<#sep>, </#sep></#list>)
+    </#if>
+        {
+    <#list type.propertyFields as field>
+            ${field.name?cap_first} = ${field.name};
+    </#list>
+        }
+
+    }
+
+}
+</#outputformat>
\ No newline at end of file
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMI.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMI.cs
new file mode 100644
index 0000000..794eb23
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMI.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class CEMI
+    {
+        // Abstract accessors for discriminator values.
+        public abstract byte GetMessageCode();
+
+        public CEMI()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformation.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformation.cs
new file mode 100644
index 0000000..e95ec38
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformation.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class CEMIAdditionalInformation
+    {
+        // Abstract accessors for discriminator values.
+        public abstract byte GetAdditionalInformationType();
+
+        public CEMIAdditionalInformation()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.cs
new file mode 100644
index 0000000..e028087
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.cs
@@ -0,0 +1,53 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIAdditionalInformationBusmonitorInfo : CEMIAdditionalInformation
+    {
+        // Accessors for discriminator values.
+        public override byte GetAdditionalInformationType() {
+            return 0x03;
+        }
+
+        // Constant values.
+        public const byte LEN = 1;
+
+        // Properties.
+        public bool FrameErrorFlag { get; }
+        public bool BitErrorFlag { get; }
+        public bool ParityErrorFlag { get; }
+        public bool UnknownFlag { get; }
+        public bool LostFlag { get; }
+        public byte SequenceNumber { get; }
+
+        public CEMIAdditionalInformationBusmonitorInfo(bool frameErrorFlag, bool bitErrorFlag, bool parityErrorFlag, bool unknownFlag, bool lostFlag, byte sequenceNumber)
+        {
+            FrameErrorFlag = frameErrorFlag;
+            BitErrorFlag = bitErrorFlag;
+            ParityErrorFlag = parityErrorFlag;
+            UnknownFlag = unknownFlag;
+            LostFlag = lostFlag;
+            SequenceNumber = sequenceNumber;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.cs
new file mode 100644
index 0000000..cbbb160
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.cs
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIAdditionalInformationRelativeTimestamp : CEMIAdditionalInformation
+    {
+        // Accessors for discriminator values.
+        public override byte GetAdditionalInformationType() {
+            return 0x04;
+        }
+
+        // Constant values.
+        public const byte LEN = 2;
+
+        // Properties.
+        public RelativeTimestamp RelativeTimestamp { get; }
+
+        public CEMIAdditionalInformationRelativeTimestamp(RelativeTimestamp relativeTimestamp)
+        {
+            RelativeTimestamp = relativeTimestamp;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIBusmonInd.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIBusmonInd.cs
new file mode 100644
index 0000000..fb5252d
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIBusmonInd.cs
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIBusmonInd : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x2B;
+        }
+
+        // Properties.
+        public byte AdditionalInformationLength { get; }
+        public CEMIAdditionalInformation[] AdditionalInformation { get; }
+        public CEMIFrame CemiFrame { get; }
+
+        public CEMIBusmonInd(byte additionalInformationLength, CEMIAdditionalInformation[] additionalInformation, CEMIFrame cemiFrame)
+        {
+            AdditionalInformationLength = additionalInformationLength;
+            AdditionalInformation = additionalInformation;
+            CemiFrame = cemiFrame;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataCon.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataCon.cs
new file mode 100644
index 0000000..061c2f7
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataCon.cs
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIDataCon : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x2E;
+        }
+
+        // Properties.
+        public byte AdditionalInformationLength { get; }
+        public CEMIAdditionalInformation[] AdditionalInformation { get; }
+        public CEMIDataFrame CemiDataFrame { get; }
+
+        public CEMIDataCon(byte additionalInformationLength, CEMIAdditionalInformation[] additionalInformation, CEMIDataFrame cemiDataFrame)
+        {
+            AdditionalInformationLength = additionalInformationLength;
+            AdditionalInformation = additionalInformation;
+            CemiDataFrame = cemiDataFrame;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataFrame.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataFrame.cs
new file mode 100644
index 0000000..a252fd8
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataFrame.cs
@@ -0,0 +1,70 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIDataFrame
+    {
+
+        // Properties.
+        public bool StandardFrame { get; }
+        public bool Polling { get; }
+        public bool NotRepeated { get; }
+        public bool NotAckFrame { get; }
+        public CEMIPriority Priority { get; }
+        public bool AcknowledgeRequested { get; }
+        public bool ErrorFlag { get; }
+        public bool GroupDestinationAddress { get; }
+        public byte HopCount { get; }
+        public byte ExtendedFrameFormat { get; }
+        public KnxAddress SourceAddress { get; }
+        public sbyte[] DestinationAddress { get; }
+        public byte DataLength { get; }
+        public TPCI Tcpi { get; }
+        public byte Counter { get; }
+        public APCI Apci { get; }
+        public sbyte DataFirstByte { get; }
+        public sbyte[] Data { get; }
+
+        public CEMIDataFrame(bool standardFrame, bool polling, bool notRepeated, bool notAckFrame, CEMIPriority priority, bool acknowledgeRequested, bool errorFlag, bool groupDestinationAddress, byte hopCount, byte extendedFrameFormat, KnxAddress sourceAddress, sbyte[] destinationAddress, byte dataLength, TPCI tcpi, byte counter, APCI apci, sbyte dataFirstByte, sbyte[] data)
+        {
+            StandardFrame = standardFrame;
+            Polling = polling;
+            NotRepeated = notRepeated;
+            NotAckFrame = notAckFrame;
+            Priority = priority;
+            AcknowledgeRequested = acknowledgeRequested;
+            ErrorFlag = errorFlag;
+            GroupDestinationAddress = groupDestinationAddress;
+            HopCount = hopCount;
+            ExtendedFrameFormat = extendedFrameFormat;
+            SourceAddress = sourceAddress;
+            DestinationAddress = destinationAddress;
+            DataLength = dataLength;
+            Tcpi = tcpi;
+            Counter = counter;
+            Apci = apci;
+            DataFirstByte = dataFirstByte;
+            Data = data;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataInd.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataInd.cs
new file mode 100644
index 0000000..694131f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataInd.cs
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIDataInd : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x29;
+        }
+
+        // Properties.
+        public byte AdditionalInformationLength { get; }
+        public CEMIAdditionalInformation[] AdditionalInformation { get; }
+        public CEMIDataFrame CemiDataFrame { get; }
+
+        public CEMIDataInd(byte additionalInformationLength, CEMIAdditionalInformation[] additionalInformation, CEMIDataFrame cemiDataFrame)
+        {
+            AdditionalInformationLength = additionalInformationLength;
+            AdditionalInformation = additionalInformation;
+            CemiDataFrame = cemiDataFrame;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataReq.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataReq.cs
new file mode 100644
index 0000000..39b3215
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIDataReq.cs
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIDataReq : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x11;
+        }
+
+        // Properties.
+        public byte AdditionalInformationLength { get; }
+        public CEMIAdditionalInformation[] AdditionalInformation { get; }
+        public CEMIDataFrame CemiDataFrame { get; }
+
+        public CEMIDataReq(byte additionalInformationLength, CEMIAdditionalInformation[] additionalInformation, CEMIDataFrame cemiDataFrame)
+        {
+            AdditionalInformationLength = additionalInformationLength;
+            AdditionalInformation = additionalInformation;
+            CemiDataFrame = cemiDataFrame;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrame.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrame.cs
new file mode 100644
index 0000000..ec0cbfd
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrame.cs
@@ -0,0 +1,46 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class CEMIFrame
+    {
+        // Abstract accessors for discriminator values.
+        public abstract bool GetNotAckFrame();
+        public abstract bool GetPolling();
+        public abstract bool GetStandardFrame();
+
+        // Properties.
+        public bool Repeated { get; }
+        public CEMIPriority Priority { get; }
+        public bool AcknowledgeRequested { get; }
+        public bool ErrorFlag { get; }
+
+        public CEMIFrame(bool repeated, CEMIPriority priority, bool acknowledgeRequested, bool errorFlag)
+        {
+            Repeated = repeated;
+            Priority = priority;
+            AcknowledgeRequested = acknowledgeRequested;
+            ErrorFlag = errorFlag;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameAck.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameAck.cs
new file mode 100644
index 0000000..f519c6d
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameAck.cs
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIFrameAck : CEMIFrame
+    {
+        // Accessors for discriminator values.
+        public override bool GetNotAckFrame() {
+            return false;
+        }
+        public override bool GetStandardFrame() {
+            return false;
+        }
+        public override bool GetPolling() {
+            return false;
+        }
+
+        public CEMIFrameAck(bool repeated, CEMIPriority priority, bool acknowledgeRequested, bool errorFlag)
+            : base(repeated, priority, acknowledgeRequested, errorFlag)
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameData.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameData.cs
new file mode 100644
index 0000000..1510b3e
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameData.cs
@@ -0,0 +1,67 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIFrameData : CEMIFrame
+    {
+        // Accessors for discriminator values.
+        public override bool GetNotAckFrame() {
+            return true;
+        }
+        public override bool GetStandardFrame() {
+            return true;
+        }
+        public override bool GetPolling() {
+            return false;
+        }
+
+        // Properties.
+        public KnxAddress SourceAddress { get; }
+        public sbyte[] DestinationAddress { get; }
+        public bool GroupAddress { get; }
+        public byte HopCount { get; }
+        public byte DataLength { get; }
+        public TPCI Tcpi { get; }
+        public byte Counter { get; }
+        public APCI Apci { get; }
+        public sbyte DataFirstByte { get; }
+        public sbyte[] Data { get; }
+        public byte Crc { get; }
+
+        public CEMIFrameData(bool repeated, CEMIPriority priority, bool acknowledgeRequested, bool errorFlag, KnxAddress sourceAddress, sbyte[] destinationAddress, bool groupAddress, byte hopCount, byte dataLength, TPCI tcpi, byte counter, APCI apci, sbyte dataFirstByte, sbyte[] data, byte crc)
+            : base(repeated, priority, acknowledgeRequested, errorFlag)
+        {
+            SourceAddress = sourceAddress;
+            DestinationAddress = destinationAddress;
+            GroupAddress = groupAddress;
+            HopCount = hopCount;
+            DataLength = dataLength;
+            Tcpi = tcpi;
+            Counter = counter;
+            Apci = apci;
+            DataFirstByte = dataFirstByte;
+            Data = data;
+            Crc = crc;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameDataExt.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameDataExt.cs
new file mode 100644
index 0000000..539f224
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFrameDataExt.cs
@@ -0,0 +1,69 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIFrameDataExt : CEMIFrame
+    {
+        // Accessors for discriminator values.
+        public override bool GetNotAckFrame() {
+            return true;
+        }
+        public override bool GetStandardFrame() {
+            return false;
+        }
+        public override bool GetPolling() {
+            return false;
+        }
+
+        // Properties.
+        public bool GroupAddress { get; }
+        public byte HopCount { get; }
+        public byte ExtendedFrameFormat { get; }
+        public KnxAddress SourceAddress { get; }
+        public sbyte[] DestinationAddress { get; }
+        public byte DataLength { get; }
+        public TPCI Tcpi { get; }
+        public byte Counter { get; }
+        public APCI Apci { get; }
+        public sbyte DataFirstByte { get; }
+        public sbyte[] Data { get; }
+        public byte Crc { get; }
+
+        public CEMIFrameDataExt(bool repeated, CEMIPriority priority, bool acknowledgeRequested, bool errorFlag, bool groupAddress, byte hopCount, byte extendedFrameFormat, KnxAddress sourceAddress, sbyte[] destinationAddress, byte dataLength, TPCI tcpi, byte counter, APCI apci, sbyte dataFirstByte, sbyte[] data, byte crc)
+            : base(repeated, priority, acknowledgeRequested, errorFlag)
+        {
+            GroupAddress = groupAddress;
+            HopCount = hopCount;
+            ExtendedFrameFormat = extendedFrameFormat;
+            SourceAddress = sourceAddress;
+            DestinationAddress = destinationAddress;
+            DataLength = dataLength;
+            Tcpi = tcpi;
+            Counter = counter;
+            Apci = apci;
+            DataFirstByte = dataFirstByte;
+            Data = data;
+            Crc = crc;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFramePollingData.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFramePollingData.cs
new file mode 100644
index 0000000..3506ff7
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFramePollingData.cs
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIFramePollingData : CEMIFrame
+    {
+        // Accessors for discriminator values.
+        public override bool GetNotAckFrame() {
+            return true;
+        }
+        public override bool GetStandardFrame() {
+            return true;
+        }
+        public override bool GetPolling() {
+            return true;
+        }
+
+        public CEMIFramePollingData(bool repeated, CEMIPriority priority, bool acknowledgeRequested, bool errorFlag)
+            : base(repeated, priority, acknowledgeRequested, errorFlag)
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFramePollingDataExt.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFramePollingDataExt.cs
new file mode 100644
index 0000000..c80a567
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIFramePollingDataExt.cs
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIFramePollingDataExt : CEMIFrame
+    {
+        // Accessors for discriminator values.
+        public override bool GetNotAckFrame() {
+            return true;
+        }
+        public override bool GetStandardFrame() {
+            return false;
+        }
+        public override bool GetPolling() {
+            return true;
+        }
+
+        public CEMIFramePollingDataExt(bool repeated, CEMIPriority priority, bool acknowledgeRequested, bool errorFlag)
+            : base(repeated, priority, acknowledgeRequested, errorFlag)
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIMPropReadCon.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIMPropReadCon.cs
new file mode 100644
index 0000000..213b265
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIMPropReadCon.cs
@@ -0,0 +1,50 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIMPropReadCon : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0xFB;
+        }
+
+        // Properties.
+        public ushort InterfaceObjectType { get; }
+        public byte ObjectInstance { get; }
+        public byte PropertyId { get; }
+        public byte NumberOfElements { get; }
+        public ushort StartIndex { get; }
+        public ushort Unknown { get; }
+
+        public CEMIMPropReadCon(ushort interfaceObjectType, byte objectInstance, byte propertyId, byte numberOfElements, ushort startIndex, ushort unknown)
+        {
+            InterfaceObjectType = interfaceObjectType;
+            ObjectInstance = objectInstance;
+            PropertyId = propertyId;
+            NumberOfElements = numberOfElements;
+            StartIndex = startIndex;
+            Unknown = unknown;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIMPropReadReq.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIMPropReadReq.cs
new file mode 100644
index 0000000..eed16e5
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIMPropReadReq.cs
@@ -0,0 +1,48 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIMPropReadReq : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0xFC;
+        }
+
+        // Properties.
+        public ushort InterfaceObjectType { get; }
+        public byte ObjectInstance { get; }
+        public byte PropertyId { get; }
+        public byte NumberOfElements { get; }
+        public ushort StartIndex { get; }
+
+        public CEMIMPropReadReq(ushort interfaceObjectType, byte objectInstance, byte propertyId, byte numberOfElements, ushort startIndex)
+        {
+            InterfaceObjectType = interfaceObjectType;
+            ObjectInstance = objectInstance;
+            PropertyId = propertyId;
+            NumberOfElements = numberOfElements;
+            StartIndex = startIndex;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPollDataCon.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPollDataCon.cs
new file mode 100644
index 0000000..37d1f22
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPollDataCon.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIPollDataCon : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x25;
+        }
+
+        public CEMIPollDataCon()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPollDataReq.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPollDataReq.cs
new file mode 100644
index 0000000..dec3e84
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPollDataReq.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIPollDataReq : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x13;
+        }
+
+        public CEMIPollDataReq()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawCon.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawCon.cs
new file mode 100644
index 0000000..f3e69f1
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawCon.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIRawCon : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x2F;
+        }
+
+        public CEMIRawCon()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawInd.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawInd.cs
new file mode 100644
index 0000000..9e5cf00
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawInd.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIRawInd : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x2D;
+        }
+
+        public CEMIRawInd()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawReq.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawReq.cs
new file mode 100644
index 0000000..0d6a8b1
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIRawReq.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIRawReq : CEMI
+    {
+        // Accessors for discriminator values.
+        public override byte GetMessageCode() {
+            return 0x10;
+        }
+
+        public CEMIRawReq()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequest.cs
new file mode 100644
index 0000000..e4d73b4
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequest.cs
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ConnectionRequest : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0205;
+        }
+
+        // Properties.
+        public HPAIDiscoveryEndpoint HpaiDiscoveryEndpoint { get; }
+        public HPAIDataEndpoint HpaiDataEndpoint { get; }
+        public ConnectionRequestInformation ConnectionRequestInformation { get; }
+
+        public ConnectionRequest(HPAIDiscoveryEndpoint hpaiDiscoveryEndpoint, HPAIDataEndpoint hpaiDataEndpoint, ConnectionRequestInformation connectionRequestInformation)
+        {
+            HpaiDiscoveryEndpoint = hpaiDiscoveryEndpoint;
+            HpaiDataEndpoint = hpaiDataEndpoint;
+            ConnectionRequestInformation = connectionRequestInformation;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformation.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformation.cs
new file mode 100644
index 0000000..f01a300
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformation.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class ConnectionRequestInformation
+    {
+        // Abstract accessors for discriminator values.
+        public abstract byte GetConnectionType();
+
+        public ConnectionRequestInformation()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformationDeviceManagement.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformationDeviceManagement.cs
new file mode 100644
index 0000000..3786528
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformationDeviceManagement.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ConnectionRequestInformationDeviceManagement : ConnectionRequestInformation
+    {
+        // Accessors for discriminator values.
+        public override byte GetConnectionType() {
+            return 0x03;
+        }
+
+        public ConnectionRequestInformationDeviceManagement()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformationTunnelConnection.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformationTunnelConnection.cs
new file mode 100644
index 0000000..a2c3c7a
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionRequestInformationTunnelConnection.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ConnectionRequestInformationTunnelConnection : ConnectionRequestInformation
+    {
+        // Accessors for discriminator values.
+        public override byte GetConnectionType() {
+            return 0x04;
+        }
+
+        // Properties.
+        public KnxLayer KnxLayer { get; }
+
+        public ConnectionRequestInformationTunnelConnection(KnxLayer knxLayer)
+        {
+            KnxLayer = knxLayer;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponse.cs
new file mode 100644
index 0000000..250381a
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponse.cs
@@ -0,0 +1,46 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ConnectionResponse : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0206;
+        }
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public Status Status { get; }
+        public HPAIDataEndpoint HpaiDataEndpoint { get; }
+        public ConnectionResponseDataBlock ConnectionResponseDataBlock { get; }
+
+        public ConnectionResponse(byte communicationChannelId, Status status, HPAIDataEndpoint hpaiDataEndpoint, ConnectionResponseDataBlock connectionResponseDataBlock)
+        {
+            CommunicationChannelId = communicationChannelId;
+            Status = status;
+            HpaiDataEndpoint = hpaiDataEndpoint;
+            ConnectionResponseDataBlock = connectionResponseDataBlock;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlock.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlock.cs
new file mode 100644
index 0000000..d01c6f7
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlock.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class ConnectionResponseDataBlock
+    {
+        // Abstract accessors for discriminator values.
+        public abstract byte GetConnectionType();
+
+        public ConnectionResponseDataBlock()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlockDeviceManagement.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlockDeviceManagement.cs
new file mode 100644
index 0000000..dca298f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlockDeviceManagement.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ConnectionResponseDataBlockDeviceManagement : ConnectionResponseDataBlock
+    {
+        // Accessors for discriminator values.
+        public override byte GetConnectionType() {
+            return 0x03;
+        }
+
+        public ConnectionResponseDataBlockDeviceManagement()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlockTunnelConnection.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlockTunnelConnection.cs
new file mode 100644
index 0000000..a45fda7
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionResponseDataBlockTunnelConnection.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ConnectionResponseDataBlockTunnelConnection : ConnectionResponseDataBlock
+    {
+        // Accessors for discriminator values.
+        public override byte GetConnectionType() {
+            return 0x04;
+        }
+
+        // Properties.
+        public KnxAddress KnxAddress { get; }
+
+        public ConnectionResponseDataBlockTunnelConnection(KnxAddress knxAddress)
+        {
+            KnxAddress = knxAddress;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionStateRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionStateRequest.cs
new file mode 100644
index 0000000..b6636d7
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionStateRequest.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ConnectionStateRequest : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0207;
+        }
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public HPAIControlEndpoint HpaiControlEndpoint { get; }
+
+        public ConnectionStateRequest(byte communicationChannelId, HPAIControlEndpoint hpaiControlEndpoint)
+        {
+            CommunicationChannelId = communicationChannelId;
+            HpaiControlEndpoint = hpaiControlEndpoint;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionStateResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionStateResponse.cs
new file mode 100644
index 0000000..0d98468
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ConnectionStateResponse.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ConnectionStateResponse : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0208;
+        }
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public Status Status { get; }
+
+        public ConnectionStateResponse(byte communicationChannelId, Status status)
+        {
+            CommunicationChannelId = communicationChannelId;
+            Status = status;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DIBDeviceInfo.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DIBDeviceInfo.cs
new file mode 100644
index 0000000..1ffeac0
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DIBDeviceInfo.cs
@@ -0,0 +1,52 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DIBDeviceInfo
+    {
+
+        // Properties.
+        public byte DescriptionType { get; }
+        public KnxMedium KnxMedium { get; }
+        public DeviceStatus DeviceStatus { get; }
+        public KnxAddress KnxAddress { get; }
+        public ProjectInstallationIdentifier ProjectInstallationIdentifier { get; }
+        public sbyte[] KnxNetIpDeviceSerialNumber { get; }
+        public IPAddress KnxNetIpDeviceMulticastAddress { get; }
+        public MACAddress KnxNetIpDeviceMacAddress { get; }
+        public sbyte[] DeviceFriendlyName { get; }
+
+        public DIBDeviceInfo(byte descriptionType, KnxMedium knxMedium, DeviceStatus deviceStatus, KnxAddress knxAddress, ProjectInstallationIdentifier projectInstallationIdentifier, sbyte[] knxNetIpDeviceSerialNumber, IPAddress knxNetIpDeviceMulticastAddress, MACAddress knxNetIpDeviceMacAddress, sbyte[] deviceFriendlyName)
+        {
+            DescriptionType = descriptionType;
+            KnxMedium = knxMedium;
+            DeviceStatus = deviceStatus;
+            KnxAddress = knxAddress;
+            ProjectInstallationIdentifier = projectInstallationIdentifier;
+            KnxNetIpDeviceSerialNumber = knxNetIpDeviceSerialNumber;
+            KnxNetIpDeviceMulticastAddress = knxNetIpDeviceMulticastAddress;
+            KnxNetIpDeviceMacAddress = knxNetIpDeviceMacAddress;
+            DeviceFriendlyName = deviceFriendlyName;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DIBSuppSvcFamilies.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DIBSuppSvcFamilies.cs
new file mode 100644
index 0000000..f1a8549
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DIBSuppSvcFamilies.cs
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DIBSuppSvcFamilies
+    {
+
+        // Properties.
+        public byte DescriptionType { get; }
+        public ServiceId[] ServiceIds { get; }
+
+        public DIBSuppSvcFamilies(byte descriptionType, ServiceId[] serviceIds)
+        {
+            DescriptionType = descriptionType;
+            ServiceIds = serviceIds;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DescriptionRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DescriptionRequest.cs
new file mode 100644
index 0000000..7d4b62d
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DescriptionRequest.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DescriptionRequest : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0203;
+        }
+
+        // Properties.
+        public HPAIControlEndpoint HpaiControlEndpoint { get; }
+
+        public DescriptionRequest(HPAIControlEndpoint hpaiControlEndpoint)
+        {
+            HpaiControlEndpoint = hpaiControlEndpoint;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DescriptionResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DescriptionResponse.cs
new file mode 100644
index 0000000..f34c1b3
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DescriptionResponse.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DescriptionResponse : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0204;
+        }
+
+        // Properties.
+        public DIBDeviceInfo DibDeviceInfo { get; }
+        public DIBSuppSvcFamilies DibSuppSvcFamilies { get; }
+
+        public DescriptionResponse(DIBDeviceInfo dibDeviceInfo, DIBSuppSvcFamilies dibSuppSvcFamilies)
+        {
+            DibDeviceInfo = dibDeviceInfo;
+            DibSuppSvcFamilies = dibSuppSvcFamilies;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationAck.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationAck.cs
new file mode 100644
index 0000000..f68c071
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationAck.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DeviceConfigurationAck : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0311;
+        }
+
+        // Properties.
+        public DeviceConfigurationAckDataBlock DeviceConfigurationAckDataBlock { get; }
+
+        public DeviceConfigurationAck(DeviceConfigurationAckDataBlock deviceConfigurationAckDataBlock)
+        {
+            DeviceConfigurationAckDataBlock = deviceConfigurationAckDataBlock;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationAckDataBlock.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationAckDataBlock.cs
new file mode 100644
index 0000000..749b756
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationAckDataBlock.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DeviceConfigurationAckDataBlock
+    {
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public byte SequenceCounter { get; }
+        public Status Status { get; }
+
+        public DeviceConfigurationAckDataBlock(byte communicationChannelId, byte sequenceCounter, Status status)
+        {
+            CommunicationChannelId = communicationChannelId;
+            SequenceCounter = sequenceCounter;
+            Status = status;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationRequest.cs
new file mode 100644
index 0000000..af8bff2
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationRequest.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DeviceConfigurationRequest : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0310;
+        }
+
+        // Properties.
+        public DeviceConfigurationRequestDataBlock DeviceConfigurationRequestDataBlock { get; }
+        public CEMI Cemi { get; }
+
+        public DeviceConfigurationRequest(DeviceConfigurationRequestDataBlock deviceConfigurationRequestDataBlock, CEMI cemi)
+        {
+            DeviceConfigurationRequestDataBlock = deviceConfigurationRequestDataBlock;
+            Cemi = cemi;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationRequestDataBlock.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationRequestDataBlock.cs
new file mode 100644
index 0000000..b514c89
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceConfigurationRequestDataBlock.cs
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DeviceConfigurationRequestDataBlock
+    {
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public byte SequenceCounter { get; }
+
+        public DeviceConfigurationRequestDataBlock(byte communicationChannelId, byte sequenceCounter)
+        {
+            CommunicationChannelId = communicationChannelId;
+            SequenceCounter = sequenceCounter;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceStatus.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceStatus.cs
new file mode 100644
index 0000000..3fce7c2
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DeviceStatus.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DeviceStatus
+    {
+
+        // Properties.
+        public bool ProgramMode { get; }
+
+        public DeviceStatus(bool programMode)
+        {
+            ProgramMode = programMode;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DisconnectRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DisconnectRequest.cs
new file mode 100644
index 0000000..a45d552
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DisconnectRequest.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DisconnectRequest : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0209;
+        }
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public HPAIControlEndpoint HpaiControlEndpoint { get; }
+
+        public DisconnectRequest(byte communicationChannelId, HPAIControlEndpoint hpaiControlEndpoint)
+        {
+            CommunicationChannelId = communicationChannelId;
+            HpaiControlEndpoint = hpaiControlEndpoint;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DisconnectResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DisconnectResponse.cs
new file mode 100644
index 0000000..c648bdd
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/DisconnectResponse.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class DisconnectResponse : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x020A;
+        }
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public Status Status { get; }
+
+        public DisconnectResponse(byte communicationChannelId, Status status)
+        {
+            CommunicationChannelId = communicationChannelId;
+            Status = status;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIControlEndpoint.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIControlEndpoint.cs
new file mode 100644
index 0000000..e2fd1b8
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIControlEndpoint.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class HPAIControlEndpoint
+    {
+
+        // Properties.
+        public HostProtocolCode HostProtocolCode { get; }
+        public IPAddress IpAddress { get; }
+        public ushort IpPort { get; }
+
+        public HPAIControlEndpoint(HostProtocolCode hostProtocolCode, IPAddress ipAddress, ushort ipPort)
+        {
+            HostProtocolCode = hostProtocolCode;
+            IpAddress = ipAddress;
+            IpPort = ipPort;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIDataEndpoint.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIDataEndpoint.cs
new file mode 100644
index 0000000..a2bff76
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIDataEndpoint.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class HPAIDataEndpoint
+    {
+
+        // Properties.
+        public HostProtocolCode HostProtocolCode { get; }
+        public IPAddress IpAddress { get; }
+        public ushort IpPort { get; }
+
+        public HPAIDataEndpoint(HostProtocolCode hostProtocolCode, IPAddress ipAddress, ushort ipPort)
+        {
+            HostProtocolCode = hostProtocolCode;
+            IpAddress = ipAddress;
+            IpPort = ipPort;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIDiscoveryEndpoint.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIDiscoveryEndpoint.cs
new file mode 100644
index 0000000..ff1c60d
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HPAIDiscoveryEndpoint.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class HPAIDiscoveryEndpoint
+    {
+
+        // Properties.
+        public HostProtocolCode HostProtocolCode { get; }
+        public IPAddress IpAddress { get; }
+        public ushort IpPort { get; }
+
+        public HPAIDiscoveryEndpoint(HostProtocolCode hostProtocolCode, IPAddress ipAddress, ushort ipPort)
+        {
+            HostProtocolCode = hostProtocolCode;
+            IpAddress = ipAddress;
+            IpPort = ipPort;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/IPAddress.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/IPAddress.cs
new file mode 100644
index 0000000..2b35bb7
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/IPAddress.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class IPAddress
+    {
+
+        // Properties.
+        public sbyte[] Addr { get; }
+
+        public IPAddress(sbyte[] addr)
+        {
+            Addr = addr;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxAddress.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxAddress.cs
new file mode 100644
index 0000000..cd94f5a
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxAddress.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxAddress
+    {
+
+        // Properties.
+        public byte MainGroup { get; }
+        public byte MiddleGroup { get; }
+        public byte SubGroup { get; }
+
+        public KnxAddress(byte mainGroup, byte middleGroup, byte subGroup)
+        {
+            MainGroup = mainGroup;
+            MiddleGroup = middleGroup;
+            SubGroup = subGroup;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress.cs
new file mode 100644
index 0000000..71dc57a
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class KnxGroupAddress
+    {
+        // Abstract accessors for discriminator values.
+        public abstract byte GetNumLevels();
+
+        public KnxGroupAddress()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress2Level.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress2Level.cs
new file mode 100644
index 0000000..d991db8
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress2Level.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxGroupAddress2Level : KnxGroupAddress
+    {
+        // Accessors for discriminator values.
+        public override byte GetNumLevels() {
+            return 2;
+        }
+
+        // Properties.
+        public byte MainGroup { get; }
+        public ushort SubGroup { get; }
+
+        public KnxGroupAddress2Level(byte mainGroup, ushort subGroup)
+        {
+            MainGroup = mainGroup;
+            SubGroup = subGroup;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress3Level.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress3Level.cs
new file mode 100644
index 0000000..b045e08
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddress3Level.cs
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxGroupAddress3Level : KnxGroupAddress
+    {
+        // Accessors for discriminator values.
+        public override byte GetNumLevels() {
+            return 3;
+        }
+
+        // Properties.
+        public byte MainGroup { get; }
+        public byte MiddleGroup { get; }
+        public byte SubGroup { get; }
+
+        public KnxGroupAddress3Level(byte mainGroup, byte middleGroup, byte subGroup)
+        {
+            MainGroup = mainGroup;
+            MiddleGroup = middleGroup;
+            SubGroup = subGroup;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddressFreeLevel.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddressFreeLevel.cs
new file mode 100644
index 0000000..d7bc817
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxGroupAddressFreeLevel.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxGroupAddressFreeLevel : KnxGroupAddress
+    {
+        // Accessors for discriminator values.
+        public override byte GetNumLevels() {
+            return 1;
+        }
+
+        // Properties.
+        public ushort SubGroup { get; }
+
+        public KnxGroupAddressFreeLevel(ushort subGroup)
+        {
+            SubGroup = subGroup;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpCore.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpCore.cs
new file mode 100644
index 0000000..199f867
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpCore.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxNetIpCore : ServiceId
+    {
+        // Accessors for discriminator values.
+        public override byte GetServiceType() {
+            return 0x02;
+        }
+
+        // Properties.
+        public byte Version { get; }
+
+        public KnxNetIpCore(byte version)
+        {
+            Version = version;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpDeviceManagement.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpDeviceManagement.cs
new file mode 100644
index 0000000..45f2398
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpDeviceManagement.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxNetIpDeviceManagement : ServiceId
+    {
+        // Accessors for discriminator values.
+        public override byte GetServiceType() {
+            return 0x03;
+        }
+
+        // Properties.
+        public byte Version { get; }
+
+        public KnxNetIpDeviceManagement(byte version)
+        {
+            Version = version;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpMessage.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpMessage.cs
new file mode 100644
index 0000000..4c65a75
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpMessage.cs
@@ -0,0 +1,37 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class KnxNetIpMessage
+    {
+        // Abstract accessors for discriminator values.
+        public abstract ushort GetMsgType();
+
+        // Constant values.
+        public const byte PROTOCOLVERSION = 0x10;
+
+        public KnxNetIpMessage()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpTunneling.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpTunneling.cs
new file mode 100644
index 0000000..ab2ee0f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetIpTunneling.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxNetIpTunneling : ServiceId
+    {
+        // Accessors for discriminator values.
+        public override byte GetServiceType() {
+            return 0x04;
+        }
+
+        // Properties.
+        public byte Version { get; }
+
+        public KnxNetIpTunneling(byte version)
+        {
+            Version = version;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetObjectServer.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetObjectServer.cs
new file mode 100644
index 0000000..8f4a93a
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetObjectServer.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxNetObjectServer : ServiceId
+    {
+        // Accessors for discriminator values.
+        public override byte GetServiceType() {
+            return 0x08;
+        }
+
+        // Properties.
+        public byte Version { get; }
+
+        public KnxNetObjectServer(byte version)
+        {
+            Version = version;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetRemoteConfigurationAndDiagnosis.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetRemoteConfigurationAndDiagnosis.cs
new file mode 100644
index 0000000..ed06102
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetRemoteConfigurationAndDiagnosis.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxNetRemoteConfigurationAndDiagnosis : ServiceId
+    {
+        // Accessors for discriminator values.
+        public override byte GetServiceType() {
+            return 0x07;
+        }
+
+        // Properties.
+        public byte Version { get; }
+
+        public KnxNetRemoteConfigurationAndDiagnosis(byte version)
+        {
+            Version = version;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetRemoteLogging.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetRemoteLogging.cs
new file mode 100644
index 0000000..8b97a98
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxNetRemoteLogging.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxNetRemoteLogging : ServiceId
+    {
+        // Accessors for discriminator values.
+        public override byte GetServiceType() {
+            return 0x06;
+        }
+
+        // Properties.
+        public byte Version { get; }
+
+        public KnxNetRemoteLogging(byte version)
+        {
+            Version = version;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/MACAddress.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/MACAddress.cs
new file mode 100644
index 0000000..6314819
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/MACAddress.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class MACAddress
+    {
+
+        // Properties.
+        public sbyte[] Addr { get; }
+
+        public MACAddress(sbyte[] addr)
+        {
+            Addr = addr;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ProjectInstallationIdentifier.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ProjectInstallationIdentifier.cs
new file mode 100644
index 0000000..30a5b53
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ProjectInstallationIdentifier.cs
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ProjectInstallationIdentifier
+    {
+
+        // Properties.
+        public byte ProjectNumber { get; }
+        public byte InstallationNumber { get; }
+
+        public ProjectInstallationIdentifier(byte projectNumber, byte installationNumber)
+        {
+            ProjectNumber = projectNumber;
+            InstallationNumber = installationNumber;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/RelativeTimestamp.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/RelativeTimestamp.cs
new file mode 100644
index 0000000..45f1d58
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/RelativeTimestamp.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class RelativeTimestamp
+    {
+
+        // Properties.
+        public ushort Timestamp { get; }
+
+        public RelativeTimestamp(ushort timestamp)
+        {
+            Timestamp = timestamp;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/RoutingIndication.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/RoutingIndication.cs
new file mode 100644
index 0000000..30afa77
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/RoutingIndication.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class RoutingIndication : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0530;
+        }
+
+        public RoutingIndication()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SearchRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SearchRequest.cs
new file mode 100644
index 0000000..d16d8de
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SearchRequest.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class SearchRequest : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0201;
+        }
+
+        // Properties.
+        public HPAIDiscoveryEndpoint HpaiIDiscoveryEndpoint { get; }
+
+        public SearchRequest(HPAIDiscoveryEndpoint hpaiIDiscoveryEndpoint)
+        {
+            HpaiIDiscoveryEndpoint = hpaiIDiscoveryEndpoint;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SearchResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SearchResponse.cs
new file mode 100644
index 0000000..a02e703
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SearchResponse.cs
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class SearchResponse : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0202;
+        }
+
+        // Properties.
+        public HPAIControlEndpoint HpaiControlEndpoint { get; }
+        public DIBDeviceInfo DibDeviceInfo { get; }
+        public DIBSuppSvcFamilies DibSuppSvcFamilies { get; }
+
+        public SearchResponse(HPAIControlEndpoint hpaiControlEndpoint, DIBDeviceInfo dibDeviceInfo, DIBSuppSvcFamilies dibSuppSvcFamilies)
+        {
+            HpaiControlEndpoint = hpaiControlEndpoint;
+            DibDeviceInfo = dibDeviceInfo;
+            DibSuppSvcFamilies = dibSuppSvcFamilies;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ServiceId.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ServiceId.cs
new file mode 100644
index 0000000..7db9d85
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/ServiceId.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class ServiceId
+    {
+        // Abstract accessors for discriminator values.
+        public abstract byte GetServiceType();
+
+        public ServiceId()
+        {
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingRequest.cs
new file mode 100644
index 0000000..28f6c27
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingRequest.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class TunnelingRequest : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0420;
+        }
+
+        // Properties.
+        public TunnelingRequestDataBlock TunnelingRequestDataBlock { get; }
+        public CEMI Cemi { get; }
+
+        public TunnelingRequest(TunnelingRequestDataBlock tunnelingRequestDataBlock, CEMI cemi)
+        {
+            TunnelingRequestDataBlock = tunnelingRequestDataBlock;
+            Cemi = cemi;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingRequestDataBlock.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingRequestDataBlock.cs
new file mode 100644
index 0000000..ce8aa02
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingRequestDataBlock.cs
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class TunnelingRequestDataBlock
+    {
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public byte SequenceCounter { get; }
+
+        public TunnelingRequestDataBlock(byte communicationChannelId, byte sequenceCounter)
+        {
+            CommunicationChannelId = communicationChannelId;
+            SequenceCounter = sequenceCounter;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingResponse.cs
new file mode 100644
index 0000000..3c5f21e
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingResponse.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class TunnelingResponse : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x0421;
+        }
+
+        // Properties.
+        public TunnelingResponseDataBlock TunnelingResponseDataBlock { get; }
+
+        public TunnelingResponse(TunnelingResponseDataBlock tunnelingResponseDataBlock)
+        {
+            TunnelingResponseDataBlock = tunnelingResponseDataBlock;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingResponseDataBlock.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingResponseDataBlock.cs
new file mode 100644
index 0000000..ccd50b5
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TunnelingResponseDataBlock.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class TunnelingResponseDataBlock
+    {
+
+        // Properties.
+        public byte CommunicationChannelId { get; }
+        public byte SequenceCounter { get; }
+        public Status Status { get; }
+
+        public TunnelingResponseDataBlock(byte communicationChannelId, byte sequenceCounter, Status status)
+        {
+            CommunicationChannelId = communicationChannelId;
+            SequenceCounter = sequenceCounter;
+            Status = status;
+        }
+
+    }
+
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/UnknownMessage.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/UnknownMessage.cs
new file mode 100644
index 0000000..e20e6bc
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/UnknownMessage.cs
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class UnknownMessage : KnxNetIpMessage
+    {
+        // Accessors for discriminator values.
+        public override ushort GetMsgType() {
+            return 0x020B;
+        }
+
+        // Properties.
+        public sbyte[] UnknownData { get; }
+
+        public UnknownMessage(sbyte[] unknownData)
+        {
+            UnknownData = unknownData;
+        }
+
+    }
+
+}

[plc4x] 04/09: - Implemented the BitString functionality ob BYTE, WORD, DWORD and LWORD

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

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

commit 1e474ccb03b0577be335c090c883a78353f192ca
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Dec 3 15:06:22 2020 +0100

    - Implemented the BitString functionality ob BYTE, WORD, DWORD and LWORD
---
 sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs  | 27 ++++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs | 39 +++++++++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs | 55 ++++++++++++++++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcWORD.cs  | 31 +++++++++++++
 4 files changed, 152 insertions(+)

diff --git a/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs b/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs
index 5c3d26e..9351847 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs
@@ -24,9 +24,36 @@ namespace org.apache.plc4net.spi.model.values
     public class PlcBYTE : PlcBitString
     {
         private byte value;
+
         public PlcBYTE(byte value)
         {
             this.value = value;
         }
+
+        public new int GetBoolLength()
+        {
+            return 8;
+        }
+
+        public new bool GetBoolAt(int index)
+        {
+            if (index > 7)
+            {
+                return false;
+            }
+
+            return ((value >> index) & 1) == 1;
+        }
+
+        public new bool[] GetBoolArray()
+        {
+            return new[]
+            {
+                GetBoolAt(0), GetBoolAt(1),
+                GetBoolAt(2), GetBoolAt(3),
+                GetBoolAt(4), GetBoolAt(5),
+                GetBoolAt(6), GetBoolAt(7)
+            };
+        }
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs
index dad1973..3051771 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs
@@ -29,5 +29,44 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+        
+        public new int GetBoolLength()
+        {
+            return 32;
+        }
+        
+        public new bool GetBoolAt(int index)
+        {
+            if (index > 31)
+            {
+                return false;
+            }
+
+            return ((value >> index) & 1) == 1;
+        }
+
+        public new bool[] GetBoolArray()
+        {
+            return new[]
+            {
+                GetBoolAt(0), GetBoolAt(1),
+                GetBoolAt(2), GetBoolAt(3),
+                GetBoolAt(4), GetBoolAt(5),
+                GetBoolAt(6), GetBoolAt(7),
+                GetBoolAt(8), GetBoolAt(9),
+                GetBoolAt(10), GetBoolAt(11),
+                GetBoolAt(12), GetBoolAt(13),
+                GetBoolAt(14), GetBoolAt(15),
+                GetBoolAt(16), GetBoolAt(17),
+                GetBoolAt(18), GetBoolAt(19),
+                GetBoolAt(20), GetBoolAt(21),
+                GetBoolAt(22), GetBoolAt(23),
+                GetBoolAt(24), GetBoolAt(25),
+                GetBoolAt(26), GetBoolAt(27),
+                GetBoolAt(28), GetBoolAt(29),
+                GetBoolAt(30), GetBoolAt(31)
+            };
+        }
+
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs
index bfe68af..64d67f3 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs
@@ -29,5 +29,60 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+        
+        public new int GetBoolLength()
+        {
+            return 64;
+        }
+        
+        public new bool GetBoolAt(int index)
+        {
+            if (index > 63)
+            {
+                return false;
+            }
+
+            return ((value >> index) & 1) == 1;
+        }
+
+        public new bool[] GetBoolArray()
+        {
+            return new[]
+            {
+                GetBoolAt(0), GetBoolAt(1),
+                GetBoolAt(2), GetBoolAt(3),
+                GetBoolAt(4), GetBoolAt(5),
+                GetBoolAt(6), GetBoolAt(7),
+                GetBoolAt(8), GetBoolAt(9),
+                GetBoolAt(10), GetBoolAt(11),
+                GetBoolAt(12), GetBoolAt(13),
+                GetBoolAt(14), GetBoolAt(15),
+                GetBoolAt(16), GetBoolAt(17),
+                GetBoolAt(18), GetBoolAt(19),
+                GetBoolAt(20), GetBoolAt(21),
+                GetBoolAt(22), GetBoolAt(23),
+                GetBoolAt(24), GetBoolAt(25),
+                GetBoolAt(26), GetBoolAt(27),
+                GetBoolAt(28), GetBoolAt(29),
+                GetBoolAt(30), GetBoolAt(31),
+                GetBoolAt(32), GetBoolAt(33),
+                GetBoolAt(34), GetBoolAt(35),
+                GetBoolAt(36), GetBoolAt(37),
+                GetBoolAt(38), GetBoolAt(39),
+                GetBoolAt(40), GetBoolAt(41),
+                GetBoolAt(42), GetBoolAt(43),
+                GetBoolAt(44), GetBoolAt(45),
+                GetBoolAt(46), GetBoolAt(47),
+                GetBoolAt(48), GetBoolAt(49),
+                GetBoolAt(50), GetBoolAt(51),
+                GetBoolAt(52), GetBoolAt(53),
+                GetBoolAt(54), GetBoolAt(55),
+                GetBoolAt(56), GetBoolAt(57),
+                GetBoolAt(58), GetBoolAt(59),
+                GetBoolAt(60), GetBoolAt(61),
+                GetBoolAt(62), GetBoolAt(63)
+            };
+        }
+
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs
index 2af3b09..84e2b99 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs
@@ -29,5 +29,36 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+        
+        public new int GetBoolLength()
+        {
+            return 16;
+        }
+        
+        public new bool GetBoolAt(int index)
+        {
+            if (index > 15)
+            {
+                return false;
+            }
+
+            return ((value >> index) & 1) == 1;
+        }
+
+        public new bool[] GetBoolArray()
+        {
+            return new[]
+            {
+                GetBoolAt(0), GetBoolAt(1),
+                GetBoolAt(2), GetBoolAt(3),
+                GetBoolAt(4), GetBoolAt(5),
+                GetBoolAt(6), GetBoolAt(7),
+                GetBoolAt(8), GetBoolAt(9),
+                GetBoolAt(10), GetBoolAt(11),
+                GetBoolAt(12), GetBoolAt(13),
+                GetBoolAt(14), GetBoolAt(15)
+            };
+        }
+
     }
 }
\ No newline at end of file

[plc4x] 03/09: - Finish implementing the WriteBuffer

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

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

commit 089e0cbc137ec31c9102712eca8ce25b9f40cc3d
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Dec 3 14:52:08 2020 +0100

    - Finish implementing the WriteBuffer
---
 sandbox/plc4net/api/api/value/IPlcValue.cs         | 19 +++++
 sandbox/plc4net/spi/spi/generation/ReadBuffer.cs   |  2 +-
 sandbox/plc4net/spi/spi/generation/WriteBuffer.cs  | 97 +++++++++++++++++++++-
 .../plc4net/spi/spi/model/values/PlcBitString.cs   | 19 +++++
 .../model/values/PlcSimpleNumericValueAdapter.cs   | 19 +++++
 .../spi/spi/model/values/PlcSimpleValueAdapter.cs  | 19 +++++
 .../spi/spi/model/values/PlcValueAdapter.cs        | 19 +++++
 7 files changed, 189 insertions(+), 5 deletions(-)

diff --git a/sandbox/plc4net/api/api/value/IPlcValue.cs b/sandbox/plc4net/api/api/value/IPlcValue.cs
index e3e29a4..a6682b9 100644
--- a/sandbox/plc4net/api/api/value/IPlcValue.cs
+++ b/sandbox/plc4net/api/api/value/IPlcValue.cs
@@ -1,3 +1,22 @@
+//
+// 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.
+//
+
 using System;
 using System.Collections.Generic;
 
diff --git a/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs b/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs
index a14ff8c..f727fba 100644
--- a/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs
+++ b/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs
@@ -196,7 +196,7 @@ namespace org.apache.plc4net.spi.generation
 
         public string ReadString(int bitLength, Encoding encoding)
         {
-            return "";
+            throw new NotImplementedException("This encoding is currently not supported");
         }
 
     }
diff --git a/sandbox/plc4net/spi/spi/generation/WriteBuffer.cs b/sandbox/plc4net/spi/spi/generation/WriteBuffer.cs
index 5f4b3b1..c6e8f82 100644
--- a/sandbox/plc4net/spi/spi/generation/WriteBuffer.cs
+++ b/sandbox/plc4net/spi/spi/generation/WriteBuffer.cs
@@ -17,72 +17,161 @@
 // under the License.
 //
 
+using System;
+using Ayx.BitIO;
+
 namespace org.apache.plc4net.spi.generation
 {
     public class WriteBuffer
     {
-        
+        private readonly BitWriter _writer;
+
+        public WriteBuffer()
+        {
+            _writer = new BitWriter();
+        }
+
         public int GetPos()
         {
-            return 0;
+            return _writer.Length;
         }
 
         public byte[] GetBytes()
         {
-            return null;
+            return _writer.GetBytes();
         }
     
         public int GetTotalBytes() 
         {
-            return 0;
+            return _writer.Length / 8 + (_writer.Length % 8 != 0 ? 1 : 0);
         }
 
         public void WriteBit(bool value)
         {
+            _writer.WriteBool(value);
         }
 
         public void WriteByte(int bitLength, byte value)
         {
+            if (bitLength > 8)
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            _writer.WriteByte(value, bitLength);
         }
         
         public void WriteUshort(int bitLength, ushort value)
         {
+            if (bitLength > 16)
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            _writer.WriteInt(value, bitLength);
         }
 
         public void WriteUint(int bitLength, uint value)
         {
+            if (bitLength > 32)
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            _writer.WriteInt((int) value, bitLength);
         }
 
         public void WriteUlong(int bitLength, ulong value)
         {
+            if (bitLength > 64)
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            var highInt = (int) ((value & 0xFFFFFFFF00000000) >> 32);
+            var lowInt = (int) (value & 0xFFFFFFFF);
+            if (bitLength > 32)
+            {
+                _writer.WriteInt(highInt, bitLength - 32);
+                _writer.WriteInt(lowInt, 32);
+            }
+            else
+            {
+                _writer.WriteInt(lowInt, bitLength);
+            }
         }
 
         public void WriteSbyte(int bitLength, sbyte value)
         {
+            if (bitLength > 8)
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            _writer.WriteInt(value, bitLength);
         }
         
         public void WriteShort(int bitLength, short value)
         {
+            if (bitLength > 16)
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            _writer.WriteInt(value, bitLength);
         }
 
         public void WriteInt(int bitLength, int value)
         {
+            if (bitLength > 32)
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            _writer.WriteInt(value, bitLength);
         }
 
         public void WriteLong(int bitLength, long value)
         {
+            if (bitLength > 64)
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            WriteUlong(bitLength, (ulong) value);
         }
 
         public void WriteFloat(int bitLength, float value)
         {
+            if (bitLength == 32)
+            {
+                var bytes = BitConverter.GetBytes(value);
+                for (var i = 0; i < bytes.Length; i++)
+                {
+                    _writer.WriteByte(8, bytes[i]);
+                }
+            }
+            else if (bitLength == 16)
+            {
+                
+            }
+            else
+            {
+                throw new NotImplementedException("This encoding is currently not supported");
+            }
         }
 
         public void WriteDouble(int bitLength, double value)
         {
+            if (bitLength == 64)
+            {
+                var bytes = BitConverter.GetBytes(value);
+                for (var i = 0; i < bytes.Length; i++)
+                {
+                    _writer.WriteByte(8, bytes[i]);
+                }
+            }
+            else
+            {
+                throw new NotImplementedException("This encoding is currently not supported");
+            }
         }
 
         public void WriteString(int bitLength, string encoding, string value)
         {
+            throw new NotImplementedException("This encoding is currently not supported");
         }
 
     }
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcBitString.cs b/sandbox/plc4net/spi/spi/model/values/PlcBitString.cs
index 4bcbcba..d5747e9 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcBitString.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcBitString.cs
@@ -1,3 +1,22 @@
+//
+// 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.
+//
+
 namespace org.apache.plc4net.spi.model.values
 {
     public class PlcBitString : PlcValueAdapter
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs b/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs
index 2f0cbba..122cc0f 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs
@@ -1,3 +1,22 @@
+//
+// 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.
+//
+
 using System;
 
 namespace org.apache.plc4net.spi.model.values
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcSimpleValueAdapter.cs b/sandbox/plc4net/spi/spi/model/values/PlcSimpleValueAdapter.cs
index 52a64b9..787fe45 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcSimpleValueAdapter.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcSimpleValueAdapter.cs
@@ -1,3 +1,22 @@
+//
+// 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.
+//
+
 namespace org.apache.plc4net.spi.model.values
 {
     public abstract class PlcSimpleValueAdapter : PlcValueAdapter
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcValueAdapter.cs b/sandbox/plc4net/spi/spi/model/values/PlcValueAdapter.cs
index f5227f6..afd5e82 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcValueAdapter.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcValueAdapter.cs
@@ -1,3 +1,22 @@
+//
+// 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.
+//
+
 using System;
 using System.Collections.Generic;
 using org.apache.plc4net.api.value;

[plc4x] 07/09: - Added a check for the installation of `go` - Updated the dotnet check to check for at least version 4.5.2 - Added code generation for C# enums

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

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

commit 3e17453993265fc545e261221f8d3a784e72b9e8
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Dec 3 22:08:54 2020 +0100

    - Added a check for the installation of `go`
    - Updated the dotnet check to check for at least version 4.5.2
    - Added code generation for C# enums
---
 .../apache/plc4x/language/cs/CsLanguageOutput.java |    3 +-
 .../main/resources/templates/cs/enum-template.ftlh |   85 +
 .../knxnetip/readwrite/model/KnxDatapointTests.cs  |   20 +-
 .../knxnetip/src/knxnetip/readwrite/model/APCI.cs  |   46 +
 .../src/knxnetip/readwrite/model/CEMIPriority.cs   |   34 +
 .../knxnetip/readwrite/model/HostProtocolCode.cs   |   32 +
 .../knxnetip/readwrite/model/KnxDatapointType.cs   | 3634 ++++++++++++++++++++
 .../src/knxnetip/readwrite/model/KnxLayer.cs       |   33 +
 .../src/knxnetip/readwrite/model/KnxMedium.cs      |   36 +
 .../src/knxnetip/readwrite/model/Status.cs         |   42 +
 .../readwrite/model/SupportedPhysicalMedia.cs      |  201 ++
 .../knxnetip/src/knxnetip/readwrite/model/TPCI.cs  |   34 +
 src/main/script/prerequisiteCheck.groovy           |   29 +-
 13 files changed, 4226 insertions(+), 3 deletions(-)

diff --git a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
index fc5a489..a71b4dd 100644
--- a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
+++ b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
@@ -55,7 +55,8 @@ public class CsLanguageOutput extends FreemarkerLanguageOutput {
 
     @Override
     protected List<Template> getEnumTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
-        return Collections.emptyList();
+        return Collections.singletonList(
+            freemarkerConfiguration.getTemplate("templates/cs/enum-template.ftlh"));
     }
 
     @Override
diff --git a/build-utils/language-cs/src/main/resources/templates/cs/enum-template.ftlh b/build-utils/language-cs/src/main/resources/templates/cs/enum-template.ftlh
new file mode 100644
index 0000000..f65432d
--- /dev/null
+++ b/build-utils/language-cs/src/main/resources/templates/cs/enum-template.ftlh
@@ -0,0 +1,85 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.EnumTypeDefinition" -->
+<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/${type.name}.cs
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFlavor?replace("-", "")}.model
+{
+
+    public enum ${type.name}<#if !helper.isStringTypeReference(type.type)> : ${helper.getLanguageTypeNameForTypeReference(type.type)}</#if>
+    {
+
+    <#list type.enumValues as enumValue>
+        ${enumValue.name}<#if !helper.isStringTypeReference(type.type)> = ${enumValue.value}</#if>,
+    </#list>
+
+    }
+
+    <#if type.constantNames?has_content>
+    public static class ${type.name}Info
+    {
+        <#list type.constantNames as constantName>
+
+        public static ${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName))} ${constantName?cap_first}(this ${type.name} value)
+        {
+            switch (value)
+            {
+            <#list helper.getUniqueEnumValues(type.enumValues) as enumValue>
+                case ${type.name}.${enumValue.name}: { /* '${enumValue.value}' */
+                    return ${helper.escapeEnumValue(type.getConstantType(constantName), enumValue.getConstant(constantName))};
+                }
+            </#list>
+                default: {
+                    return ${helper.getNullValueForTypeReference(type.getConstantType(constantName))};
+                }
+            }
+        }
+        </#list>
+    }
+
+    </#if>
+}
+
+</#outputformat>
diff --git a/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs b/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs
index 64a0d55..57e290d 100644
--- a/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs
+++ b/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs
@@ -1,4 +1,22 @@
-using System;
+//
+// 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.
+//
+
 using System.Collections.Generic;
 using org.apache.plc4net.api.value;
 using org.apache.plc4net.drivers.knxnetip.readwrite.model;
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/APCI.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/APCI.cs
new file mode 100644
index 0000000..71fdd8c
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/APCI.cs
@@ -0,0 +1,46 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum APCI : byte
+    {
+
+        GROUP_VALUE_READ_PDU = 0x0,
+        GROUP_VALUE_RESPONSE_PDU = 0x1,
+        GROUP_VALUE_WRITE_PDU = 0x2,
+        INDIVIDUAL_ADDRESS_WRITE_PDU = 0x3,
+        INDIVIDUAL_ADDRESS_READ_PDU = 0x4,
+        INDIVIDUAL_ADDRESS_RESPONSE_PDU = 0x5,
+        ADC_READ_PDU = 0x6,
+        ADC_RESPONSE_PDU = 0x7,
+        MEMORY_READ_PDU = 0x8,
+        MEMORY_RESPONSE_PDU = 0x9,
+        MEMORY_WRITE_PDU = 0xA,
+        USER_MESSAGE_PDU = 0xB,
+        DEVICE_DESCRIPTOR_READ_PDU = 0xC,
+        DEVICE_DESCRIPTOR_RESPONSE_PDU = 0xD,
+        RESTART_PDU = 0xE,
+        OTHER_PDU = 0xF,
+
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPriority.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPriority.cs
new file mode 100644
index 0000000..089f7ee
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/CEMIPriority.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum CEMIPriority : byte
+    {
+
+        SYSTEM = 0x0,
+        NORMAL = 0x1,
+        URGENT = 0x2,
+        LOW = 0x3,
+
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HostProtocolCode.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HostProtocolCode.cs
new file mode 100644
index 0000000..24d3497
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/HostProtocolCode.cs
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum HostProtocolCode : byte
+    {
+
+        IPV4_UDP = 0x01,
+        IPV4_TCP = 0x02,
+
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxDatapointType.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxDatapointType.cs
new file mode 100644
index 0000000..efa608c
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxDatapointType.cs
@@ -0,0 +1,3634 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum KnxDatapointType
+    {
+
+        DPT_Switch,
+        DPT_Bool,
+        DPT_Enable,
+        DPT_Ramp,
+        DPT_Alarm,
+        DPT_BinaryValue,
+        DPT_Step,
+        DPT_UpDown,
+        DPT_OpenClose,
+        DPT_Start,
+        DPT_State,
+        DPT_Invert,
+        DPT_DimSendStyle,
+        DPT_InputSource,
+        DPT_Reset,
+        DPT_Ack,
+        DPT_Trigger,
+        DPT_Occupancy,
+        DPT_Window_Door,
+        DPT_LogicalFunction,
+        DPT_Scene_AB,
+        DPT_ShutterBlinds_Mode,
+        DPT_Heat_Cool,
+        DPT_Switch_Control,
+        DPT_Bool_Control,
+        DPT_Enable_Control,
+        DPT_Ramp_Control,
+        DPT_Alarm_Control,
+        DPT_BinaryValue_Control,
+        DPT_Step_Control,
+        DPT_Direction1_Control,
+        DPT_Direction2_Control,
+        DPT_Start_Control,
+        DPT_State_Control,
+        DPT_Invert_Control,
+        DPT_Control_Dimming,
+        DPT_Control_Blinds,
+        DPT_Char_ASCII,
+        DPT_Char_8859_1,
+        DPT_Scaling,
+        DPT_Angle,
+        DPT_Percent_U8,
+        DPT_DecimalFactor,
+        DPT_Tariff,
+        DPT_Value_1_Ucount,
+        DPT_Percent_V8,
+        DPT_Value_1_Count,
+        DPT_Status_Mode3,
+        DPT_Value_2_Ucount,
+        DPT_TimePeriodMsec,
+        DPT_TimePeriod10MSec,
+        DPT_TimePeriod100MSec,
+        DPT_TimePeriodSec,
+        DPT_TimePeriodMin,
+        DPT_TimePeriodHrs,
+        DPT_PropDataType,
+        DPT_Length_mm,
+        DPT_UElCurrentmA,
+        DPT_Brightness,
+        DPT_Value_2_Count,
+        DPT_DeltaTimeMsec,
+        DPT_DeltaTime10MSec,
+        DPT_DeltaTime100MSec,
+        DPT_DeltaTimeSec,
+        DPT_DeltaTimeMin,
+        DPT_DeltaTimeHrs,
+        DPT_Percent_V16,
+        DPT_Rotation_Angle,
+        DPT_Value_Temp,
+        DPT_Value_Tempd,
+        DPT_Value_Tempa,
+        DPT_Value_Lux,
+        DPT_Value_Wsp,
+        DPT_Value_Pres,
+        DPT_Value_Humidity,
+        DPT_Value_AirQuality,
+        DPT_Value_Time1,
+        DPT_Value_Time2,
+        DPT_Value_Volt,
+        DPT_Value_Curr,
+        DPT_PowerDensity,
+        DPT_KelvinPerPercent,
+        DPT_Power,
+        DPT_Value_Volume_Flow,
+        DPT_Rain_Amount,
+        DPT_Value_Temp_F,
+        DPT_Value_Wsp_kmh,
+        DPT_TimeOfDay,
+        DPT_Date,
+        DPT_Value_4_Ucount,
+        DPT_Value_4_Count,
+        DPT_FlowRate_m3h,
+        DPT_ActiveEnergy,
+        DPT_ApparantEnergy,
+        DPT_ReactiveEnergy,
+        DPT_ActiveEnergy_kWh,
+        DPT_ApparantEnergy_kVAh,
+        DPT_ReactiveEnergy_kVARh,
+        DPT_LongDeltaTimeSec,
+        DPT_Value_Acceleration,
+        DPT_Value_Acceleration_Angular,
+        DPT_Value_Activation_Energy,
+        DPT_Value_Activity,
+        DPT_Value_Mol,
+        DPT_Value_Amplitude,
+        DPT_Value_AngleRad,
+        DPT_Value_AngleDeg,
+        DPT_Value_Angular_Momentum,
+        DPT_Value_Angular_Velocity,
+        DPT_Value_Area,
+        DPT_Value_Capacitance,
+        DPT_Value_Charge_DensitySurface,
+        DPT_Value_Charge_DensityVolume,
+        DPT_Value_Compressibility,
+        DPT_Value_Conductance,
+        DPT_Value_Electrical_Conductivity,
+        DPT_Value_Density,
+        DPT_Value_Electric_Charge,
+        DPT_Value_Electric_Current,
+        DPT_Value_Electric_CurrentDensity,
+        DPT_Value_Electric_DipoleMoment,
+        DPT_Value_Electric_Displacement,
+        DPT_Value_Electric_FieldStrength,
+        DPT_Value_Electric_Flux,
+        DPT_Value_Electric_FluxDensity,
+        DPT_Value_Electric_Polarization,
+        DPT_Value_Electric_Potential,
+        DPT_Value_Electric_PotentialDifference,
+        DPT_Value_ElectromagneticMoment,
+        DPT_Value_Electromotive_Force,
+        DPT_Value_Energy,
+        DPT_Value_Force,
+        DPT_Value_Frequency,
+        DPT_Value_Angular_Frequency,
+        DPT_Value_Heat_Capacity,
+        DPT_Value_Heat_FlowRate,
+        DPT_Value_Heat_Quantity,
+        DPT_Value_Impedance,
+        DPT_Value_Length,
+        DPT_Value_Light_Quantity,
+        DPT_Value_Luminance,
+        DPT_Value_Luminous_Flux,
+        DPT_Value_Luminous_Intensity,
+        DPT_Value_Magnetic_FieldStrength,
+        DPT_Value_Magnetic_Flux,
+        DPT_Value_Magnetic_FluxDensity,
+        DPT_Value_Magnetic_Moment,
+        DPT_Value_Magnetic_Polarization,
+        DPT_Value_Magnetization,
+        DPT_Value_MagnetomotiveForce,
+        DPT_Value_Mass,
+        DPT_Value_MassFlux,
+        DPT_Value_Momentum,
+        DPT_Value_Phase_AngleRad,
+        DPT_Value_Phase_AngleDeg,
+        DPT_Value_Power,
+        DPT_Value_Power_Factor,
+        DPT_Value_Pressure,
+        DPT_Value_Reactance,
+        DPT_Value_Resistance,
+        DPT_Value_Resistivity,
+        DPT_Value_SelfInductance,
+        DPT_Value_SolidAngle,
+        DPT_Value_Sound_Intensity,
+        DPT_Value_Speed,
+        DPT_Value_Stress,
+        DPT_Value_Surface_Tension,
+        DPT_Value_Common_Temperature,
+        DPT_Value_Absolute_Temperature,
+        DPT_Value_TemperatureDifference,
+        DPT_Value_Thermal_Capacity,
+        DPT_Value_Thermal_Conductivity,
+        DPT_Value_ThermoelectricPower,
+        DPT_Value_Time,
+        DPT_Value_Torque,
+        DPT_Value_Volume,
+        DPT_Value_Volume_Flux,
+        DPT_Value_Weight,
+        DPT_Value_Work,
+        DPT_Access_Data,
+        DPT_String_ASCII,
+        DPT_String_8859_1,
+        DPT_SceneNumber,
+        DPT_SceneControl,
+        DPT_DateTime,
+        DPT_SCLOMode,
+        DPT_BuildingMode,
+        DPT_OccMode,
+        DPT_Priority,
+        DPT_LightApplicationMode,
+        DPT_ApplicationArea,
+        DPT_AlarmClassType,
+        DPT_PSUMode,
+        DPT_ErrorClass_System,
+        DPT_ErrorClass_HVAC,
+        DPT_Time_Delay,
+        DPT_Beaufort_Wind_Force_Scale,
+        DPT_SensorSelect,
+        DPT_ActuatorConnectType,
+        DPT_FuelType,
+        DPT_BurnerType,
+        DPT_HVACMode,
+        DPT_DHWMode,
+        DPT_LoadPriority,
+        DPT_HVACContrMode,
+        DPT_HVACEmergMode,
+        DPT_ChangeoverMode,
+        DPT_ValveMode,
+        DPT_DamperMode,
+        DPT_HeaterMode,
+        DPT_FanMode,
+        DPT_MasterSlaveMode,
+        DPT_StatusRoomSetp,
+        DPT_ADAType,
+        DPT_BackupMode,
+        DPT_StartSynchronization,
+        DPT_Behaviour_Lock_Unlock,
+        DPT_Behaviour_Bus_Power_Up_Down,
+        DPT_DALI_Fade_Time,
+        DPT_BlinkingMode,
+        DPT_LightControlMode,
+        DPT_SwitchPBModel,
+        DPT_PBAction,
+        DPT_DimmPBModel,
+        DPT_SwitchOnMode,
+        DPT_LoadTypeSet,
+        DPT_LoadTypeDetected,
+        DPT_SABExceptBehaviour,
+        DPT_SABBehaviour_Lock_Unlock,
+        DPT_SSSBMode,
+        DPT_BlindsControlMode,
+        DPT_CommMode,
+        DPT_AddInfoTypes,
+        DPT_RF_ModeSelect,
+        DPT_RF_FilterSelect,
+        DPT_StatusGen,
+        DPT_Device_Control,
+        DPT_ForceSign,
+        DPT_ForceSignCool,
+        DPT_StatusRHC,
+        DPT_StatusSDHWC,
+        DPT_FuelTypeSet,
+        DPT_StatusRCC,
+        DPT_StatusAHU,
+        DPT_LightActuatorErrorInfo,
+        DPT_RF_ModeInfo,
+        DPT_RF_FilterInfo,
+        DPT_Channel_Activation_8,
+        DPT_StatusDHWC,
+        DPT_StatusRHCC,
+        DPT_Media,
+        DPT_Channel_Activation_16,
+        DPT_OnOff_Action,
+        DPT_Alarm_Reaction,
+        DPT_UpDown_Action,
+        DPT_HVAC_PB_Action,
+        DPT_VarString_8859_1,
+        DPT_DoubleNibble,
+        DPT_SceneInfo,
+        DPT_CombinedInfoOnOff,
+        DPT_UTF_8,
+        DPT_ActiveEnergy_V64,
+        DPT_ApparantEnergy_V64,
+        DPT_ReactiveEnergy_V64,
+        DPT_Channel_Activation_24,
+        DPT_PB_Action_HVAC_Extended,
+        DPT_Heat_Cool_Z,
+        DPT_BinaryValue_Z,
+        DPT_HVACMode_Z,
+        DPT_DHWMode_Z,
+        DPT_HVACContrMode_Z,
+        DPT_EnablH_Cstage_Z_DPT_EnablH_CStage,
+        DPT_BuildingMode_Z,
+        DPT_OccMode_Z,
+        DPT_HVACEmergMode_Z,
+        DPT_RelValue_Z,
+        DPT_UCountValue8_Z,
+        DPT_TimePeriodMsec_Z,
+        DPT_TimePeriod10Msec_Z,
+        DPT_TimePeriod100Msec_Z,
+        DPT_TimePeriodSec_Z,
+        DPT_TimePeriodMin_Z,
+        DPT_TimePeriodHrs_Z,
+        DPT_UFlowRateLiter_h_Z,
+        DPT_UCountValue16_Z,
+        DPT_UElCurrentyA_Z,
+        DPT_PowerKW_Z,
+        DPT_AtmPressureAbs_Z,
+        DPT_PercentU16_Z,
+        DPT_HVACAirQual_Z,
+        DPT_WindSpeed_Z_DPT_WindSpeed,
+        DPT_SunIntensity_Z,
+        DPT_HVACAirFlowAbs_Z,
+        DPT_RelSignedValue_Z,
+        DPT_DeltaTimeMsec_Z,
+        DPT_DeltaTime10Msec_Z,
+        DPT_DeltaTime100Msec_Z,
+        DPT_DeltaTimeSec_Z,
+        DPT_DeltaTimeMin_Z,
+        DPT_DeltaTimeHrs_Z,
+        DPT_Percent_V16_Z,
+        DPT_TempHVACAbs_Z,
+        DPT_TempHVACRel_Z,
+        DPT_HVACAirFlowRel_Z,
+        DPT_HVACModeNext,
+        DPT_DHWModeNext,
+        DPT_OccModeNext,
+        DPT_BuildingModeNext,
+        DPT_StatusBUC,
+        DPT_LockSign,
+        DPT_ValueDemBOC,
+        DPT_ActPosDemAbs,
+        DPT_StatusAct,
+        DPT_StatusLightingActuator,
+        DPT_StatusHPM,
+        DPT_TempRoomDemAbs,
+        DPT_StatusCPM,
+        DPT_StatusWTC,
+        DPT_TempFlowWaterDemAbs,
+        DPT_EnergyDemWater,
+        DPT_TempRoomSetpSetShift3,
+        DPT_TempRoomSetpSet3,
+        DPT_TempRoomSetpSet4,
+        DPT_TempDHWSetpSet4,
+        DPT_TempRoomSetpSetShift4,
+        DPT_PowerFlowWaterDemHPM,
+        DPT_PowerFlowWaterDemCPM,
+        DPT_StatusBOC,
+        DPT_StatusCC,
+        DPT_SpecHeatProd,
+        DPT_Version,
+        DPT_VolumeLiter_Z,
+        DPT_FlowRate_m3h_Z,
+        DPT_AlarmInfo,
+        DPT_TempHVACAbsNext,
+        DPT_SerNum,
+        DPT_TempRoomSetpSetF163,
+        DPT_TempRoomSetpSetShiftF163,
+        DPT_EnergyDemAir,
+        DPT_TempSupply_AirSetpSet,
+        DPT_ScalingSpeed,
+        DPT_Scaling_Step_Time,
+        DPT_TariffNext,
+        DPT_MeteringValue,
+        DPT_MBus_Address,
+        DPT_Locale_ASCII,
+        DPT_Colour_RGB,
+        DPT_LanguageCodeAlpha2_ASCII,
+        DPT_RegionCodeAlpha2_ASCII,
+        DPT_Tariff_ActiveEnergy,
+        DPT_Prioritised_Mode_Control,
+        DPT_DALI_Control_Gear_Diagnostic,
+        DPT_SceneConfig,
+        DPT_DALI_Diagnostics,
+        DPT_FlaggedScaling,
+        DPT_CombinedPosition,
+        DPT_StatusSAB,
+
+    }
+
+    public static class KnxDatapointTypeInfo
+    {
+
+        public static string FormatName(this KnxDatapointType value)
+        {
+            switch (value)
+            {
+                case KnxDatapointType.DPT_ADAType: { /* 'DPT_ADAType' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Access_Data: { /* 'DPT_Access_Data' */
+                    return "U4U4U4U4U4U4B4N4";
+                }
+                case KnxDatapointType.DPT_Ack: { /* 'DPT_Ack' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_ActPosDemAbs: { /* 'DPT_ActPosDemAbs' */
+                    return "U8B8ActuatorPositionDemand";
+                }
+                case KnxDatapointType.DPT_ActiveEnergy: { /* 'DPT_ActiveEnergy' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_ActiveEnergy_V64: { /* 'DPT_ActiveEnergy_V64' */
+                    return "V64";
+                }
+                case KnxDatapointType.DPT_ActiveEnergy_kWh: { /* 'DPT_ActiveEnergy_kWh' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_ActuatorConnectType: { /* 'DPT_ActuatorConnectType' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_AddInfoTypes: { /* 'DPT_AddInfoTypes' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Alarm: { /* 'DPT_Alarm' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_AlarmClassType: { /* 'DPT_AlarmClassType' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_AlarmInfo: { /* 'DPT_AlarmInfo' */
+                    return "U8N8N8N8B8B8";
+                }
+                case KnxDatapointType.DPT_Alarm_Control: { /* 'DPT_Alarm_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_Alarm_Reaction: { /* 'DPT_Alarm_Reaction' */
+                    return "N2";
+                }
+                case KnxDatapointType.DPT_Angle: { /* 'DPT_Angle' */
+                    return "U8";
+                }
+                case KnxDatapointType.DPT_ApparantEnergy: { /* 'DPT_ApparantEnergy' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_ApparantEnergy_V64: { /* 'DPT_ApparantEnergy_V64' */
+                    return "V64";
+                }
+                case KnxDatapointType.DPT_ApparantEnergy_kVAh: { /* 'DPT_ApparantEnergy_kVAh' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_ApplicationArea: { /* 'DPT_ApplicationArea' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_AtmPressureAbs_Z: { /* 'DPT_AtmPressureAbs_Z' */
+                    return "U16Z8AtmPressure";
+                }
+                case KnxDatapointType.DPT_BackupMode: { /* 'DPT_BackupMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Beaufort_Wind_Force_Scale: { /* 'DPT_Beaufort_Wind_Force_Scale' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Behaviour_Bus_Power_Up_Down: { /* 'DPT_Behaviour_Bus_Power_Up_Down' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Behaviour_Lock_Unlock: { /* 'DPT_Behaviour_Lock_Unlock' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_BinaryValue: { /* 'DPT_BinaryValue' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_BinaryValue_Control: { /* 'DPT_BinaryValue_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_BinaryValue_Z: { /* 'DPT_BinaryValue_Z' */
+                    return "B1Z8BinaryValueZ";
+                }
+                case KnxDatapointType.DPT_BlindsControlMode: { /* 'DPT_BlindsControlMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_BlinkingMode: { /* 'DPT_BlinkingMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Bool: { /* 'DPT_Bool' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_Bool_Control: { /* 'DPT_Bool_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_Brightness: { /* 'DPT_Brightness' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_BuildingMode: { /* 'DPT_BuildingMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_BuildingModeNext: { /* 'DPT_BuildingModeNext' */
+                    return "U16N8BuildingModeAndTimeDelay";
+                }
+                case KnxDatapointType.DPT_BuildingMode_Z: { /* 'DPT_BuildingMode_Z' */
+                    return "N8Z8BuildingMode";
+                }
+                case KnxDatapointType.DPT_BurnerType: { /* 'DPT_BurnerType' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_ChangeoverMode: { /* 'DPT_ChangeoverMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Channel_Activation_16: { /* 'DPT_Channel_Activation_16' */
+                    return "B16";
+                }
+                case KnxDatapointType.DPT_Channel_Activation_24: { /* 'DPT_Channel_Activation_24' */
+                    return "B24";
+                }
+                case KnxDatapointType.DPT_Channel_Activation_8: { /* 'DPT_Channel_Activation_8' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_Char_8859_1: { /* 'DPT_Char_8859_1' */
+                    return "A8_8859_1";
+                }
+                case KnxDatapointType.DPT_Char_ASCII: { /* 'DPT_Char_ASCII' */
+                    return "A8_ASCII";
+                }
+                case KnxDatapointType.DPT_Colour_RGB: { /* 'DPT_Colour_RGB' */
+                    return "U8U8U8";
+                }
+                case KnxDatapointType.DPT_CombinedInfoOnOff: { /* 'DPT_CombinedInfoOnOff' */
+                    return "B32";
+                }
+                case KnxDatapointType.DPT_CombinedPosition: { /* 'DPT_CombinedPosition' */
+                    return "U8U8B8";
+                }
+                case KnxDatapointType.DPT_CommMode: { /* 'DPT_CommMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Control_Blinds: { /* 'DPT_Control_Blinds' */
+                    return "B1U3";
+                }
+                case KnxDatapointType.DPT_Control_Dimming: { /* 'DPT_Control_Dimming' */
+                    return "B1U3";
+                }
+                case KnxDatapointType.DPT_DALI_Control_Gear_Diagnostic: { /* 'DPT_DALI_Control_Gear_Diagnostic' */
+                    return "B10U6";
+                }
+                case KnxDatapointType.DPT_DALI_Diagnostics: { /* 'DPT_DALI_Diagnostics' */
+                    return "B2U6";
+                }
+                case KnxDatapointType.DPT_DALI_Fade_Time: { /* 'DPT_DALI_Fade_Time' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_DHWMode: { /* 'DPT_DHWMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_DHWModeNext: { /* 'DPT_DHWModeNext' */
+                    return "U16N8DhwModeAndTimeDelay";
+                }
+                case KnxDatapointType.DPT_DHWMode_Z: { /* 'DPT_DHWMode_Z' */
+                    return "N8Z8DhwMode";
+                }
+                case KnxDatapointType.DPT_DamperMode: { /* 'DPT_DamperMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Date: { /* 'DPT_Date' */
+                    return "r3N5r4N4r1U7";
+                }
+                case KnxDatapointType.DPT_DateTime: { /* 'DPT_DateTime' */
+                    return "U8r4U4r3U5U3U5r2U6r2U6B16";
+                }
+                case KnxDatapointType.DPT_DecimalFactor: { /* 'DPT_DecimalFactor' */
+                    return "U8";
+                }
+                case KnxDatapointType.DPT_DeltaTime100MSec: { /* 'DPT_DeltaTime100MSec' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_DeltaTime100Msec_Z: { /* 'DPT_DeltaTime100Msec_Z' */
+                    return "V16Z8DeltaTime";
+                }
+                case KnxDatapointType.DPT_DeltaTime10MSec: { /* 'DPT_DeltaTime10MSec' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_DeltaTime10Msec_Z: { /* 'DPT_DeltaTime10Msec_Z' */
+                    return "V16Z8DeltaTime";
+                }
+                case KnxDatapointType.DPT_DeltaTimeHrs: { /* 'DPT_DeltaTimeHrs' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_DeltaTimeHrs_Z: { /* 'DPT_DeltaTimeHrs_Z' */
+                    return "V16Z8DeltaTime";
+                }
+                case KnxDatapointType.DPT_DeltaTimeMin: { /* 'DPT_DeltaTimeMin' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_DeltaTimeMin_Z: { /* 'DPT_DeltaTimeMin_Z' */
+                    return "V16Z8DeltaTime";
+                }
+                case KnxDatapointType.DPT_DeltaTimeMsec: { /* 'DPT_DeltaTimeMsec' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_DeltaTimeMsec_Z: { /* 'DPT_DeltaTimeMsec_Z' */
+                    return "V16Z8DeltaTime";
+                }
+                case KnxDatapointType.DPT_DeltaTimeSec: { /* 'DPT_DeltaTimeSec' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_DeltaTimeSec_Z: { /* 'DPT_DeltaTimeSec_Z' */
+                    return "V16Z8DeltaTime";
+                }
+                case KnxDatapointType.DPT_Device_Control: { /* 'DPT_Device_Control' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_DimSendStyle: { /* 'DPT_DimSendStyle' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_DimmPBModel: { /* 'DPT_DimmPBModel' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Direction1_Control: { /* 'DPT_Direction1_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_Direction2_Control: { /* 'DPT_Direction2_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_DoubleNibble: { /* 'DPT_DoubleNibble' */
+                    return "U4U4";
+                }
+                case KnxDatapointType.DPT_EnablH_Cstage_Z_DPT_EnablH_CStage: { /* 'DPT_EnablH_Cstage_Z_DPT_EnablH_CStage' */
+                    return "N8Z8EnableHeatingOrCoolingStage";
+                }
+                case KnxDatapointType.DPT_Enable: { /* 'DPT_Enable' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_Enable_Control: { /* 'DPT_Enable_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_EnergyDemAir: { /* 'DPT_EnergyDemAir' */
+                    return "V8N8N8";
+                }
+                case KnxDatapointType.DPT_EnergyDemWater: { /* 'DPT_EnergyDemWater' */
+                    return "U8N8";
+                }
+                case KnxDatapointType.DPT_ErrorClass_HVAC: { /* 'DPT_ErrorClass_HVAC' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_ErrorClass_System: { /* 'DPT_ErrorClass_System' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_FanMode: { /* 'DPT_FanMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_FlaggedScaling: { /* 'DPT_FlaggedScaling' */
+                    return "U8r7B1";
+                }
+                case KnxDatapointType.DPT_FlowRate_m3h: { /* 'DPT_FlowRate_m3h' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_FlowRate_m3h_Z: { /* 'DPT_FlowRate_m3h_Z' */
+                    return "V32Z8FlowRate";
+                }
+                case KnxDatapointType.DPT_ForceSign: { /* 'DPT_ForceSign' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_ForceSignCool: { /* 'DPT_ForceSignCool' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_FuelType: { /* 'DPT_FuelType' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_FuelTypeSet: { /* 'DPT_FuelTypeSet' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_HVACAirFlowAbs_Z: { /* 'DPT_HVACAirFlowAbs_Z' */
+                    return "U16Z8HvacAirFlow";
+                }
+                case KnxDatapointType.DPT_HVACAirFlowRel_Z: { /* 'DPT_HVACAirFlowRel_Z' */
+                    return "V16Z8RelSignedValue";
+                }
+                case KnxDatapointType.DPT_HVACAirQual_Z: { /* 'DPT_HVACAirQual_Z' */
+                    return "U16Z8HvacAirQuality";
+                }
+                case KnxDatapointType.DPT_HVACContrMode: { /* 'DPT_HVACContrMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_HVACContrMode_Z: { /* 'DPT_HVACContrMode_Z' */
+                    return "N8Z8HvacControllingMode";
+                }
+                case KnxDatapointType.DPT_HVACEmergMode: { /* 'DPT_HVACEmergMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_HVACEmergMode_Z: { /* 'DPT_HVACEmergMode_Z' */
+                    return "N8Z8EmergencyMode";
+                }
+                case KnxDatapointType.DPT_HVACMode: { /* 'DPT_HVACMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_HVACModeNext: { /* 'DPT_HVACModeNext' */
+                    return "U16N8HvacModeAndTimeDelay";
+                }
+                case KnxDatapointType.DPT_HVACMode_Z: { /* 'DPT_HVACMode_Z' */
+                    return "N8Z8HvacOperatingMode";
+                }
+                case KnxDatapointType.DPT_HVAC_PB_Action: { /* 'DPT_HVAC_PB_Action' */
+                    return "N2";
+                }
+                case KnxDatapointType.DPT_Heat_Cool: { /* 'DPT_Heat_Cool' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_Heat_Cool_Z: { /* 'DPT_Heat_Cool_Z' */
+                    return "B1Z8HeatingOrCoolingZ";
+                }
+                case KnxDatapointType.DPT_HeaterMode: { /* 'DPT_HeaterMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_InputSource: { /* 'DPT_InputSource' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_Invert: { /* 'DPT_Invert' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_Invert_Control: { /* 'DPT_Invert_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_KelvinPerPercent: { /* 'DPT_KelvinPerPercent' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_LanguageCodeAlpha2_ASCII: { /* 'DPT_LanguageCodeAlpha2_ASCII' */
+                    return "A8A8Language";
+                }
+                case KnxDatapointType.DPT_Length_mm: { /* 'DPT_Length_mm' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_LightActuatorErrorInfo: { /* 'DPT_LightActuatorErrorInfo' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_LightApplicationMode: { /* 'DPT_LightApplicationMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_LightControlMode: { /* 'DPT_LightControlMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_LoadPriority: { /* 'DPT_LoadPriority' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_LoadTypeDetected: { /* 'DPT_LoadTypeDetected' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_LoadTypeSet: { /* 'DPT_LoadTypeSet' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Locale_ASCII: { /* 'DPT_Locale_ASCII' */
+                    return "A8A8A8A8";
+                }
+                case KnxDatapointType.DPT_LockSign: { /* 'DPT_LockSign' */
+                    return "U8B8LockingSignal";
+                }
+                case KnxDatapointType.DPT_LogicalFunction: { /* 'DPT_LogicalFunction' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_LongDeltaTimeSec: { /* 'DPT_LongDeltaTimeSec' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_MBus_Address: { /* 'DPT_MBus_Address' */
+                    return "U16U32U8N8";
+                }
+                case KnxDatapointType.DPT_MasterSlaveMode: { /* 'DPT_MasterSlaveMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Media: { /* 'DPT_Media' */
+                    return "B16";
+                }
+                case KnxDatapointType.DPT_MeteringValue: { /* 'DPT_MeteringValue' */
+                    return "V32N8Z8";
+                }
+                case KnxDatapointType.DPT_OccMode: { /* 'DPT_OccMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_OccModeNext: { /* 'DPT_OccModeNext' */
+                    return "U16N8OccupancyModeAndTimeDelay";
+                }
+                case KnxDatapointType.DPT_OccMode_Z: { /* 'DPT_OccMode_Z' */
+                    return "N8Z8OccupancyMode";
+                }
+                case KnxDatapointType.DPT_Occupancy: { /* 'DPT_Occupancy' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_OnOff_Action: { /* 'DPT_OnOff_Action' */
+                    return "N2";
+                }
+                case KnxDatapointType.DPT_OpenClose: { /* 'DPT_OpenClose' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_PBAction: { /* 'DPT_PBAction' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_PB_Action_HVAC_Extended: { /* 'DPT_PB_Action_HVAC_Extended' */
+                    return "N3";
+                }
+                case KnxDatapointType.DPT_PSUMode: { /* 'DPT_PSUMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_PercentU16_Z: { /* 'DPT_PercentU16_Z' */
+                    return "U16Z8PercentValue";
+                }
+                case KnxDatapointType.DPT_Percent_U8: { /* 'DPT_Percent_U8' */
+                    return "U8";
+                }
+                case KnxDatapointType.DPT_Percent_V16: { /* 'DPT_Percent_V16' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_Percent_V16_Z: { /* 'DPT_Percent_V16_Z' */
+                    return "V16Z8RelSignedValue";
+                }
+                case KnxDatapointType.DPT_Percent_V8: { /* 'DPT_Percent_V8' */
+                    return "V8";
+                }
+                case KnxDatapointType.DPT_Power: { /* 'DPT_Power' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_PowerDensity: { /* 'DPT_PowerDensity' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_PowerFlowWaterDemCPM: { /* 'DPT_PowerFlowWaterDemCPM' */
+                    return "V16U8B8ChilledWater";
+                }
+                case KnxDatapointType.DPT_PowerFlowWaterDemHPM: { /* 'DPT_PowerFlowWaterDemHPM' */
+                    return "V16U8B8Heat";
+                }
+                case KnxDatapointType.DPT_PowerKW_Z: { /* 'DPT_PowerKW_Z' */
+                    return "U16Z8Power";
+                }
+                case KnxDatapointType.DPT_Prioritised_Mode_Control: { /* 'DPT_Prioritised_Mode_Control' */
+                    return "B1N3N4";
+                }
+                case KnxDatapointType.DPT_Priority: { /* 'DPT_Priority' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_PropDataType: { /* 'DPT_PropDataType' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_RF_FilterInfo: { /* 'DPT_RF_FilterInfo' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_RF_FilterSelect: { /* 'DPT_RF_FilterSelect' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_RF_ModeInfo: { /* 'DPT_RF_ModeInfo' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_RF_ModeSelect: { /* 'DPT_RF_ModeSelect' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Rain_Amount: { /* 'DPT_Rain_Amount' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Ramp: { /* 'DPT_Ramp' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_Ramp_Control: { /* 'DPT_Ramp_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy: { /* 'DPT_ReactiveEnergy' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy_V64: { /* 'DPT_ReactiveEnergy_V64' */
+                    return "V64";
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy_kVARh: { /* 'DPT_ReactiveEnergy_kVARh' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_RegionCodeAlpha2_ASCII: { /* 'DPT_RegionCodeAlpha2_ASCII' */
+                    return "A8A8Region";
+                }
+                case KnxDatapointType.DPT_RelSignedValue_Z: { /* 'DPT_RelSignedValue_Z' */
+                    return "V8Z8RelSignedValue";
+                }
+                case KnxDatapointType.DPT_RelValue_Z: { /* 'DPT_RelValue_Z' */
+                    return "U8Z8Rel";
+                }
+                case KnxDatapointType.DPT_Reset: { /* 'DPT_Reset' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_Rotation_Angle: { /* 'DPT_Rotation_Angle' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_SABBehaviour_Lock_Unlock: { /* 'DPT_SABBehaviour_Lock_Unlock' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_SABExceptBehaviour: { /* 'DPT_SABExceptBehaviour' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_SCLOMode: { /* 'DPT_SCLOMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_SSSBMode: { /* 'DPT_SSSBMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Scaling: { /* 'DPT_Scaling' */
+                    return "U8";
+                }
+                case KnxDatapointType.DPT_ScalingSpeed: { /* 'DPT_ScalingSpeed' */
+                    return "U16U8Scaling";
+                }
+                case KnxDatapointType.DPT_Scaling_Step_Time: { /* 'DPT_Scaling_Step_Time' */
+                    return "U16U8Scaling";
+                }
+                case KnxDatapointType.DPT_SceneConfig: { /* 'DPT_SceneConfig' */
+                    return "B2U6";
+                }
+                case KnxDatapointType.DPT_SceneControl: { /* 'DPT_SceneControl' */
+                    return "B1r1U6";
+                }
+                case KnxDatapointType.DPT_SceneInfo: { /* 'DPT_SceneInfo' */
+                    return "r1b1U6";
+                }
+                case KnxDatapointType.DPT_SceneNumber: { /* 'DPT_SceneNumber' */
+                    return "r2U6";
+                }
+                case KnxDatapointType.DPT_Scene_AB: { /* 'DPT_Scene_AB' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_SensorSelect: { /* 'DPT_SensorSelect' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_SerNum: { /* 'DPT_SerNum' */
+                    return "N16U32";
+                }
+                case KnxDatapointType.DPT_ShutterBlinds_Mode: { /* 'DPT_ShutterBlinds_Mode' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_SpecHeatProd: { /* 'DPT_SpecHeatProd' */
+                    return "U16U8N8B8";
+                }
+                case KnxDatapointType.DPT_Start: { /* 'DPT_Start' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_StartSynchronization: { /* 'DPT_StartSynchronization' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Start_Control: { /* 'DPT_Start_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_State: { /* 'DPT_State' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_State_Control: { /* 'DPT_State_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_StatusAHU: { /* 'DPT_StatusAHU' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_StatusAct: { /* 'DPT_StatusAct' */
+                    return "U8B8ActuatorPositionStatus";
+                }
+                case KnxDatapointType.DPT_StatusBOC: { /* 'DPT_StatusBOC' */
+                    return "V16U8B16Boiler";
+                }
+                case KnxDatapointType.DPT_StatusBUC: { /* 'DPT_StatusBUC' */
+                    return "U8B8StatusBurnerController";
+                }
+                case KnxDatapointType.DPT_StatusCC: { /* 'DPT_StatusCC' */
+                    return "V16U8B16Chiller";
+                }
+                case KnxDatapointType.DPT_StatusCPM: { /* 'DPT_StatusCPM' */
+                    return "V16B8ColdWaterProducerManagerStatus";
+                }
+                case KnxDatapointType.DPT_StatusDHWC: { /* 'DPT_StatusDHWC' */
+                    return "B16";
+                }
+                case KnxDatapointType.DPT_StatusGen: { /* 'DPT_StatusGen' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_StatusHPM: { /* 'DPT_StatusHPM' */
+                    return "V16B8HeatProducerManagerStatus";
+                }
+                case KnxDatapointType.DPT_StatusLightingActuator: { /* 'DPT_StatusLightingActuator' */
+                    return "U8B8StatusLightingActuator";
+                }
+                case KnxDatapointType.DPT_StatusRCC: { /* 'DPT_StatusRCC' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_StatusRHC: { /* 'DPT_StatusRHC' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_StatusRHCC: { /* 'DPT_StatusRHCC' */
+                    return "B16";
+                }
+                case KnxDatapointType.DPT_StatusRoomSetp: { /* 'DPT_StatusRoomSetp' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_StatusSAB: { /* 'DPT_StatusSAB' */
+                    return "U8U8B16";
+                }
+                case KnxDatapointType.DPT_StatusSDHWC: { /* 'DPT_StatusSDHWC' */
+                    return "B8";
+                }
+                case KnxDatapointType.DPT_StatusWTC: { /* 'DPT_StatusWTC' */
+                    return "V16B8WaterTemperatureControllerStatus";
+                }
+                case KnxDatapointType.DPT_Status_Mode3: { /* 'DPT_Status_Mode3' */
+                    return "B5N3";
+                }
+                case KnxDatapointType.DPT_Step: { /* 'DPT_Step' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_Step_Control: { /* 'DPT_Step_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_String_8859_1: { /* 'DPT_String_8859_1' */
+                    return "A112_8859_1";
+                }
+                case KnxDatapointType.DPT_String_ASCII: { /* 'DPT_String_ASCII' */
+                    return "A112_ASCII";
+                }
+                case KnxDatapointType.DPT_SunIntensity_Z: { /* 'DPT_SunIntensity_Z' */
+                    return "U16Z8SunIntensity";
+                }
+                case KnxDatapointType.DPT_Switch: { /* 'DPT_Switch' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_SwitchOnMode: { /* 'DPT_SwitchOnMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_SwitchPBModel: { /* 'DPT_SwitchPBModel' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Switch_Control: { /* 'DPT_Switch_Control' */
+                    return "B2";
+                }
+                case KnxDatapointType.DPT_Tariff: { /* 'DPT_Tariff' */
+                    return "U8";
+                }
+                case KnxDatapointType.DPT_TariffNext: { /* 'DPT_TariffNext' */
+                    return "U16U8TariffNext";
+                }
+                case KnxDatapointType.DPT_Tariff_ActiveEnergy: { /* 'DPT_Tariff_ActiveEnergy' */
+                    return "V32U8B8";
+                }
+                case KnxDatapointType.DPT_TempDHWSetpSet4: { /* 'DPT_TempDHWSetpSet4' */
+                    return "V16V16V16V16DhwtTemperature";
+                }
+                case KnxDatapointType.DPT_TempFlowWaterDemAbs: { /* 'DPT_TempFlowWaterDemAbs' */
+                    return "V16B16";
+                }
+                case KnxDatapointType.DPT_TempHVACAbsNext: { /* 'DPT_TempHVACAbsNext' */
+                    return "U16V16";
+                }
+                case KnxDatapointType.DPT_TempHVACAbs_Z: { /* 'DPT_TempHVACAbs_Z' */
+                    return "V16Z8RelSignedValue";
+                }
+                case KnxDatapointType.DPT_TempHVACRel_Z: { /* 'DPT_TempHVACRel_Z' */
+                    return "V16Z8RelSignedValue";
+                }
+                case KnxDatapointType.DPT_TempRoomDemAbs: { /* 'DPT_TempRoomDemAbs' */
+                    return "V16B8RoomTemperatureDemand";
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSet3: { /* 'DPT_TempRoomSetpSet3' */
+                    return "V16V16V16RoomTemperature";
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSet4: { /* 'DPT_TempRoomSetpSet4' */
+                    return "V16V16V16V16RoomTemperature";
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetF163: { /* 'DPT_TempRoomSetpSetF163' */
+                    return "F16F16F16";
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShift3: { /* 'DPT_TempRoomSetpSetShift3' */
+                    return "V16V16V16RoomTemperatureShift";
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShift4: { /* 'DPT_TempRoomSetpSetShift4' */
+                    return "V16V16V16V16RoomTemperatureShift";
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShiftF163: { /* 'DPT_TempRoomSetpSetShiftF163' */
+                    return "F16F16F16";
+                }
+                case KnxDatapointType.DPT_TempSupply_AirSetpSet: { /* 'DPT_TempSupply_AirSetpSet' */
+                    return "V16V16N8N8";
+                }
+                case KnxDatapointType.DPT_TimeOfDay: { /* 'DPT_TimeOfDay' */
+                    return "N3N5r2N6r2N6";
+                }
+                case KnxDatapointType.DPT_TimePeriod100MSec: { /* 'DPT_TimePeriod100MSec' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_TimePeriod100Msec_Z: { /* 'DPT_TimePeriod100Msec_Z' */
+                    return "U16Z8TimePeriod";
+                }
+                case KnxDatapointType.DPT_TimePeriod10MSec: { /* 'DPT_TimePeriod10MSec' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_TimePeriod10Msec_Z: { /* 'DPT_TimePeriod10Msec_Z' */
+                    return "U16Z8TimePeriod";
+                }
+                case KnxDatapointType.DPT_TimePeriodHrs: { /* 'DPT_TimePeriodHrs' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_TimePeriodHrs_Z: { /* 'DPT_TimePeriodHrs_Z' */
+                    return "U16Z8TimePeriod";
+                }
+                case KnxDatapointType.DPT_TimePeriodMin: { /* 'DPT_TimePeriodMin' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_TimePeriodMin_Z: { /* 'DPT_TimePeriodMin_Z' */
+                    return "U16Z8TimePeriod";
+                }
+                case KnxDatapointType.DPT_TimePeriodMsec: { /* 'DPT_TimePeriodMsec' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_TimePeriodMsec_Z: { /* 'DPT_TimePeriodMsec_Z' */
+                    return "U16Z8TimePeriod";
+                }
+                case KnxDatapointType.DPT_TimePeriodSec: { /* 'DPT_TimePeriodSec' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_TimePeriodSec_Z: { /* 'DPT_TimePeriodSec_Z' */
+                    return "U16Z8TimePeriod";
+                }
+                case KnxDatapointType.DPT_Time_Delay: { /* 'DPT_Time_Delay' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_Trigger: { /* 'DPT_Trigger' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_UCountValue16_Z: { /* 'DPT_UCountValue16_Z' */
+                    return "U16Z8Counter";
+                }
+                case KnxDatapointType.DPT_UCountValue8_Z: { /* 'DPT_UCountValue8_Z' */
+                    return "U8Z8Counter";
+                }
+                case KnxDatapointType.DPT_UElCurrentmA: { /* 'DPT_UElCurrentmA' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_UElCurrentyA_Z: { /* 'DPT_UElCurrentyA_Z' */
+                    return "U16Z8ElectricCurrent";
+                }
+                case KnxDatapointType.DPT_UFlowRateLiter_h_Z: { /* 'DPT_UFlowRateLiter_h_Z' */
+                    return "U16Z8FlowRate";
+                }
+                case KnxDatapointType.DPT_UTF_8: { /* 'DPT_UTF_8' */
+                    return "An_UTF_8";
+                }
+                case KnxDatapointType.DPT_UpDown: { /* 'DPT_UpDown' */
+                    return "B1";
+                }
+                case KnxDatapointType.DPT_UpDown_Action: { /* 'DPT_UpDown_Action' */
+                    return "N2";
+                }
+                case KnxDatapointType.DPT_ValueDemBOC: { /* 'DPT_ValueDemBOC' */
+                    return "U8B8BoilerControllerDemandSignal";
+                }
+                case KnxDatapointType.DPT_Value_1_Count: { /* 'DPT_Value_1_Count' */
+                    return "V8";
+                }
+                case KnxDatapointType.DPT_Value_1_Ucount: { /* 'DPT_Value_1_Ucount' */
+                    return "U8";
+                }
+                case KnxDatapointType.DPT_Value_2_Count: { /* 'DPT_Value_2_Count' */
+                    return "V16";
+                }
+                case KnxDatapointType.DPT_Value_2_Ucount: { /* 'DPT_Value_2_Ucount' */
+                    return "U16";
+                }
+                case KnxDatapointType.DPT_Value_4_Count: { /* 'DPT_Value_4_Count' */
+                    return "V32";
+                }
+                case KnxDatapointType.DPT_Value_4_Ucount: { /* 'DPT_Value_4_Ucount' */
+                    return "U32";
+                }
+                case KnxDatapointType.DPT_Value_Absolute_Temperature: { /* 'DPT_Value_Absolute_Temperature' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Acceleration: { /* 'DPT_Value_Acceleration' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Acceleration_Angular: { /* 'DPT_Value_Acceleration_Angular' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Activation_Energy: { /* 'DPT_Value_Activation_Energy' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Activity: { /* 'DPT_Value_Activity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_AirQuality: { /* 'DPT_Value_AirQuality' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Amplitude: { /* 'DPT_Value_Amplitude' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_AngleDeg: { /* 'DPT_Value_AngleDeg' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_AngleRad: { /* 'DPT_Value_AngleRad' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Angular_Frequency: { /* 'DPT_Value_Angular_Frequency' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Angular_Momentum: { /* 'DPT_Value_Angular_Momentum' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Angular_Velocity: { /* 'DPT_Value_Angular_Velocity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Area: { /* 'DPT_Value_Area' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Capacitance: { /* 'DPT_Value_Capacitance' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Charge_DensitySurface: { /* 'DPT_Value_Charge_DensitySurface' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Charge_DensityVolume: { /* 'DPT_Value_Charge_DensityVolume' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Common_Temperature: { /* 'DPT_Value_Common_Temperature' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Compressibility: { /* 'DPT_Value_Compressibility' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Conductance: { /* 'DPT_Value_Conductance' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Curr: { /* 'DPT_Value_Curr' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Density: { /* 'DPT_Value_Density' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_Charge: { /* 'DPT_Value_Electric_Charge' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_Current: { /* 'DPT_Value_Electric_Current' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_CurrentDensity: { /* 'DPT_Value_Electric_CurrentDensity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_DipoleMoment: { /* 'DPT_Value_Electric_DipoleMoment' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_Displacement: { /* 'DPT_Value_Electric_Displacement' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_FieldStrength: { /* 'DPT_Value_Electric_FieldStrength' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_Flux: { /* 'DPT_Value_Electric_Flux' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_FluxDensity: { /* 'DPT_Value_Electric_FluxDensity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_Polarization: { /* 'DPT_Value_Electric_Polarization' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_Potential: { /* 'DPT_Value_Electric_Potential' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electric_PotentialDifference: { /* 'DPT_Value_Electric_PotentialDifference' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electrical_Conductivity: { /* 'DPT_Value_Electrical_Conductivity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_ElectromagneticMoment: { /* 'DPT_Value_ElectromagneticMoment' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Electromotive_Force: { /* 'DPT_Value_Electromotive_Force' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Energy: { /* 'DPT_Value_Energy' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Force: { /* 'DPT_Value_Force' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Frequency: { /* 'DPT_Value_Frequency' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Heat_Capacity: { /* 'DPT_Value_Heat_Capacity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Heat_FlowRate: { /* 'DPT_Value_Heat_FlowRate' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Heat_Quantity: { /* 'DPT_Value_Heat_Quantity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Humidity: { /* 'DPT_Value_Humidity' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Impedance: { /* 'DPT_Value_Impedance' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Length: { /* 'DPT_Value_Length' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Light_Quantity: { /* 'DPT_Value_Light_Quantity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Luminance: { /* 'DPT_Value_Luminance' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Luminous_Flux: { /* 'DPT_Value_Luminous_Flux' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Luminous_Intensity: { /* 'DPT_Value_Luminous_Intensity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Lux: { /* 'DPT_Value_Lux' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_FieldStrength: { /* 'DPT_Value_Magnetic_FieldStrength' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Flux: { /* 'DPT_Value_Magnetic_Flux' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_FluxDensity: { /* 'DPT_Value_Magnetic_FluxDensity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Moment: { /* 'DPT_Value_Magnetic_Moment' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Polarization: { /* 'DPT_Value_Magnetic_Polarization' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Magnetization: { /* 'DPT_Value_Magnetization' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_MagnetomotiveForce: { /* 'DPT_Value_MagnetomotiveForce' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Mass: { /* 'DPT_Value_Mass' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_MassFlux: { /* 'DPT_Value_MassFlux' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Mol: { /* 'DPT_Value_Mol' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Momentum: { /* 'DPT_Value_Momentum' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Phase_AngleDeg: { /* 'DPT_Value_Phase_AngleDeg' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Phase_AngleRad: { /* 'DPT_Value_Phase_AngleRad' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Power: { /* 'DPT_Value_Power' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Power_Factor: { /* 'DPT_Value_Power_Factor' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Pres: { /* 'DPT_Value_Pres' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Pressure: { /* 'DPT_Value_Pressure' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Reactance: { /* 'DPT_Value_Reactance' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Resistance: { /* 'DPT_Value_Resistance' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Resistivity: { /* 'DPT_Value_Resistivity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_SelfInductance: { /* 'DPT_Value_SelfInductance' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_SolidAngle: { /* 'DPT_Value_SolidAngle' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Sound_Intensity: { /* 'DPT_Value_Sound_Intensity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Speed: { /* 'DPT_Value_Speed' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Stress: { /* 'DPT_Value_Stress' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Surface_Tension: { /* 'DPT_Value_Surface_Tension' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Temp: { /* 'DPT_Value_Temp' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Temp_F: { /* 'DPT_Value_Temp_F' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Tempa: { /* 'DPT_Value_Tempa' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Tempd: { /* 'DPT_Value_Tempd' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_TemperatureDifference: { /* 'DPT_Value_TemperatureDifference' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Thermal_Capacity: { /* 'DPT_Value_Thermal_Capacity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Thermal_Conductivity: { /* 'DPT_Value_Thermal_Conductivity' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_ThermoelectricPower: { /* 'DPT_Value_ThermoelectricPower' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Time: { /* 'DPT_Value_Time' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Time1: { /* 'DPT_Value_Time1' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Time2: { /* 'DPT_Value_Time2' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Torque: { /* 'DPT_Value_Torque' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Volt: { /* 'DPT_Value_Volt' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Volume: { /* 'DPT_Value_Volume' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Volume_Flow: { /* 'DPT_Value_Volume_Flow' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Volume_Flux: { /* 'DPT_Value_Volume_Flux' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Weight: { /* 'DPT_Value_Weight' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Work: { /* 'DPT_Value_Work' */
+                    return "F32";
+                }
+                case KnxDatapointType.DPT_Value_Wsp: { /* 'DPT_Value_Wsp' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_Value_Wsp_kmh: { /* 'DPT_Value_Wsp_kmh' */
+                    return "F16";
+                }
+                case KnxDatapointType.DPT_ValveMode: { /* 'DPT_ValveMode' */
+                    return "N8";
+                }
+                case KnxDatapointType.DPT_VarString_8859_1: { /* 'DPT_VarString_8859_1' */
+                    return "An_8859_1";
+                }
+                case KnxDatapointType.DPT_Version: { /* 'DPT_Version' */
+                    return "U5U5U6";
+                }
+                case KnxDatapointType.DPT_VolumeLiter_Z: { /* 'DPT_VolumeLiter_Z' */
+                    return "V32Z8VolumeLiter";
+                }
+                case KnxDatapointType.DPT_WindSpeed_Z_DPT_WindSpeed: { /* 'DPT_WindSpeed_Z_DPT_WindSpeed' */
+                    return "U16Z8WindSpeed";
+                }
+                case KnxDatapointType.DPT_Window_Door: { /* 'DPT_Window_Door' */
+                    return "B1";
+                }
+                default: {
+                    return "";
+                }
+            }
+        }
+
+        public static ushort MainNumber(this KnxDatapointType value)
+        {
+            switch (value)
+            {
+                case KnxDatapointType.DPT_ADAType: { /* 'DPT_ADAType' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Access_Data: { /* 'DPT_Access_Data' */
+                    return 15;
+                }
+                case KnxDatapointType.DPT_Ack: { /* 'DPT_Ack' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_ActPosDemAbs: { /* 'DPT_ActPosDemAbs' */
+                    return 207;
+                }
+                case KnxDatapointType.DPT_ActiveEnergy: { /* 'DPT_ActiveEnergy' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_ActiveEnergy_V64: { /* 'DPT_ActiveEnergy_V64' */
+                    return 29;
+                }
+                case KnxDatapointType.DPT_ActiveEnergy_kWh: { /* 'DPT_ActiveEnergy_kWh' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_ActuatorConnectType: { /* 'DPT_ActuatorConnectType' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_AddInfoTypes: { /* 'DPT_AddInfoTypes' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Alarm: { /* 'DPT_Alarm' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_AlarmClassType: { /* 'DPT_AlarmClassType' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_AlarmInfo: { /* 'DPT_AlarmInfo' */
+                    return 219;
+                }
+                case KnxDatapointType.DPT_Alarm_Control: { /* 'DPT_Alarm_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Alarm_Reaction: { /* 'DPT_Alarm_Reaction' */
+                    return 23;
+                }
+                case KnxDatapointType.DPT_Angle: { /* 'DPT_Angle' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_ApparantEnergy: { /* 'DPT_ApparantEnergy' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_ApparantEnergy_V64: { /* 'DPT_ApparantEnergy_V64' */
+                    return 29;
+                }
+                case KnxDatapointType.DPT_ApparantEnergy_kVAh: { /* 'DPT_ApparantEnergy_kVAh' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_ApplicationArea: { /* 'DPT_ApplicationArea' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_AtmPressureAbs_Z: { /* 'DPT_AtmPressureAbs_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_BackupMode: { /* 'DPT_BackupMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Beaufort_Wind_Force_Scale: { /* 'DPT_Beaufort_Wind_Force_Scale' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Behaviour_Bus_Power_Up_Down: { /* 'DPT_Behaviour_Bus_Power_Up_Down' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Behaviour_Lock_Unlock: { /* 'DPT_Behaviour_Lock_Unlock' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_BinaryValue: { /* 'DPT_BinaryValue' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_BinaryValue_Control: { /* 'DPT_BinaryValue_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_BinaryValue_Z: { /* 'DPT_BinaryValue_Z' */
+                    return 200;
+                }
+                case KnxDatapointType.DPT_BlindsControlMode: { /* 'DPT_BlindsControlMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_BlinkingMode: { /* 'DPT_BlinkingMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Bool: { /* 'DPT_Bool' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Bool_Control: { /* 'DPT_Bool_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Brightness: { /* 'DPT_Brightness' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_BuildingMode: { /* 'DPT_BuildingMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_BuildingModeNext: { /* 'DPT_BuildingModeNext' */
+                    return 206;
+                }
+                case KnxDatapointType.DPT_BuildingMode_Z: { /* 'DPT_BuildingMode_Z' */
+                    return 201;
+                }
+                case KnxDatapointType.DPT_BurnerType: { /* 'DPT_BurnerType' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_ChangeoverMode: { /* 'DPT_ChangeoverMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Channel_Activation_16: { /* 'DPT_Channel_Activation_16' */
+                    return 22;
+                }
+                case KnxDatapointType.DPT_Channel_Activation_24: { /* 'DPT_Channel_Activation_24' */
+                    return 30;
+                }
+                case KnxDatapointType.DPT_Channel_Activation_8: { /* 'DPT_Channel_Activation_8' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_Char_8859_1: { /* 'DPT_Char_8859_1' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_Char_ASCII: { /* 'DPT_Char_ASCII' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_Colour_RGB: { /* 'DPT_Colour_RGB' */
+                    return 232;
+                }
+                case KnxDatapointType.DPT_CombinedInfoOnOff: { /* 'DPT_CombinedInfoOnOff' */
+                    return 27;
+                }
+                case KnxDatapointType.DPT_CombinedPosition: { /* 'DPT_CombinedPosition' */
+                    return 240;
+                }
+                case KnxDatapointType.DPT_CommMode: { /* 'DPT_CommMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Control_Blinds: { /* 'DPT_Control_Blinds' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_Control_Dimming: { /* 'DPT_Control_Dimming' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_DALI_Control_Gear_Diagnostic: { /* 'DPT_DALI_Control_Gear_Diagnostic' */
+                    return 237;
+                }
+                case KnxDatapointType.DPT_DALI_Diagnostics: { /* 'DPT_DALI_Diagnostics' */
+                    return 238;
+                }
+                case KnxDatapointType.DPT_DALI_Fade_Time: { /* 'DPT_DALI_Fade_Time' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_DHWMode: { /* 'DPT_DHWMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_DHWModeNext: { /* 'DPT_DHWModeNext' */
+                    return 206;
+                }
+                case KnxDatapointType.DPT_DHWMode_Z: { /* 'DPT_DHWMode_Z' */
+                    return 201;
+                }
+                case KnxDatapointType.DPT_DamperMode: { /* 'DPT_DamperMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Date: { /* 'DPT_Date' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_DateTime: { /* 'DPT_DateTime' */
+                    return 19;
+                }
+                case KnxDatapointType.DPT_DecimalFactor: { /* 'DPT_DecimalFactor' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_DeltaTime100MSec: { /* 'DPT_DeltaTime100MSec' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_DeltaTime100Msec_Z: { /* 'DPT_DeltaTime100Msec_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_DeltaTime10MSec: { /* 'DPT_DeltaTime10MSec' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_DeltaTime10Msec_Z: { /* 'DPT_DeltaTime10Msec_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_DeltaTimeHrs: { /* 'DPT_DeltaTimeHrs' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_DeltaTimeHrs_Z: { /* 'DPT_DeltaTimeHrs_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_DeltaTimeMin: { /* 'DPT_DeltaTimeMin' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_DeltaTimeMin_Z: { /* 'DPT_DeltaTimeMin_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_DeltaTimeMsec: { /* 'DPT_DeltaTimeMsec' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_DeltaTimeMsec_Z: { /* 'DPT_DeltaTimeMsec_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_DeltaTimeSec: { /* 'DPT_DeltaTimeSec' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_DeltaTimeSec_Z: { /* 'DPT_DeltaTimeSec_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_Device_Control: { /* 'DPT_Device_Control' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_DimSendStyle: { /* 'DPT_DimSendStyle' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_DimmPBModel: { /* 'DPT_DimmPBModel' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Direction1_Control: { /* 'DPT_Direction1_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Direction2_Control: { /* 'DPT_Direction2_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_DoubleNibble: { /* 'DPT_DoubleNibble' */
+                    return 25;
+                }
+                case KnxDatapointType.DPT_EnablH_Cstage_Z_DPT_EnablH_CStage: { /* 'DPT_EnablH_Cstage_Z_DPT_EnablH_CStage' */
+                    return 201;
+                }
+                case KnxDatapointType.DPT_Enable: { /* 'DPT_Enable' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Enable_Control: { /* 'DPT_Enable_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_EnergyDemAir: { /* 'DPT_EnergyDemAir' */
+                    return 223;
+                }
+                case KnxDatapointType.DPT_EnergyDemWater: { /* 'DPT_EnergyDemWater' */
+                    return 211;
+                }
+                case KnxDatapointType.DPT_ErrorClass_HVAC: { /* 'DPT_ErrorClass_HVAC' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_ErrorClass_System: { /* 'DPT_ErrorClass_System' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_FanMode: { /* 'DPT_FanMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_FlaggedScaling: { /* 'DPT_FlaggedScaling' */
+                    return 239;
+                }
+                case KnxDatapointType.DPT_FlowRate_m3h: { /* 'DPT_FlowRate_m3h' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_FlowRate_m3h_Z: { /* 'DPT_FlowRate_m3h_Z' */
+                    return 218;
+                }
+                case KnxDatapointType.DPT_ForceSign: { /* 'DPT_ForceSign' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_ForceSignCool: { /* 'DPT_ForceSignCool' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_FuelType: { /* 'DPT_FuelType' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_FuelTypeSet: { /* 'DPT_FuelTypeSet' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_HVACAirFlowAbs_Z: { /* 'DPT_HVACAirFlowAbs_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_HVACAirFlowRel_Z: { /* 'DPT_HVACAirFlowRel_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_HVACAirQual_Z: { /* 'DPT_HVACAirQual_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_HVACContrMode: { /* 'DPT_HVACContrMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_HVACContrMode_Z: { /* 'DPT_HVACContrMode_Z' */
+                    return 201;
+                }
+                case KnxDatapointType.DPT_HVACEmergMode: { /* 'DPT_HVACEmergMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_HVACEmergMode_Z: { /* 'DPT_HVACEmergMode_Z' */
+                    return 201;
+                }
+                case KnxDatapointType.DPT_HVACMode: { /* 'DPT_HVACMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_HVACModeNext: { /* 'DPT_HVACModeNext' */
+                    return 206;
+                }
+                case KnxDatapointType.DPT_HVACMode_Z: { /* 'DPT_HVACMode_Z' */
+                    return 201;
+                }
+                case KnxDatapointType.DPT_HVAC_PB_Action: { /* 'DPT_HVAC_PB_Action' */
+                    return 23;
+                }
+                case KnxDatapointType.DPT_Heat_Cool: { /* 'DPT_Heat_Cool' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Heat_Cool_Z: { /* 'DPT_Heat_Cool_Z' */
+                    return 200;
+                }
+                case KnxDatapointType.DPT_HeaterMode: { /* 'DPT_HeaterMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_InputSource: { /* 'DPT_InputSource' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Invert: { /* 'DPT_Invert' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Invert_Control: { /* 'DPT_Invert_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_KelvinPerPercent: { /* 'DPT_KelvinPerPercent' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_LanguageCodeAlpha2_ASCII: { /* 'DPT_LanguageCodeAlpha2_ASCII' */
+                    return 234;
+                }
+                case KnxDatapointType.DPT_Length_mm: { /* 'DPT_Length_mm' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_LightActuatorErrorInfo: { /* 'DPT_LightActuatorErrorInfo' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_LightApplicationMode: { /* 'DPT_LightApplicationMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_LightControlMode: { /* 'DPT_LightControlMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_LoadPriority: { /* 'DPT_LoadPriority' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_LoadTypeDetected: { /* 'DPT_LoadTypeDetected' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_LoadTypeSet: { /* 'DPT_LoadTypeSet' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Locale_ASCII: { /* 'DPT_Locale_ASCII' */
+                    return 231;
+                }
+                case KnxDatapointType.DPT_LockSign: { /* 'DPT_LockSign' */
+                    return 207;
+                }
+                case KnxDatapointType.DPT_LogicalFunction: { /* 'DPT_LogicalFunction' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_LongDeltaTimeSec: { /* 'DPT_LongDeltaTimeSec' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_MBus_Address: { /* 'DPT_MBus_Address' */
+                    return 230;
+                }
+                case KnxDatapointType.DPT_MasterSlaveMode: { /* 'DPT_MasterSlaveMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Media: { /* 'DPT_Media' */
+                    return 22;
+                }
+                case KnxDatapointType.DPT_MeteringValue: { /* 'DPT_MeteringValue' */
+                    return 229;
+                }
+                case KnxDatapointType.DPT_OccMode: { /* 'DPT_OccMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_OccModeNext: { /* 'DPT_OccModeNext' */
+                    return 206;
+                }
+                case KnxDatapointType.DPT_OccMode_Z: { /* 'DPT_OccMode_Z' */
+                    return 201;
+                }
+                case KnxDatapointType.DPT_Occupancy: { /* 'DPT_Occupancy' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_OnOff_Action: { /* 'DPT_OnOff_Action' */
+                    return 23;
+                }
+                case KnxDatapointType.DPT_OpenClose: { /* 'DPT_OpenClose' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_PBAction: { /* 'DPT_PBAction' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_PB_Action_HVAC_Extended: { /* 'DPT_PB_Action_HVAC_Extended' */
+                    return 31;
+                }
+                case KnxDatapointType.DPT_PSUMode: { /* 'DPT_PSUMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_PercentU16_Z: { /* 'DPT_PercentU16_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_Percent_U8: { /* 'DPT_Percent_U8' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_Percent_V16: { /* 'DPT_Percent_V16' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_Percent_V16_Z: { /* 'DPT_Percent_V16_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_Percent_V8: { /* 'DPT_Percent_V8' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_Power: { /* 'DPT_Power' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_PowerDensity: { /* 'DPT_PowerDensity' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_PowerFlowWaterDemCPM: { /* 'DPT_PowerFlowWaterDemCPM' */
+                    return 214;
+                }
+                case KnxDatapointType.DPT_PowerFlowWaterDemHPM: { /* 'DPT_PowerFlowWaterDemHPM' */
+                    return 214;
+                }
+                case KnxDatapointType.DPT_PowerKW_Z: { /* 'DPT_PowerKW_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_Prioritised_Mode_Control: { /* 'DPT_Prioritised_Mode_Control' */
+                    return 236;
+                }
+                case KnxDatapointType.DPT_Priority: { /* 'DPT_Priority' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_PropDataType: { /* 'DPT_PropDataType' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_RF_FilterInfo: { /* 'DPT_RF_FilterInfo' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_RF_FilterSelect: { /* 'DPT_RF_FilterSelect' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_RF_ModeInfo: { /* 'DPT_RF_ModeInfo' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_RF_ModeSelect: { /* 'DPT_RF_ModeSelect' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Rain_Amount: { /* 'DPT_Rain_Amount' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Ramp: { /* 'DPT_Ramp' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Ramp_Control: { /* 'DPT_Ramp_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy: { /* 'DPT_ReactiveEnergy' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy_V64: { /* 'DPT_ReactiveEnergy_V64' */
+                    return 29;
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy_kVARh: { /* 'DPT_ReactiveEnergy_kVARh' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_RegionCodeAlpha2_ASCII: { /* 'DPT_RegionCodeAlpha2_ASCII' */
+                    return 234;
+                }
+                case KnxDatapointType.DPT_RelSignedValue_Z: { /* 'DPT_RelSignedValue_Z' */
+                    return 204;
+                }
+                case KnxDatapointType.DPT_RelValue_Z: { /* 'DPT_RelValue_Z' */
+                    return 202;
+                }
+                case KnxDatapointType.DPT_Reset: { /* 'DPT_Reset' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Rotation_Angle: { /* 'DPT_Rotation_Angle' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_SABBehaviour_Lock_Unlock: { /* 'DPT_SABBehaviour_Lock_Unlock' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_SABExceptBehaviour: { /* 'DPT_SABExceptBehaviour' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_SCLOMode: { /* 'DPT_SCLOMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_SSSBMode: { /* 'DPT_SSSBMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Scaling: { /* 'DPT_Scaling' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_ScalingSpeed: { /* 'DPT_ScalingSpeed' */
+                    return 225;
+                }
+                case KnxDatapointType.DPT_Scaling_Step_Time: { /* 'DPT_Scaling_Step_Time' */
+                    return 225;
+                }
+                case KnxDatapointType.DPT_SceneConfig: { /* 'DPT_SceneConfig' */
+                    return 238;
+                }
+                case KnxDatapointType.DPT_SceneControl: { /* 'DPT_SceneControl' */
+                    return 18;
+                }
+                case KnxDatapointType.DPT_SceneInfo: { /* 'DPT_SceneInfo' */
+                    return 26;
+                }
+                case KnxDatapointType.DPT_SceneNumber: { /* 'DPT_SceneNumber' */
+                    return 17;
+                }
+                case KnxDatapointType.DPT_Scene_AB: { /* 'DPT_Scene_AB' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_SensorSelect: { /* 'DPT_SensorSelect' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_SerNum: { /* 'DPT_SerNum' */
+                    return 221;
+                }
+                case KnxDatapointType.DPT_ShutterBlinds_Mode: { /* 'DPT_ShutterBlinds_Mode' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_SpecHeatProd: { /* 'DPT_SpecHeatProd' */
+                    return 216;
+                }
+                case KnxDatapointType.DPT_Start: { /* 'DPT_Start' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_StartSynchronization: { /* 'DPT_StartSynchronization' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Start_Control: { /* 'DPT_Start_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_State: { /* 'DPT_State' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_State_Control: { /* 'DPT_State_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_StatusAHU: { /* 'DPT_StatusAHU' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_StatusAct: { /* 'DPT_StatusAct' */
+                    return 207;
+                }
+                case KnxDatapointType.DPT_StatusBOC: { /* 'DPT_StatusBOC' */
+                    return 215;
+                }
+                case KnxDatapointType.DPT_StatusBUC: { /* 'DPT_StatusBUC' */
+                    return 207;
+                }
+                case KnxDatapointType.DPT_StatusCC: { /* 'DPT_StatusCC' */
+                    return 215;
+                }
+                case KnxDatapointType.DPT_StatusCPM: { /* 'DPT_StatusCPM' */
+                    return 209;
+                }
+                case KnxDatapointType.DPT_StatusDHWC: { /* 'DPT_StatusDHWC' */
+                    return 22;
+                }
+                case KnxDatapointType.DPT_StatusGen: { /* 'DPT_StatusGen' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_StatusHPM: { /* 'DPT_StatusHPM' */
+                    return 209;
+                }
+                case KnxDatapointType.DPT_StatusLightingActuator: { /* 'DPT_StatusLightingActuator' */
+                    return 207;
+                }
+                case KnxDatapointType.DPT_StatusRCC: { /* 'DPT_StatusRCC' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_StatusRHC: { /* 'DPT_StatusRHC' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_StatusRHCC: { /* 'DPT_StatusRHCC' */
+                    return 22;
+                }
+                case KnxDatapointType.DPT_StatusRoomSetp: { /* 'DPT_StatusRoomSetp' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_StatusSAB: { /* 'DPT_StatusSAB' */
+                    return 241;
+                }
+                case KnxDatapointType.DPT_StatusSDHWC: { /* 'DPT_StatusSDHWC' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_StatusWTC: { /* 'DPT_StatusWTC' */
+                    return 209;
+                }
+                case KnxDatapointType.DPT_Status_Mode3: { /* 'DPT_Status_Mode3' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_Step: { /* 'DPT_Step' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Step_Control: { /* 'DPT_Step_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_String_8859_1: { /* 'DPT_String_8859_1' */
+                    return 16;
+                }
+                case KnxDatapointType.DPT_String_ASCII: { /* 'DPT_String_ASCII' */
+                    return 16;
+                }
+                case KnxDatapointType.DPT_SunIntensity_Z: { /* 'DPT_SunIntensity_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_Switch: { /* 'DPT_Switch' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_SwitchOnMode: { /* 'DPT_SwitchOnMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_SwitchPBModel: { /* 'DPT_SwitchPBModel' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Switch_Control: { /* 'DPT_Switch_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Tariff: { /* 'DPT_Tariff' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_TariffNext: { /* 'DPT_TariffNext' */
+                    return 225;
+                }
+                case KnxDatapointType.DPT_Tariff_ActiveEnergy: { /* 'DPT_Tariff_ActiveEnergy' */
+                    return 235;
+                }
+                case KnxDatapointType.DPT_TempDHWSetpSet4: { /* 'DPT_TempDHWSetpSet4' */
+                    return 213;
+                }
+                case KnxDatapointType.DPT_TempFlowWaterDemAbs: { /* 'DPT_TempFlowWaterDemAbs' */
+                    return 210;
+                }
+                case KnxDatapointType.DPT_TempHVACAbsNext: { /* 'DPT_TempHVACAbsNext' */
+                    return 220;
+                }
+                case KnxDatapointType.DPT_TempHVACAbs_Z: { /* 'DPT_TempHVACAbs_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_TempHVACRel_Z: { /* 'DPT_TempHVACRel_Z' */
+                    return 205;
+                }
+                case KnxDatapointType.DPT_TempRoomDemAbs: { /* 'DPT_TempRoomDemAbs' */
+                    return 209;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSet3: { /* 'DPT_TempRoomSetpSet3' */
+                    return 212;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSet4: { /* 'DPT_TempRoomSetpSet4' */
+                    return 213;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetF163: { /* 'DPT_TempRoomSetpSetF163' */
+                    return 222;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShift3: { /* 'DPT_TempRoomSetpSetShift3' */
+                    return 212;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShift4: { /* 'DPT_TempRoomSetpSetShift4' */
+                    return 213;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShiftF163: { /* 'DPT_TempRoomSetpSetShiftF163' */
+                    return 222;
+                }
+                case KnxDatapointType.DPT_TempSupply_AirSetpSet: { /* 'DPT_TempSupply_AirSetpSet' */
+                    return 224;
+                }
+                case KnxDatapointType.DPT_TimeOfDay: { /* 'DPT_TimeOfDay' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_TimePeriod100MSec: { /* 'DPT_TimePeriod100MSec' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_TimePeriod100Msec_Z: { /* 'DPT_TimePeriod100Msec_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_TimePeriod10MSec: { /* 'DPT_TimePeriod10MSec' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_TimePeriod10Msec_Z: { /* 'DPT_TimePeriod10Msec_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_TimePeriodHrs: { /* 'DPT_TimePeriodHrs' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_TimePeriodHrs_Z: { /* 'DPT_TimePeriodHrs_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_TimePeriodMin: { /* 'DPT_TimePeriodMin' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_TimePeriodMin_Z: { /* 'DPT_TimePeriodMin_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_TimePeriodMsec: { /* 'DPT_TimePeriodMsec' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_TimePeriodMsec_Z: { /* 'DPT_TimePeriodMsec_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_TimePeriodSec: { /* 'DPT_TimePeriodSec' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_TimePeriodSec_Z: { /* 'DPT_TimePeriodSec_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_Time_Delay: { /* 'DPT_Time_Delay' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Trigger: { /* 'DPT_Trigger' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_UCountValue16_Z: { /* 'DPT_UCountValue16_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_UCountValue8_Z: { /* 'DPT_UCountValue8_Z' */
+                    return 202;
+                }
+                case KnxDatapointType.DPT_UElCurrentmA: { /* 'DPT_UElCurrentmA' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_UElCurrentyA_Z: { /* 'DPT_UElCurrentyA_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_UFlowRateLiter_h_Z: { /* 'DPT_UFlowRateLiter_h_Z' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_UTF_8: { /* 'DPT_UTF_8' */
+                    return 28;
+                }
+                case KnxDatapointType.DPT_UpDown: { /* 'DPT_UpDown' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_UpDown_Action: { /* 'DPT_UpDown_Action' */
+                    return 23;
+                }
+                case KnxDatapointType.DPT_ValueDemBOC: { /* 'DPT_ValueDemBOC' */
+                    return 207;
+                }
+                case KnxDatapointType.DPT_Value_1_Count: { /* 'DPT_Value_1_Count' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_Value_1_Ucount: { /* 'DPT_Value_1_Ucount' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_Value_2_Count: { /* 'DPT_Value_2_Count' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_Value_2_Ucount: { /* 'DPT_Value_2_Ucount' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_Value_4_Count: { /* 'DPT_Value_4_Count' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_Value_4_Ucount: { /* 'DPT_Value_4_Ucount' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_Value_Absolute_Temperature: { /* 'DPT_Value_Absolute_Temperature' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Acceleration: { /* 'DPT_Value_Acceleration' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Acceleration_Angular: { /* 'DPT_Value_Acceleration_Angular' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Activation_Energy: { /* 'DPT_Value_Activation_Energy' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Activity: { /* 'DPT_Value_Activity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_AirQuality: { /* 'DPT_Value_AirQuality' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Amplitude: { /* 'DPT_Value_Amplitude' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_AngleDeg: { /* 'DPT_Value_AngleDeg' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_AngleRad: { /* 'DPT_Value_AngleRad' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Angular_Frequency: { /* 'DPT_Value_Angular_Frequency' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Angular_Momentum: { /* 'DPT_Value_Angular_Momentum' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Angular_Velocity: { /* 'DPT_Value_Angular_Velocity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Area: { /* 'DPT_Value_Area' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Capacitance: { /* 'DPT_Value_Capacitance' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Charge_DensitySurface: { /* 'DPT_Value_Charge_DensitySurface' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Charge_DensityVolume: { /* 'DPT_Value_Charge_DensityVolume' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Common_Temperature: { /* 'DPT_Value_Common_Temperature' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Compressibility: { /* 'DPT_Value_Compressibility' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Conductance: { /* 'DPT_Value_Conductance' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Curr: { /* 'DPT_Value_Curr' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Density: { /* 'DPT_Value_Density' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Charge: { /* 'DPT_Value_Electric_Charge' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Current: { /* 'DPT_Value_Electric_Current' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_CurrentDensity: { /* 'DPT_Value_Electric_CurrentDensity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_DipoleMoment: { /* 'DPT_Value_Electric_DipoleMoment' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Displacement: { /* 'DPT_Value_Electric_Displacement' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_FieldStrength: { /* 'DPT_Value_Electric_FieldStrength' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Flux: { /* 'DPT_Value_Electric_Flux' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_FluxDensity: { /* 'DPT_Value_Electric_FluxDensity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Polarization: { /* 'DPT_Value_Electric_Polarization' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Potential: { /* 'DPT_Value_Electric_Potential' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electric_PotentialDifference: { /* 'DPT_Value_Electric_PotentialDifference' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electrical_Conductivity: { /* 'DPT_Value_Electrical_Conductivity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_ElectromagneticMoment: { /* 'DPT_Value_ElectromagneticMoment' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Electromotive_Force: { /* 'DPT_Value_Electromotive_Force' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Energy: { /* 'DPT_Value_Energy' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Force: { /* 'DPT_Value_Force' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Frequency: { /* 'DPT_Value_Frequency' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Heat_Capacity: { /* 'DPT_Value_Heat_Capacity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Heat_FlowRate: { /* 'DPT_Value_Heat_FlowRate' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Heat_Quantity: { /* 'DPT_Value_Heat_Quantity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Humidity: { /* 'DPT_Value_Humidity' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Impedance: { /* 'DPT_Value_Impedance' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Length: { /* 'DPT_Value_Length' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Light_Quantity: { /* 'DPT_Value_Light_Quantity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Luminance: { /* 'DPT_Value_Luminance' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Luminous_Flux: { /* 'DPT_Value_Luminous_Flux' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Luminous_Intensity: { /* 'DPT_Value_Luminous_Intensity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Lux: { /* 'DPT_Value_Lux' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_FieldStrength: { /* 'DPT_Value_Magnetic_FieldStrength' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Flux: { /* 'DPT_Value_Magnetic_Flux' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_FluxDensity: { /* 'DPT_Value_Magnetic_FluxDensity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Moment: { /* 'DPT_Value_Magnetic_Moment' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Polarization: { /* 'DPT_Value_Magnetic_Polarization' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Magnetization: { /* 'DPT_Value_Magnetization' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_MagnetomotiveForce: { /* 'DPT_Value_MagnetomotiveForce' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Mass: { /* 'DPT_Value_Mass' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_MassFlux: { /* 'DPT_Value_MassFlux' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Mol: { /* 'DPT_Value_Mol' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Momentum: { /* 'DPT_Value_Momentum' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Phase_AngleDeg: { /* 'DPT_Value_Phase_AngleDeg' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Phase_AngleRad: { /* 'DPT_Value_Phase_AngleRad' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Power: { /* 'DPT_Value_Power' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Power_Factor: { /* 'DPT_Value_Power_Factor' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Pres: { /* 'DPT_Value_Pres' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Pressure: { /* 'DPT_Value_Pressure' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Reactance: { /* 'DPT_Value_Reactance' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Resistance: { /* 'DPT_Value_Resistance' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Resistivity: { /* 'DPT_Value_Resistivity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_SelfInductance: { /* 'DPT_Value_SelfInductance' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_SolidAngle: { /* 'DPT_Value_SolidAngle' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Sound_Intensity: { /* 'DPT_Value_Sound_Intensity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Speed: { /* 'DPT_Value_Speed' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Stress: { /* 'DPT_Value_Stress' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Surface_Tension: { /* 'DPT_Value_Surface_Tension' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Temp: { /* 'DPT_Value_Temp' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Temp_F: { /* 'DPT_Value_Temp_F' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Tempa: { /* 'DPT_Value_Tempa' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Tempd: { /* 'DPT_Value_Tempd' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_TemperatureDifference: { /* 'DPT_Value_TemperatureDifference' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Thermal_Capacity: { /* 'DPT_Value_Thermal_Capacity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Thermal_Conductivity: { /* 'DPT_Value_Thermal_Conductivity' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_ThermoelectricPower: { /* 'DPT_Value_ThermoelectricPower' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Time: { /* 'DPT_Value_Time' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Time1: { /* 'DPT_Value_Time1' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Time2: { /* 'DPT_Value_Time2' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Torque: { /* 'DPT_Value_Torque' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Volt: { /* 'DPT_Value_Volt' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Volume: { /* 'DPT_Value_Volume' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Volume_Flow: { /* 'DPT_Value_Volume_Flow' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Volume_Flux: { /* 'DPT_Value_Volume_Flux' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Weight: { /* 'DPT_Value_Weight' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Work: { /* 'DPT_Value_Work' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Wsp: { /* 'DPT_Value_Wsp' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Wsp_kmh: { /* 'DPT_Value_Wsp_kmh' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_ValveMode: { /* 'DPT_ValveMode' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_VarString_8859_1: { /* 'DPT_VarString_8859_1' */
+                    return 24;
+                }
+                case KnxDatapointType.DPT_Version: { /* 'DPT_Version' */
+                    return 217;
+                }
+                case KnxDatapointType.DPT_VolumeLiter_Z: { /* 'DPT_VolumeLiter_Z' */
+                    return 218;
+                }
+                case KnxDatapointType.DPT_WindSpeed_Z_DPT_WindSpeed: { /* 'DPT_WindSpeed_Z_DPT_WindSpeed' */
+                    return 203;
+                }
+                case KnxDatapointType.DPT_Window_Door: { /* 'DPT_Window_Door' */
+                    return 1;
+                }
+                default: {
+                    return 0;
+                }
+            }
+        }
+
+        public static ushort SubNumber(this KnxDatapointType value)
+        {
+            switch (value)
+            {
+                case KnxDatapointType.DPT_ADAType: { /* 'DPT_ADAType' */
+                    return 120;
+                }
+                case KnxDatapointType.DPT_Access_Data: { /* 'DPT_Access_Data' */
+                    return 0;
+                }
+                case KnxDatapointType.DPT_Ack: { /* 'DPT_Ack' */
+                    return 16;
+                }
+                case KnxDatapointType.DPT_ActPosDemAbs: { /* 'DPT_ActPosDemAbs' */
+                    return 104;
+                }
+                case KnxDatapointType.DPT_ActiveEnergy: { /* 'DPT_ActiveEnergy' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_ActiveEnergy_V64: { /* 'DPT_ActiveEnergy_V64' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_ActiveEnergy_kWh: { /* 'DPT_ActiveEnergy_kWh' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_ActuatorConnectType: { /* 'DPT_ActuatorConnectType' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_AddInfoTypes: { /* 'DPT_AddInfoTypes' */
+                    return 1001;
+                }
+                case KnxDatapointType.DPT_Alarm: { /* 'DPT_Alarm' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_AlarmClassType: { /* 'DPT_AlarmClassType' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_AlarmInfo: { /* 'DPT_AlarmInfo' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Alarm_Control: { /* 'DPT_Alarm_Control' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_Alarm_Reaction: { /* 'DPT_Alarm_Reaction' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Angle: { /* 'DPT_Angle' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_ApparantEnergy: { /* 'DPT_ApparantEnergy' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_ApparantEnergy_V64: { /* 'DPT_ApparantEnergy_V64' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_ApparantEnergy_kVAh: { /* 'DPT_ApparantEnergy_kVAh' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_ApplicationArea: { /* 'DPT_ApplicationArea' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_AtmPressureAbs_Z: { /* 'DPT_AtmPressureAbs_Z' */
+                    return 15;
+                }
+                case KnxDatapointType.DPT_BackupMode: { /* 'DPT_BackupMode' */
+                    return 121;
+                }
+                case KnxDatapointType.DPT_Beaufort_Wind_Force_Scale: { /* 'DPT_Beaufort_Wind_Force_Scale' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Behaviour_Bus_Power_Up_Down: { /* 'DPT_Behaviour_Bus_Power_Up_Down' */
+                    return 601;
+                }
+                case KnxDatapointType.DPT_Behaviour_Lock_Unlock: { /* 'DPT_Behaviour_Lock_Unlock' */
+                    return 600;
+                }
+                case KnxDatapointType.DPT_BinaryValue: { /* 'DPT_BinaryValue' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_BinaryValue_Control: { /* 'DPT_BinaryValue_Control' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_BinaryValue_Z: { /* 'DPT_BinaryValue_Z' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_BlindsControlMode: { /* 'DPT_BlindsControlMode' */
+                    return 804;
+                }
+                case KnxDatapointType.DPT_BlinkingMode: { /* 'DPT_BlinkingMode' */
+                    return 603;
+                }
+                case KnxDatapointType.DPT_Bool: { /* 'DPT_Bool' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Bool_Control: { /* 'DPT_Bool_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Brightness: { /* 'DPT_Brightness' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_BuildingMode: { /* 'DPT_BuildingMode' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_BuildingModeNext: { /* 'DPT_BuildingModeNext' */
+                    return 105;
+                }
+                case KnxDatapointType.DPT_BuildingMode_Z: { /* 'DPT_BuildingMode_Z' */
+                    return 107;
+                }
+                case KnxDatapointType.DPT_BurnerType: { /* 'DPT_BurnerType' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_ChangeoverMode: { /* 'DPT_ChangeoverMode' */
+                    return 107;
+                }
+                case KnxDatapointType.DPT_Channel_Activation_16: { /* 'DPT_Channel_Activation_16' */
+                    return 1010;
+                }
+                case KnxDatapointType.DPT_Channel_Activation_24: { /* 'DPT_Channel_Activation_24' */
+                    return 1010;
+                }
+                case KnxDatapointType.DPT_Channel_Activation_8: { /* 'DPT_Channel_Activation_8' */
+                    return 1010;
+                }
+                case KnxDatapointType.DPT_Char_8859_1: { /* 'DPT_Char_8859_1' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Char_ASCII: { /* 'DPT_Char_ASCII' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Colour_RGB: { /* 'DPT_Colour_RGB' */
+                    return 600;
+                }
+                case KnxDatapointType.DPT_CombinedInfoOnOff: { /* 'DPT_CombinedInfoOnOff' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_CombinedPosition: { /* 'DPT_CombinedPosition' */
+                    return 800;
+                }
+                case KnxDatapointType.DPT_CommMode: { /* 'DPT_CommMode' */
+                    return 1000;
+                }
+                case KnxDatapointType.DPT_Control_Blinds: { /* 'DPT_Control_Blinds' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_Control_Dimming: { /* 'DPT_Control_Dimming' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_DALI_Control_Gear_Diagnostic: { /* 'DPT_DALI_Control_Gear_Diagnostic' */
+                    return 600;
+                }
+                case KnxDatapointType.DPT_DALI_Diagnostics: { /* 'DPT_DALI_Diagnostics' */
+                    return 600;
+                }
+                case KnxDatapointType.DPT_DALI_Fade_Time: { /* 'DPT_DALI_Fade_Time' */
+                    return 602;
+                }
+                case KnxDatapointType.DPT_DHWMode: { /* 'DPT_DHWMode' */
+                    return 103;
+                }
+                case KnxDatapointType.DPT_DHWModeNext: { /* 'DPT_DHWModeNext' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_DHWMode_Z: { /* 'DPT_DHWMode_Z' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_DamperMode: { /* 'DPT_DamperMode' */
+                    return 109;
+                }
+                case KnxDatapointType.DPT_Date: { /* 'DPT_Date' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_DateTime: { /* 'DPT_DateTime' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_DecimalFactor: { /* 'DPT_DecimalFactor' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_DeltaTime100MSec: { /* 'DPT_DeltaTime100MSec' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_DeltaTime100Msec_Z: { /* 'DPT_DeltaTime100Msec_Z' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_DeltaTime10MSec: { /* 'DPT_DeltaTime10MSec' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_DeltaTime10Msec_Z: { /* 'DPT_DeltaTime10Msec_Z' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_DeltaTimeHrs: { /* 'DPT_DeltaTimeHrs' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_DeltaTimeHrs_Z: { /* 'DPT_DeltaTimeHrs_Z' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_DeltaTimeMin: { /* 'DPT_DeltaTimeMin' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_DeltaTimeMin_Z: { /* 'DPT_DeltaTimeMin_Z' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_DeltaTimeMsec: { /* 'DPT_DeltaTimeMsec' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_DeltaTimeMsec_Z: { /* 'DPT_DeltaTimeMsec_Z' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_DeltaTimeSec: { /* 'DPT_DeltaTimeSec' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_DeltaTimeSec_Z: { /* 'DPT_DeltaTimeSec_Z' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_Device_Control: { /* 'DPT_Device_Control' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_DimSendStyle: { /* 'DPT_DimSendStyle' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_DimmPBModel: { /* 'DPT_DimmPBModel' */
+                    return 607;
+                }
+                case KnxDatapointType.DPT_Direction1_Control: { /* 'DPT_Direction1_Control' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_Direction2_Control: { /* 'DPT_Direction2_Control' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_DoubleNibble: { /* 'DPT_DoubleNibble' */
+                    return 1000;
+                }
+                case KnxDatapointType.DPT_EnablH_Cstage_Z_DPT_EnablH_CStage: { /* 'DPT_EnablH_Cstage_Z_DPT_EnablH_CStage' */
+                    return 105;
+                }
+                case KnxDatapointType.DPT_Enable: { /* 'DPT_Enable' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_Enable_Control: { /* 'DPT_Enable_Control' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_EnergyDemAir: { /* 'DPT_EnergyDemAir' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_EnergyDemWater: { /* 'DPT_EnergyDemWater' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_ErrorClass_HVAC: { /* 'DPT_ErrorClass_HVAC' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_ErrorClass_System: { /* 'DPT_ErrorClass_System' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_FanMode: { /* 'DPT_FanMode' */
+                    return 111;
+                }
+                case KnxDatapointType.DPT_FlaggedScaling: { /* 'DPT_FlaggedScaling' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_FlowRate_m3h: { /* 'DPT_FlowRate_m3h' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_FlowRate_m3h_Z: { /* 'DPT_FlowRate_m3h_Z' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_ForceSign: { /* 'DPT_ForceSign' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_ForceSignCool: { /* 'DPT_ForceSignCool' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_FuelType: { /* 'DPT_FuelType' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_FuelTypeSet: { /* 'DPT_FuelTypeSet' */
+                    return 104;
+                }
+                case KnxDatapointType.DPT_HVACAirFlowAbs_Z: { /* 'DPT_HVACAirFlowAbs_Z' */
+                    return 104;
+                }
+                case KnxDatapointType.DPT_HVACAirFlowRel_Z: { /* 'DPT_HVACAirFlowRel_Z' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_HVACAirQual_Z: { /* 'DPT_HVACAirQual_Z' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_HVACContrMode: { /* 'DPT_HVACContrMode' */
+                    return 105;
+                }
+                case KnxDatapointType.DPT_HVACContrMode_Z: { /* 'DPT_HVACContrMode_Z' */
+                    return 104;
+                }
+                case KnxDatapointType.DPT_HVACEmergMode: { /* 'DPT_HVACEmergMode' */
+                    return 106;
+                }
+                case KnxDatapointType.DPT_HVACEmergMode_Z: { /* 'DPT_HVACEmergMode_Z' */
+                    return 109;
+                }
+                case KnxDatapointType.DPT_HVACMode: { /* 'DPT_HVACMode' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_HVACModeNext: { /* 'DPT_HVACModeNext' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_HVACMode_Z: { /* 'DPT_HVACMode_Z' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_HVAC_PB_Action: { /* 'DPT_HVAC_PB_Action' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_Heat_Cool: { /* 'DPT_Heat_Cool' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_Heat_Cool_Z: { /* 'DPT_Heat_Cool_Z' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_HeaterMode: { /* 'DPT_HeaterMode' */
+                    return 110;
+                }
+                case KnxDatapointType.DPT_InputSource: { /* 'DPT_InputSource' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Invert: { /* 'DPT_Invert' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_Invert_Control: { /* 'DPT_Invert_Control' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_KelvinPerPercent: { /* 'DPT_KelvinPerPercent' */
+                    return 23;
+                }
+                case KnxDatapointType.DPT_LanguageCodeAlpha2_ASCII: { /* 'DPT_LanguageCodeAlpha2_ASCII' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Length_mm: { /* 'DPT_Length_mm' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_LightActuatorErrorInfo: { /* 'DPT_LightActuatorErrorInfo' */
+                    return 601;
+                }
+                case KnxDatapointType.DPT_LightApplicationMode: { /* 'DPT_LightApplicationMode' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_LightControlMode: { /* 'DPT_LightControlMode' */
+                    return 604;
+                }
+                case KnxDatapointType.DPT_LoadPriority: { /* 'DPT_LoadPriority' */
+                    return 104;
+                }
+                case KnxDatapointType.DPT_LoadTypeDetected: { /* 'DPT_LoadTypeDetected' */
+                    return 610;
+                }
+                case KnxDatapointType.DPT_LoadTypeSet: { /* 'DPT_LoadTypeSet' */
+                    return 609;
+                }
+                case KnxDatapointType.DPT_Locale_ASCII: { /* 'DPT_Locale_ASCII' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_LockSign: { /* 'DPT_LockSign' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_LogicalFunction: { /* 'DPT_LogicalFunction' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_LongDeltaTimeSec: { /* 'DPT_LongDeltaTimeSec' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_MBus_Address: { /* 'DPT_MBus_Address' */
+                    return 1000;
+                }
+                case KnxDatapointType.DPT_MasterSlaveMode: { /* 'DPT_MasterSlaveMode' */
+                    return 112;
+                }
+                case KnxDatapointType.DPT_Media: { /* 'DPT_Media' */
+                    return 1000;
+                }
+                case KnxDatapointType.DPT_MeteringValue: { /* 'DPT_MeteringValue' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_OccMode: { /* 'DPT_OccMode' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_OccModeNext: { /* 'DPT_OccModeNext' */
+                    return 104;
+                }
+                case KnxDatapointType.DPT_OccMode_Z: { /* 'DPT_OccMode_Z' */
+                    return 108;
+                }
+                case KnxDatapointType.DPT_Occupancy: { /* 'DPT_Occupancy' */
+                    return 18;
+                }
+                case KnxDatapointType.DPT_OnOff_Action: { /* 'DPT_OnOff_Action' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_OpenClose: { /* 'DPT_OpenClose' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_PBAction: { /* 'DPT_PBAction' */
+                    return 606;
+                }
+                case KnxDatapointType.DPT_PB_Action_HVAC_Extended: { /* 'DPT_PB_Action_HVAC_Extended' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_PSUMode: { /* 'DPT_PSUMode' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_PercentU16_Z: { /* 'DPT_PercentU16_Z' */
+                    return 17;
+                }
+                case KnxDatapointType.DPT_Percent_U8: { /* 'DPT_Percent_U8' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_Percent_V16: { /* 'DPT_Percent_V16' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_Percent_V16_Z: { /* 'DPT_Percent_V16_Z' */
+                    return 17;
+                }
+                case KnxDatapointType.DPT_Percent_V8: { /* 'DPT_Percent_V8' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Power: { /* 'DPT_Power' */
+                    return 24;
+                }
+                case KnxDatapointType.DPT_PowerDensity: { /* 'DPT_PowerDensity' */
+                    return 22;
+                }
+                case KnxDatapointType.DPT_PowerFlowWaterDemCPM: { /* 'DPT_PowerFlowWaterDemCPM' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_PowerFlowWaterDemHPM: { /* 'DPT_PowerFlowWaterDemHPM' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_PowerKW_Z: { /* 'DPT_PowerKW_Z' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Prioritised_Mode_Control: { /* 'DPT_Prioritised_Mode_Control' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Priority: { /* 'DPT_Priority' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_PropDataType: { /* 'DPT_PropDataType' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_RF_FilterInfo: { /* 'DPT_RF_FilterInfo' */
+                    return 1001;
+                }
+                case KnxDatapointType.DPT_RF_FilterSelect: { /* 'DPT_RF_FilterSelect' */
+                    return 1003;
+                }
+                case KnxDatapointType.DPT_RF_ModeInfo: { /* 'DPT_RF_ModeInfo' */
+                    return 1000;
+                }
+                case KnxDatapointType.DPT_RF_ModeSelect: { /* 'DPT_RF_ModeSelect' */
+                    return 1002;
+                }
+                case KnxDatapointType.DPT_Rain_Amount: { /* 'DPT_Rain_Amount' */
+                    return 26;
+                }
+                case KnxDatapointType.DPT_Ramp: { /* 'DPT_Ramp' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_Ramp_Control: { /* 'DPT_Ramp_Control' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy: { /* 'DPT_ReactiveEnergy' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy_V64: { /* 'DPT_ReactiveEnergy_V64' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_ReactiveEnergy_kVARh: { /* 'DPT_ReactiveEnergy_kVARh' */
+                    return 15;
+                }
+                case KnxDatapointType.DPT_RegionCodeAlpha2_ASCII: { /* 'DPT_RegionCodeAlpha2_ASCII' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_RelSignedValue_Z: { /* 'DPT_RelSignedValue_Z' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_RelValue_Z: { /* 'DPT_RelValue_Z' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Reset: { /* 'DPT_Reset' */
+                    return 15;
+                }
+                case KnxDatapointType.DPT_Rotation_Angle: { /* 'DPT_Rotation_Angle' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_SABBehaviour_Lock_Unlock: { /* 'DPT_SABBehaviour_Lock_Unlock' */
+                    return 802;
+                }
+                case KnxDatapointType.DPT_SABExceptBehaviour: { /* 'DPT_SABExceptBehaviour' */
+                    return 801;
+                }
+                case KnxDatapointType.DPT_SCLOMode: { /* 'DPT_SCLOMode' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_SSSBMode: { /* 'DPT_SSSBMode' */
+                    return 803;
+                }
+                case KnxDatapointType.DPT_Scaling: { /* 'DPT_Scaling' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_ScalingSpeed: { /* 'DPT_ScalingSpeed' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Scaling_Step_Time: { /* 'DPT_Scaling_Step_Time' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_SceneConfig: { /* 'DPT_SceneConfig' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_SceneControl: { /* 'DPT_SceneControl' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_SceneInfo: { /* 'DPT_SceneInfo' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_SceneNumber: { /* 'DPT_SceneNumber' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Scene_AB: { /* 'DPT_Scene_AB' */
+                    return 22;
+                }
+                case KnxDatapointType.DPT_SensorSelect: { /* 'DPT_SensorSelect' */
+                    return 17;
+                }
+                case KnxDatapointType.DPT_SerNum: { /* 'DPT_SerNum' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_ShutterBlinds_Mode: { /* 'DPT_ShutterBlinds_Mode' */
+                    return 23;
+                }
+                case KnxDatapointType.DPT_SpecHeatProd: { /* 'DPT_SpecHeatProd' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_Start: { /* 'DPT_Start' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_StartSynchronization: { /* 'DPT_StartSynchronization' */
+                    return 122;
+                }
+                case KnxDatapointType.DPT_Start_Control: { /* 'DPT_Start_Control' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_State: { /* 'DPT_State' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_State_Control: { /* 'DPT_State_Control' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_StatusAHU: { /* 'DPT_StatusAHU' */
+                    return 106;
+                }
+                case KnxDatapointType.DPT_StatusAct: { /* 'DPT_StatusAct' */
+                    return 105;
+                }
+                case KnxDatapointType.DPT_StatusBOC: { /* 'DPT_StatusBOC' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_StatusBUC: { /* 'DPT_StatusBUC' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_StatusCC: { /* 'DPT_StatusCC' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_StatusCPM: { /* 'DPT_StatusCPM' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_StatusDHWC: { /* 'DPT_StatusDHWC' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_StatusGen: { /* 'DPT_StatusGen' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_StatusHPM: { /* 'DPT_StatusHPM' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_StatusLightingActuator: { /* 'DPT_StatusLightingActuator' */
+                    return 600;
+                }
+                case KnxDatapointType.DPT_StatusRCC: { /* 'DPT_StatusRCC' */
+                    return 105;
+                }
+                case KnxDatapointType.DPT_StatusRHC: { /* 'DPT_StatusRHC' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_StatusRHCC: { /* 'DPT_StatusRHCC' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_StatusRoomSetp: { /* 'DPT_StatusRoomSetp' */
+                    return 113;
+                }
+                case KnxDatapointType.DPT_StatusSAB: { /* 'DPT_StatusSAB' */
+                    return 800;
+                }
+                case KnxDatapointType.DPT_StatusSDHWC: { /* 'DPT_StatusSDHWC' */
+                    return 103;
+                }
+                case KnxDatapointType.DPT_StatusWTC: { /* 'DPT_StatusWTC' */
+                    return 103;
+                }
+                case KnxDatapointType.DPT_Status_Mode3: { /* 'DPT_Status_Mode3' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Step: { /* 'DPT_Step' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_Step_Control: { /* 'DPT_Step_Control' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_String_8859_1: { /* 'DPT_String_8859_1' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_String_ASCII: { /* 'DPT_String_ASCII' */
+                    return 0;
+                }
+                case KnxDatapointType.DPT_SunIntensity_Z: { /* 'DPT_SunIntensity_Z' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_Switch: { /* 'DPT_Switch' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_SwitchOnMode: { /* 'DPT_SwitchOnMode' */
+                    return 608;
+                }
+                case KnxDatapointType.DPT_SwitchPBModel: { /* 'DPT_SwitchPBModel' */
+                    return 605;
+                }
+                case KnxDatapointType.DPT_Switch_Control: { /* 'DPT_Switch_Control' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Tariff: { /* 'DPT_Tariff' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_TariffNext: { /* 'DPT_TariffNext' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_Tariff_ActiveEnergy: { /* 'DPT_Tariff_ActiveEnergy' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_TempDHWSetpSet4: { /* 'DPT_TempDHWSetpSet4' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_TempFlowWaterDemAbs: { /* 'DPT_TempFlowWaterDemAbs' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_TempHVACAbsNext: { /* 'DPT_TempHVACAbsNext' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_TempHVACAbs_Z: { /* 'DPT_TempHVACAbs_Z' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_TempHVACRel_Z: { /* 'DPT_TempHVACRel_Z' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_TempRoomDemAbs: { /* 'DPT_TempRoomDemAbs' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSet3: { /* 'DPT_TempRoomSetpSet3' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSet4: { /* 'DPT_TempRoomSetpSet4' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetF163: { /* 'DPT_TempRoomSetpSetF163' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShift3: { /* 'DPT_TempRoomSetpSetShift3' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShift4: { /* 'DPT_TempRoomSetpSetShift4' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_TempRoomSetpSetShiftF163: { /* 'DPT_TempRoomSetpSetShiftF163' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_TempSupply_AirSetpSet: { /* 'DPT_TempSupply_AirSetpSet' */
+                    return 100;
+                }
+                case KnxDatapointType.DPT_TimeOfDay: { /* 'DPT_TimeOfDay' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_TimePeriod100MSec: { /* 'DPT_TimePeriod100MSec' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_TimePeriod100Msec_Z: { /* 'DPT_TimePeriod100Msec_Z' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_TimePeriod10MSec: { /* 'DPT_TimePeriod10MSec' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_TimePeriod10Msec_Z: { /* 'DPT_TimePeriod10Msec_Z' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_TimePeriodHrs: { /* 'DPT_TimePeriodHrs' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_TimePeriodHrs_Z: { /* 'DPT_TimePeriodHrs_Z' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_TimePeriodMin: { /* 'DPT_TimePeriodMin' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_TimePeriodMin_Z: { /* 'DPT_TimePeriodMin_Z' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_TimePeriodMsec: { /* 'DPT_TimePeriodMsec' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_TimePeriodMsec_Z: { /* 'DPT_TimePeriodMsec_Z' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_TimePeriodSec: { /* 'DPT_TimePeriodSec' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_TimePeriodSec_Z: { /* 'DPT_TimePeriodSec_Z' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_Time_Delay: { /* 'DPT_Time_Delay' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_Trigger: { /* 'DPT_Trigger' */
+                    return 17;
+                }
+                case KnxDatapointType.DPT_UCountValue16_Z: { /* 'DPT_UCountValue16_Z' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_UCountValue8_Z: { /* 'DPT_UCountValue8_Z' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_UElCurrentmA: { /* 'DPT_UElCurrentmA' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_UElCurrentyA_Z: { /* 'DPT_UElCurrentyA_Z' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_UFlowRateLiter_h_Z: { /* 'DPT_UFlowRateLiter_h_Z' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_UTF_8: { /* 'DPT_UTF_8' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_UpDown: { /* 'DPT_UpDown' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_UpDown_Action: { /* 'DPT_UpDown_Action' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_ValueDemBOC: { /* 'DPT_ValueDemBOC' */
+                    return 102;
+                }
+                case KnxDatapointType.DPT_Value_1_Count: { /* 'DPT_Value_1_Count' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_Value_1_Ucount: { /* 'DPT_Value_1_Ucount' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_Value_2_Count: { /* 'DPT_Value_2_Count' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Value_2_Ucount: { /* 'DPT_Value_2_Ucount' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Value_4_Count: { /* 'DPT_Value_4_Count' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Value_4_Ucount: { /* 'DPT_Value_4_Ucount' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Value_Absolute_Temperature: { /* 'DPT_Value_Absolute_Temperature' */
+                    return 69;
+                }
+                case KnxDatapointType.DPT_Value_Acceleration: { /* 'DPT_Value_Acceleration' */
+                    return 0;
+                }
+                case KnxDatapointType.DPT_Value_Acceleration_Angular: { /* 'DPT_Value_Acceleration_Angular' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Value_Activation_Energy: { /* 'DPT_Value_Activation_Energy' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Value_Activity: { /* 'DPT_Value_Activity' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_Value_AirQuality: { /* 'DPT_Value_AirQuality' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_Value_Amplitude: { /* 'DPT_Value_Amplitude' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_Value_AngleDeg: { /* 'DPT_Value_AngleDeg' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_Value_AngleRad: { /* 'DPT_Value_AngleRad' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_Value_Angular_Frequency: { /* 'DPT_Value_Angular_Frequency' */
+                    return 34;
+                }
+                case KnxDatapointType.DPT_Value_Angular_Momentum: { /* 'DPT_Value_Angular_Momentum' */
+                    return 8;
+                }
+                case KnxDatapointType.DPT_Value_Angular_Velocity: { /* 'DPT_Value_Angular_Velocity' */
+                    return 9;
+                }
+                case KnxDatapointType.DPT_Value_Area: { /* 'DPT_Value_Area' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_Value_Capacitance: { /* 'DPT_Value_Capacitance' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_Value_Charge_DensitySurface: { /* 'DPT_Value_Charge_DensitySurface' */
+                    return 12;
+                }
+                case KnxDatapointType.DPT_Value_Charge_DensityVolume: { /* 'DPT_Value_Charge_DensityVolume' */
+                    return 13;
+                }
+                case KnxDatapointType.DPT_Value_Common_Temperature: { /* 'DPT_Value_Common_Temperature' */
+                    return 68;
+                }
+                case KnxDatapointType.DPT_Value_Compressibility: { /* 'DPT_Value_Compressibility' */
+                    return 14;
+                }
+                case KnxDatapointType.DPT_Value_Conductance: { /* 'DPT_Value_Conductance' */
+                    return 15;
+                }
+                case KnxDatapointType.DPT_Value_Curr: { /* 'DPT_Value_Curr' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_Value_Density: { /* 'DPT_Value_Density' */
+                    return 17;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Charge: { /* 'DPT_Value_Electric_Charge' */
+                    return 18;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Current: { /* 'DPT_Value_Electric_Current' */
+                    return 19;
+                }
+                case KnxDatapointType.DPT_Value_Electric_CurrentDensity: { /* 'DPT_Value_Electric_CurrentDensity' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Value_Electric_DipoleMoment: { /* 'DPT_Value_Electric_DipoleMoment' */
+                    return 21;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Displacement: { /* 'DPT_Value_Electric_Displacement' */
+                    return 22;
+                }
+                case KnxDatapointType.DPT_Value_Electric_FieldStrength: { /* 'DPT_Value_Electric_FieldStrength' */
+                    return 23;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Flux: { /* 'DPT_Value_Electric_Flux' */
+                    return 24;
+                }
+                case KnxDatapointType.DPT_Value_Electric_FluxDensity: { /* 'DPT_Value_Electric_FluxDensity' */
+                    return 25;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Polarization: { /* 'DPT_Value_Electric_Polarization' */
+                    return 26;
+                }
+                case KnxDatapointType.DPT_Value_Electric_Potential: { /* 'DPT_Value_Electric_Potential' */
+                    return 27;
+                }
+                case KnxDatapointType.DPT_Value_Electric_PotentialDifference: { /* 'DPT_Value_Electric_PotentialDifference' */
+                    return 28;
+                }
+                case KnxDatapointType.DPT_Value_Electrical_Conductivity: { /* 'DPT_Value_Electrical_Conductivity' */
+                    return 16;
+                }
+                case KnxDatapointType.DPT_Value_ElectromagneticMoment: { /* 'DPT_Value_ElectromagneticMoment' */
+                    return 29;
+                }
+                case KnxDatapointType.DPT_Value_Electromotive_Force: { /* 'DPT_Value_Electromotive_Force' */
+                    return 30;
+                }
+                case KnxDatapointType.DPT_Value_Energy: { /* 'DPT_Value_Energy' */
+                    return 31;
+                }
+                case KnxDatapointType.DPT_Value_Force: { /* 'DPT_Value_Force' */
+                    return 32;
+                }
+                case KnxDatapointType.DPT_Value_Frequency: { /* 'DPT_Value_Frequency' */
+                    return 33;
+                }
+                case KnxDatapointType.DPT_Value_Heat_Capacity: { /* 'DPT_Value_Heat_Capacity' */
+                    return 35;
+                }
+                case KnxDatapointType.DPT_Value_Heat_FlowRate: { /* 'DPT_Value_Heat_FlowRate' */
+                    return 36;
+                }
+                case KnxDatapointType.DPT_Value_Heat_Quantity: { /* 'DPT_Value_Heat_Quantity' */
+                    return 37;
+                }
+                case KnxDatapointType.DPT_Value_Humidity: { /* 'DPT_Value_Humidity' */
+                    return 7;
+                }
+                case KnxDatapointType.DPT_Value_Impedance: { /* 'DPT_Value_Impedance' */
+                    return 38;
+                }
+                case KnxDatapointType.DPT_Value_Length: { /* 'DPT_Value_Length' */
+                    return 39;
+                }
+                case KnxDatapointType.DPT_Value_Light_Quantity: { /* 'DPT_Value_Light_Quantity' */
+                    return 40;
+                }
+                case KnxDatapointType.DPT_Value_Luminance: { /* 'DPT_Value_Luminance' */
+                    return 41;
+                }
+                case KnxDatapointType.DPT_Value_Luminous_Flux: { /* 'DPT_Value_Luminous_Flux' */
+                    return 42;
+                }
+                case KnxDatapointType.DPT_Value_Luminous_Intensity: { /* 'DPT_Value_Luminous_Intensity' */
+                    return 43;
+                }
+                case KnxDatapointType.DPT_Value_Lux: { /* 'DPT_Value_Lux' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_FieldStrength: { /* 'DPT_Value_Magnetic_FieldStrength' */
+                    return 44;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Flux: { /* 'DPT_Value_Magnetic_Flux' */
+                    return 45;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_FluxDensity: { /* 'DPT_Value_Magnetic_FluxDensity' */
+                    return 46;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Moment: { /* 'DPT_Value_Magnetic_Moment' */
+                    return 47;
+                }
+                case KnxDatapointType.DPT_Value_Magnetic_Polarization: { /* 'DPT_Value_Magnetic_Polarization' */
+                    return 48;
+                }
+                case KnxDatapointType.DPT_Value_Magnetization: { /* 'DPT_Value_Magnetization' */
+                    return 49;
+                }
+                case KnxDatapointType.DPT_Value_MagnetomotiveForce: { /* 'DPT_Value_MagnetomotiveForce' */
+                    return 50;
+                }
+                case KnxDatapointType.DPT_Value_Mass: { /* 'DPT_Value_Mass' */
+                    return 51;
+                }
+                case KnxDatapointType.DPT_Value_MassFlux: { /* 'DPT_Value_MassFlux' */
+                    return 52;
+                }
+                case KnxDatapointType.DPT_Value_Mol: { /* 'DPT_Value_Mol' */
+                    return 4;
+                }
+                case KnxDatapointType.DPT_Value_Momentum: { /* 'DPT_Value_Momentum' */
+                    return 53;
+                }
+                case KnxDatapointType.DPT_Value_Phase_AngleDeg: { /* 'DPT_Value_Phase_AngleDeg' */
+                    return 55;
+                }
+                case KnxDatapointType.DPT_Value_Phase_AngleRad: { /* 'DPT_Value_Phase_AngleRad' */
+                    return 54;
+                }
+                case KnxDatapointType.DPT_Value_Power: { /* 'DPT_Value_Power' */
+                    return 56;
+                }
+                case KnxDatapointType.DPT_Value_Power_Factor: { /* 'DPT_Value_Power_Factor' */
+                    return 57;
+                }
+                case KnxDatapointType.DPT_Value_Pres: { /* 'DPT_Value_Pres' */
+                    return 6;
+                }
+                case KnxDatapointType.DPT_Value_Pressure: { /* 'DPT_Value_Pressure' */
+                    return 58;
+                }
+                case KnxDatapointType.DPT_Value_Reactance: { /* 'DPT_Value_Reactance' */
+                    return 59;
+                }
+                case KnxDatapointType.DPT_Value_Resistance: { /* 'DPT_Value_Resistance' */
+                    return 60;
+                }
+                case KnxDatapointType.DPT_Value_Resistivity: { /* 'DPT_Value_Resistivity' */
+                    return 61;
+                }
+                case KnxDatapointType.DPT_Value_SelfInductance: { /* 'DPT_Value_SelfInductance' */
+                    return 62;
+                }
+                case KnxDatapointType.DPT_Value_SolidAngle: { /* 'DPT_Value_SolidAngle' */
+                    return 63;
+                }
+                case KnxDatapointType.DPT_Value_Sound_Intensity: { /* 'DPT_Value_Sound_Intensity' */
+                    return 64;
+                }
+                case KnxDatapointType.DPT_Value_Speed: { /* 'DPT_Value_Speed' */
+                    return 65;
+                }
+                case KnxDatapointType.DPT_Value_Stress: { /* 'DPT_Value_Stress' */
+                    return 66;
+                }
+                case KnxDatapointType.DPT_Value_Surface_Tension: { /* 'DPT_Value_Surface_Tension' */
+                    return 67;
+                }
+                case KnxDatapointType.DPT_Value_Temp: { /* 'DPT_Value_Temp' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Value_Temp_F: { /* 'DPT_Value_Temp_F' */
+                    return 27;
+                }
+                case KnxDatapointType.DPT_Value_Tempa: { /* 'DPT_Value_Tempa' */
+                    return 3;
+                }
+                case KnxDatapointType.DPT_Value_Tempd: { /* 'DPT_Value_Tempd' */
+                    return 2;
+                }
+                case KnxDatapointType.DPT_Value_TemperatureDifference: { /* 'DPT_Value_TemperatureDifference' */
+                    return 70;
+                }
+                case KnxDatapointType.DPT_Value_Thermal_Capacity: { /* 'DPT_Value_Thermal_Capacity' */
+                    return 71;
+                }
+                case KnxDatapointType.DPT_Value_Thermal_Conductivity: { /* 'DPT_Value_Thermal_Conductivity' */
+                    return 72;
+                }
+                case KnxDatapointType.DPT_Value_ThermoelectricPower: { /* 'DPT_Value_ThermoelectricPower' */
+                    return 73;
+                }
+                case KnxDatapointType.DPT_Value_Time: { /* 'DPT_Value_Time' */
+                    return 74;
+                }
+                case KnxDatapointType.DPT_Value_Time1: { /* 'DPT_Value_Time1' */
+                    return 10;
+                }
+                case KnxDatapointType.DPT_Value_Time2: { /* 'DPT_Value_Time2' */
+                    return 11;
+                }
+                case KnxDatapointType.DPT_Value_Torque: { /* 'DPT_Value_Torque' */
+                    return 75;
+                }
+                case KnxDatapointType.DPT_Value_Volt: { /* 'DPT_Value_Volt' */
+                    return 20;
+                }
+                case KnxDatapointType.DPT_Value_Volume: { /* 'DPT_Value_Volume' */
+                    return 76;
+                }
+                case KnxDatapointType.DPT_Value_Volume_Flow: { /* 'DPT_Value_Volume_Flow' */
+                    return 25;
+                }
+                case KnxDatapointType.DPT_Value_Volume_Flux: { /* 'DPT_Value_Volume_Flux' */
+                    return 77;
+                }
+                case KnxDatapointType.DPT_Value_Weight: { /* 'DPT_Value_Weight' */
+                    return 78;
+                }
+                case KnxDatapointType.DPT_Value_Work: { /* 'DPT_Value_Work' */
+                    return 79;
+                }
+                case KnxDatapointType.DPT_Value_Wsp: { /* 'DPT_Value_Wsp' */
+                    return 5;
+                }
+                case KnxDatapointType.DPT_Value_Wsp_kmh: { /* 'DPT_Value_Wsp_kmh' */
+                    return 28;
+                }
+                case KnxDatapointType.DPT_ValveMode: { /* 'DPT_ValveMode' */
+                    return 108;
+                }
+                case KnxDatapointType.DPT_VarString_8859_1: { /* 'DPT_VarString_8859_1' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_Version: { /* 'DPT_Version' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_VolumeLiter_Z: { /* 'DPT_VolumeLiter_Z' */
+                    return 1;
+                }
+                case KnxDatapointType.DPT_WindSpeed_Z_DPT_WindSpeed: { /* 'DPT_WindSpeed_Z_DPT_WindSpeed' */
+                    return 101;
+                }
+                case KnxDatapointType.DPT_Window_Door: { /* 'DPT_Window_Door' */
+                    return 19;
+                }
+                default: {
+                    return 0;
+                }
+            }
+        }
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxLayer.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxLayer.cs
new file mode 100644
index 0000000..0b697cc
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxLayer.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum KnxLayer : byte
+    {
+
+        TUNNEL_LINK_LAYER = 0x02,
+        TUNNEL_RAW = 0x04,
+        TUNNEL_BUSMONITOR = 0x80,
+
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxMedium.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxMedium.cs
new file mode 100644
index 0000000..d7ffb76
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxMedium.cs
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum KnxMedium : byte
+    {
+
+        MEDIUM_RESERVED_1 = 0x01,
+        MEDIUM_TP1 = 0x02,
+        MEDIUM_PL110 = 0x04,
+        MEDIUM_RESERVED_2 = 0x08,
+        MEDIUM_RF = 0x10,
+        MEDIUM_KNX_IP = 0x20,
+
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/Status.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/Status.cs
new file mode 100644
index 0000000..d000f4a
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/Status.cs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum Status : byte
+    {
+
+        NO_ERROR = 0x00,
+        PROTOCOL_TYPE_NOT_SUPPORTED = 0x01,
+        UNSUPPORTED_PROTOCOL_VERSION = 0x02,
+        OUT_OF_ORDER_SEQUENCE_NUMBER = 0x04,
+        INVALID_CONNECTION_ID = 0x21,
+        CONNECTION_TYPE_NOT_SUPPORTED = 0x22,
+        CONNECTION_OPTION_NOT_SUPPORTED = 0x23,
+        NO_MORE_CONNECTIONS = 0x24,
+        NO_MORE_UNIQUE_CONNECTIONS = 0x25,
+        DATA_CONNECTION = 0x26,
+        KNX_CONNECTION = 0x27,
+        TUNNELLING_LAYER_NOT_SUPPORTED = 0x29,
+
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SupportedPhysicalMedia.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SupportedPhysicalMedia.cs
new file mode 100644
index 0000000..f33d56e
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/SupportedPhysicalMedia.cs
@@ -0,0 +1,201 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum SupportedPhysicalMedia : byte
+    {
+
+        OTHER = 0x00,
+        OIL_METER = 0x01,
+        ELECTRICITY_METER = 0x02,
+        GAS_METER = 0x03,
+        HEAT_METER = 0x04,
+        STEAM_METER = 0x05,
+        WARM_WATER_METER = 0x06,
+        WATER_METER = 0x07,
+        HEAT_COST_ALLOCATOR = 0x08,
+        COMPRESSED_AIR = 0x09,
+        COOLING_LOAD_METER_INLET = 0x0A,
+        COOLING_LOAD_METER_OUTLET = 0x0B,
+        HEAT_INLET = 0x0C,
+        HEAT_AND_COOL = 0x0D,
+        BUS_OR_SYSTEM = 0x0E,
+        UNKNOWN_DEVICE_TYPE = 0x0F,
+        BREAKER = 0x20,
+        VALVE = 0x21,
+        WASTE_WATER_METER = 0x28,
+        GARBAGE = 0x29,
+        RADIO_CONVERTER = 0x37,
+
+    }
+
+    public static class SupportedPhysicalMediaInfo
+    {
+
+        public static bool KnxSupport(this SupportedPhysicalMedia value)
+        {
+            switch (value)
+            {
+                case SupportedPhysicalMedia.OTHER: { /* '0x00' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.OIL_METER: { /* '0x01' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.ELECTRICITY_METER: { /* '0x02' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.GAS_METER: { /* '0x03' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.HEAT_METER: { /* '0x04' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.STEAM_METER: { /* '0x05' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.WARM_WATER_METER: { /* '0x06' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.WATER_METER: { /* '0x07' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.HEAT_COST_ALLOCATOR: { /* '0x08' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.COMPRESSED_AIR: { /* '0x09' */
+                    return false;
+                }
+                case SupportedPhysicalMedia.COOLING_LOAD_METER_INLET: { /* '0x0A' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.COOLING_LOAD_METER_OUTLET: { /* '0x0B' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.HEAT_INLET: { /* '0x0C' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.HEAT_AND_COOL: { /* '0x0D' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.BUS_OR_SYSTEM: { /* '0x0E' */
+                    return false;
+                }
+                case SupportedPhysicalMedia.UNKNOWN_DEVICE_TYPE: { /* '0x0F' */
+                    return false;
+                }
+                case SupportedPhysicalMedia.BREAKER: { /* '0x20' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.VALVE: { /* '0x21' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.WASTE_WATER_METER: { /* '0x28' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.GARBAGE: { /* '0x29' */
+                    return true;
+                }
+                case SupportedPhysicalMedia.RADIO_CONVERTER: { /* '0x37' */
+                    return false;
+                }
+                default: {
+                    return false;
+                }
+            }
+        }
+
+        public static string Description(this SupportedPhysicalMedia value)
+        {
+            switch (value)
+            {
+                case SupportedPhysicalMedia.OTHER: { /* '0x00' */
+                    return "used_for_undefined_physical_medium";
+                }
+                case SupportedPhysicalMedia.OIL_METER: { /* '0x01' */
+                    return "measures_volume_of_oil";
+                }
+                case SupportedPhysicalMedia.ELECTRICITY_METER: { /* '0x02' */
+                    return "measures_electric_energy";
+                }
+                case SupportedPhysicalMedia.GAS_METER: { /* '0x03' */
+                    return "measures_volume_of_gaseous_energy";
+                }
+                case SupportedPhysicalMedia.HEAT_METER: { /* '0x04' */
+                    return "heat_energy_measured_in_outlet_pipe";
+                }
+                case SupportedPhysicalMedia.STEAM_METER: { /* '0x05' */
+                    return "measures_weight_of_hot_steam";
+                }
+                case SupportedPhysicalMedia.WARM_WATER_METER: { /* '0x06' */
+                    return "measured_heated_water_volume";
+                }
+                case SupportedPhysicalMedia.WATER_METER: { /* '0x07' */
+                    return "measured_water_volume";
+                }
+                case SupportedPhysicalMedia.HEAT_COST_ALLOCATOR: { /* '0x08' */
+                    return "measured_relative_cumulated_heat_consumption";
+                }
+                case SupportedPhysicalMedia.COMPRESSED_AIR: { /* '0x09' */
+                    return "measures_weight_of_compressed_air";
+                }
+                case SupportedPhysicalMedia.COOLING_LOAD_METER_INLET: { /* '0x0A' */
+                    return "cooling_energy_measured_in_inlet_pipe";
+                }
+                case SupportedPhysicalMedia.COOLING_LOAD_METER_OUTLET: { /* '0x0B' */
+                    return "cooling_energy_measured_in_outlet_pipe";
+                }
+                case SupportedPhysicalMedia.HEAT_INLET: { /* '0x0C' */
+                    return "heat_energy_measured_in_inlet_pipe";
+                }
+                case SupportedPhysicalMedia.HEAT_AND_COOL: { /* '0x0D' */
+                    return "measures_both_heat_and_cool";
+                }
+                case SupportedPhysicalMedia.BUS_OR_SYSTEM: { /* '0x0E' */
+                    return "no_meter";
+                }
+                case SupportedPhysicalMedia.UNKNOWN_DEVICE_TYPE: { /* '0x0F' */
+                    return "used_for_undefined_physical_medium";
+                }
+                case SupportedPhysicalMedia.BREAKER: { /* '0x20' */
+                    return "status_of_electric_energy_supply";
+                }
+                case SupportedPhysicalMedia.VALVE: { /* '0x21' */
+                    return "status_of_supply_of_Gas_or_water";
+                }
+                case SupportedPhysicalMedia.WASTE_WATER_METER: { /* '0x28' */
+                    return "measured_volume_of_disposed_water";
+                }
+                case SupportedPhysicalMedia.GARBAGE: { /* '0x29' */
+                    return "measured_weight_of_disposed_rubbish";
+                }
+                case SupportedPhysicalMedia.RADIO_CONVERTER: { /* '0x37' */
+                    return "enables_the_radio_transmission_of_a_meter_without_a_radio_interface";
+                }
+                default: {
+                    return "";
+                }
+            }
+        }
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TPCI.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TPCI.cs
new file mode 100644
index 0000000..757f83f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/TPCI.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum TPCI : byte
+    {
+
+        UNNUMBERED_DATA_PACKET = 0x0,
+        UNNUMBERED = 0x1,
+        NUMBERED_DATA_PACKET = 0x2,
+        NUMBERED_CONTROL_DATA = 0x3,
+
+    }
+
+}
+
diff --git a/src/main/script/prerequisiteCheck.groovy b/src/main/script/prerequisiteCheck.groovy
index 117bc9c..dba4ff1 100644
--- a/src/main/script/prerequisiteCheck.groovy
+++ b/src/main/script/prerequisiteCheck.groovy
@@ -109,7 +109,28 @@ def checkDotnet() {
     Matcher matcher = extractVersion(output)
     if (matcher.size() > 0) {
         def curVersion = matcher[0][1]
-        def result = checkVersionAtLeast(curVersion, "2.0.0")
+        def result = checkVersionAtLeast(curVersion, "4.5.2")
+        if (!result) {
+            allConditionsMet = false
+        }
+    } else {
+        println "missing"
+        allConditionsMet = false
+    }
+}
+
+def checkGo() {
+    print "Detecting Go version:      "
+    def output
+    try {
+        output = "go version".execute().text
+    } catch (IOException e) {
+        output = ""
+    }
+    Matcher matcher = extractVersion(output)
+    if (matcher.size() > 0) {
+        def curVersion = matcher[0][1]
+        def result = checkVersionAtLeast(curVersion, "1.0.0")
         if (!result) {
             allConditionsMet = false
         }
@@ -481,6 +502,8 @@ for (def activeProfile : activeProfiles) {
     } else if (activeProfile == "with-docker") {
         dockerEnabled = true
     } else if (activeProfile == "with-dotnet") {
+        goEnabled = true
+    } else if (activeProfile == "with-go") {
         dotnetEnabled = true
     } else if (activeProfile == "with-go") {
         goEnabled = true
@@ -518,6 +541,10 @@ if (dotnetEnabled) {
     checkDotnet()
 }
 
+if (goEnabled) {
+    checkGo()
+}
+
 if (cppEnabled) {
     checkClang()
     // The cmake-maven-plugin requires at least java 11

[plc4x] 01/09: - Work on PLC4net - Work on C# code generation

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

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

commit c88b01d668cc5b156701b155a1501972165fb1f9
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Dec 2 18:51:47 2020 +0100

    - Work on PLC4net
    - Work on C# code generation
---
 .../plc4net => build-utils/language-cs}/pom.xml    |   48 +-
 .../apache/plc4x/language/cs/CsLanguageOutput.java |   72 +
 .../language/cs/CsLanguageTemplateHelper.java      | 1053 ++++++
 ...x.plugins.codegenerator.language.LanguageOutput |   19 +
 .../resources/templates/cs/data-io-template.ftlh   |  206 +
 sandbox/plc4net/.gitignore                         |    7 +-
 .../{ => api}/exceptions/PlcConnectionException.cs |    0
 .../api/{ => api}/exceptions/PlcException.cs       |    0
 .../exceptions/PlcInvalidFieldException.cs         |    0
 .../api/{ => api}/messages/IPlcFieldRequest.cs     |    0
 .../api/{ => api}/messages/IPlcFieldResponse.cs    |    0
 .../plc4net/api/{ => api}/messages/IPlcMessage.cs  |    0
 .../api/{ => api}/messages/IPlcReadRequest.cs      |    0
 .../{ => api}/messages/IPlcReadRequestBuilder.cs   |    0
 .../api/{ => api}/messages/IPlcReadResponse.cs     |    0
 .../plc4net/api/{ => api}/messages/IPlcRequest.cs  |    0
 .../api/{ => api}/messages/IPlcRequestBuilder.cs   |    0
 .../plc4net/api/{ => api}/messages/IPlcResponse.cs |    0
 .../messages/IPlcSubscriptionEventArgs.cs          |    0
 .../{ => api}/messages/IPlcSubscriptionRequest.cs  |    0
 .../messages/IPlcSubscriptionRequestBuilder.cs     |    0
 .../{ => api}/messages/IPlcSubscriptionResponse.cs |    0
 .../messages/IPlcUnsubscriptionRequest.cs          |    0
 .../messages/IPlcUnsubscriptionRequestBuilder.cs   |    0
 .../messages/IPlcUnsubscriptionResponse.cs         |    0
 .../api/{ => api}/messages/IPlcWriteRequest.cs     |    0
 .../{ => api}/messages/IPlcWriteRequestBuilder.cs  |    0
 sandbox/plc4net/api/{ => api}/model/IPlcField.cs   |    0
 .../api/{ => api}/model/IPlcSubscriptionHandle.cs  |    0
 .../plc4net/api/{ => api}/types/PlcResponseCode.cs |    0
 sandbox/plc4net/api/api/value/IPlcValue.cs         |   68 +
 .../plc4net/api/{api.csproj => plc4net-api.csproj} |   14 +-
 .../knxnetip/readwrite/model/KnxDatapoint.cs       | 3955 ++++++++++++++++++++
 .../knxnetip/ParserSerializerTestsuite.xml         |  500 +++
 .../knxnetip/plc4net-driver-knxproj.csproj}        |   11 +-
 sandbox/plc4net/plc4net.sln                        |   34 +-
 sandbox/plc4net/pom.xml                            |  102 +-
 .../{api/api.csproj => spi/plc4net-spi.csproj}     |   22 +-
 sandbox/plc4net/spi/spi/generation/ReadBuffer.cs   |  203 +
 sandbox/plc4net/spi/spi/generation/WriteBuffer.cs  |   89 +
 sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs    |   33 +
 sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs    |   32 +
 .../plc4net/spi/spi/model/values/PlcBitString.cs   |    7 +
 sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs    |   33 +
 sandbox/plc4net/spi/spi/model/values/PlcDATE.cs    |   34 +
 .../spi/spi/model/values/PlcDATE_AND_TIME.cs       |   33 +
 sandbox/plc4net/spi/spi/model/values/PlcDINT.cs    |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs   |   33 +
 sandbox/plc4net/spi/spi/model/values/PlcINT.cs     |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcLINT.cs    |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcLREAL.cs   |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs   |   34 +
 sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs   |   33 +
 sandbox/plc4net/spi/spi/model/values/PlcNULL.cs    |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs |   34 +
 sandbox/plc4net/spi/spi/model/values/PlcREAL.cs    |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcSINT.cs    |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs  |   33 +
 .../model/values/PlcSimpleNumericValueAdapter.cs   |  175 +
 .../spi/spi/model/values/PlcSimpleValueAdapter.cs  |   17 +
 sandbox/plc4net/spi/spi/model/values/PlcStruct.cs  |   37 +
 .../spi/spi/model/values/PlcTIME _OF_DAY.cs        |   34 +
 sandbox/plc4net/spi/spi/model/values/PlcTIME.cs    |   34 +
 sandbox/plc4net/spi/spi/model/values/PlcUDINT.cs   |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcUINT.cs    |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcULINT.cs   |   30 +
 sandbox/plc4net/spi/spi/model/values/PlcUSINT.cs   |   30 +
 .../spi/spi/model/values/PlcValueAdapter.cs        |  223 ++
 sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs   |   33 +
 sandbox/plc4net/spi/spi/model/values/PlcWORD.cs    |   33 +
 sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs |   33 +
 71 files changed, 7644 insertions(+), 47 deletions(-)

diff --git a/sandbox/plc4net/pom.xml b/build-utils/language-cs/pom.xml
similarity index 52%
copy from sandbox/plc4net/pom.xml
copy to build-utils/language-cs/pom.xml
index ab7bdb8..2a02405 100644
--- a/sandbox/plc4net/pom.xml
+++ b/build-utils/language-cs/pom.xml
@@ -22,25 +22,37 @@
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <groupId>org.apache.plc4x.sandbox</groupId>
-    <artifactId>plc4x-sandbox</artifactId>
-    <version>0.10.0-SNAPSHOT</version>
+    <groupId>org.apache.plc4x</groupId>
+    <artifactId>plc4x-build-utils</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
   </parent>
 
-  <artifactId>plc4net</artifactId>
-  <packaging>pom</packaging>
-
-  <name>Sandbox: PLC4Net</name>
-  <description>Implementation of the protocol adapters for usage as .Net module.</description>
-
-  <!-- Disabled for now as C# support is currently not installed in Apache SonarQube -->
-  <!--properties>
-    <sonar.language>c#</sonar.language>
-  </properties-->
-
-  <modules>
-    <module>api</module>
-    <module>plc4net.driver</module>
-  </modules>
+  <artifactId>plc4x-build-utils-language-cs</artifactId>
+
+  <name>PLC4X: Build Utils: Language: C#</name>
+  <description>Code generation template for generating C# code</description>
+
+  <dependencies>
+    <!-- We are using the Freemarker module to generate Java code -->
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-language-base-freemarker</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x.plugins</groupId>
+      <artifactId>plc4x-code-generation-types-base</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.freemarker</groupId>
+      <artifactId>freemarker</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-text</artifactId>
+    </dependency>
+  </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
new file mode 100644
index 0000000..fc5a489
--- /dev/null
+++ b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
@@ -0,0 +1,72 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.language.cs;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageOutput;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageTemplateHelper;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class CsLanguageOutput extends FreemarkerLanguageOutput {
+
+    @Override
+    public String getName() {
+        return "C#";
+    }
+
+    @Override
+    public List<String> supportedOutputFlavors() {
+        return Arrays.asList("read-write", "read-only", "passive");
+    }
+
+    @Override
+    protected List<Template> getSpecTemplates(Configuration freemarkerConfiguration) throws IOException {
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected List<Template> getComplexTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected List<Template> getEnumTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected List<Template> getDataIoTemplates(Configuration freemarkerConfiguration) throws IOException {
+        return Collections.singletonList(
+            freemarkerConfiguration.getTemplate("templates/cs/data-io-template.ftlh"));
+    }
+
+    @Override
+    protected FreemarkerLanguageTemplateHelper getHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+        return new CsLanguageTemplateHelper(thisType, protocolName, flavorName, types);
+    }
+
+}
diff --git a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
new file mode 100644
index 0000000..223654d
--- /dev/null
+++ b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
@@ -0,0 +1,1053 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.language.cs;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.BaseFreemarkerLanguageTemplateHelper;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
+import org.apache.plc4x.plugins.codegenerator.types.enums.EnumValue;
+import org.apache.plc4x.plugins.codegenerator.types.fields.*;
+import org.apache.plc4x.plugins.codegenerator.types.references.*;
+import org.apache.plc4x.plugins.codegenerator.types.terms.*;
+
+import java.util.*;
+
+@SuppressWarnings({"unused", "WeakerAccess"})
+public class CsLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelper {
+
+    public CsLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+        super(thisType, protocolName, flavorName, types);
+    }
+
+    public String fileName(String protocolName, String languageName, String languageFlavorName) {
+        return String.join("", protocolName.split("\\-")) + "." +
+            String.join("", languageFlavorName.split("\\-"));
+    }
+
+    public String packageName(String languageFlavorName) {
+        return String.join("", languageFlavorName.split("\\-"));
+    }
+
+    @Override
+    public String getLanguageTypeNameForField(Field field) {
+        boolean optional = field instanceof OptionalField;
+        // If the referenced type is a DataIo type, the value is of type PlcValue.
+        if(field instanceof PropertyField) {
+            PropertyField propertyField = (PropertyField) field;
+            if(propertyField.getType() instanceof ComplexTypeReference) {
+                ComplexTypeReference complexTypeReference = (ComplexTypeReference) propertyField.getType();
+                final TypeDefinition typeDefinition = getTypeDefinitions().get(complexTypeReference.getName());
+                if(typeDefinition instanceof DataIoTypeDefinition) {
+                    return "PlcValue";
+                }
+            }
+        }
+        return getLanguageTypeNameForTypeReference(((TypedField) field).getType());
+    }
+
+    @Override
+    public String getLanguageTypeNameForTypeReference(TypeReference typeReference) {
+        if(typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case BIT: {
+                    return "bool";
+                }
+                case UINT: {
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 8) {
+                        return "byte";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 16) {
+                        return "ushort";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "uint";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 64) {
+                        return "ulong";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case INT: {
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 8) {
+                        return "sbyte";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 16) {
+                        return "short";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "int";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 64) {
+                        return "long";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case FLOAT:
+                case UFLOAT: {
+                    FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                    int sizeInBits = ((floatTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) ? 1 : 0) +
+                        floatTypeReference.getExponent() + floatTypeReference.getMantissa();
+                    if (sizeInBits <= 32) {
+                        return "float";
+                    }
+                    if (sizeInBits <= 64) {
+                        return "double";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case STRING: {
+                    return "string";
+                }
+                case TIME: {
+                    return "time";
+                }
+                case DATE: {
+                    return "date";
+                }
+                case DATETIME: {
+                    return "datetime2";
+                }
+            }
+            throw new RuntimeException("Unsupported simple type");
+        } else {
+            return (typeReference != null) ? ((ComplexTypeReference) typeReference).getName() : "";
+        }
+    }
+
+    public String getPlcValueTypeForTypeReference(TypeReference typeReference) {
+        if(typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case BIT: {
+                    return "PlcBOOL";
+                }
+                case UINT: {
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 8) {
+                        return "PlcUSINT";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 16) {
+                        return "PlcUINT";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "PlcUDINT";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 64) {
+                        return "PlcULINT";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case INT: {
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 8) {
+                        return "PlcSINT";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 16) {
+                        return "PlcINT";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "PlcDINT";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 64) {
+                        return "PlcLINT";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case FLOAT:
+                case UFLOAT: {
+                    FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                    int sizeInBits = ((floatTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) ? 1 : 0) +
+                        floatTypeReference.getExponent() + floatTypeReference.getMantissa();
+                    if (sizeInBits <= 32) {
+                        return "PlcREAL";
+                    }
+                    if (sizeInBits <= 64) {
+                        return "PlcLREAL";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case STRING: {
+                    return "PlcSTRING";
+                }
+                case TIME: {
+                    return "PlcTIME";
+                }
+                case DATE: {
+                    return "PlcDATE";
+                }
+                case DATETIME: {
+                    return "PlcDATE_AND_TIME";
+                }
+            }
+            throw new RuntimeException("Unsupported simple type");
+        } else {
+            return (typeReference != null) ? ((ComplexTypeReference) typeReference).getName() : "";
+        }
+    }
+
+    @Override
+    public String getNullValueForTypeReference(TypeReference typeReference) {
+        if(typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case BIT: {
+                    return "false";
+                }
+                case UINT:
+                case INT: {
+                    return "0";
+                }
+                case FLOAT: {
+                    return "0.0";
+                }
+                case STRING: {
+                    return "\"\"";
+                }
+            }
+        } else if(typeReference instanceof ComplexTypeReference) {
+            return "0";
+        }
+        return "null";
+    }
+
+    public int getNumBits(SimpleTypeReference simpleTypeReference) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT: {
+                return 1;
+            }
+            case UINT:
+            case INT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                return integerTypeReference.getSizeInBits();
+            }
+            case FLOAT: {
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                return floatTypeReference.getSizeInBits();
+            }
+            case STRING: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                return integerTypeReference.getSizeInBits();
+            }
+            default: {
+                return 0;
+            }
+        }
+    }
+
+    public String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference, String valueString) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT: {
+                return "io.ReadBit()";
+            }
+            case UINT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "io.ReadByte(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "io.ReadUshort(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "io.ReadUint(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "io.ReadUlong(" + integerTypeReference.getSizeInBits() + ")";
+                }
+            }
+            case INT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "io.ReadSbyte(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "io.ReadShort(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "io.ReadInt(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "io.ReadLong(" + integerTypeReference.getSizeInBits() + ")";
+                }
+            }
+            case FLOAT: {
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                if (floatTypeReference.getSizeInBits() <= 32) {
+                    return "io.ReadFloat(true, " + floatTypeReference.getExponent() + ", " + floatTypeReference.getMantissa() + ")";
+                }
+                if (floatTypeReference.getSizeInBits() <= 64) {
+                    return "io.ReadDouble(true, " + floatTypeReference.getExponent() + ", " + floatTypeReference.getMantissa() + ")";
+                }
+            }
+            case STRING: {
+                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
+                return "io.ReadString(" + stringTypeReference.getSizeInBits() + ")";
+            }
+        }
+        return "Hurz";
+    }
+
+    @Override
+    public String getWriteBufferWriteMethodCall(SimpleTypeReference simpleTypeReference, String fieldName) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT: {
+                return "io.WriteBit(" + fieldName + ")";
+            }
+            case UINT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "io.WriteByte(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "io.WriteUshort(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "io.WriteUint(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "io.WriteUlong(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+            }
+            case INT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "io.WriteSbyte(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "io.WriteShort(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "io.WriteInt(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "io.WriteLong(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+            }
+            case FLOAT:
+            case UFLOAT: {
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                if (floatTypeReference.getSizeInBits() <= 32) {
+                    return "io.WriteFloat(" + floatTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+                if (floatTypeReference.getSizeInBits() <= 64) {
+                    return "io.WriteDouble(" + floatTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                }
+            }
+            case STRING: {
+                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
+                String encoding = ((stringTypeReference.getEncoding() != null) && (stringTypeReference.getEncoding().length() > 2)) ?
+                    stringTypeReference.getEncoding().substring(1, stringTypeReference.getEncoding().length() - 1) : "UTF-8";
+                return "io.WriteString(" + stringTypeReference.getSizeInBits() + ", \"" +
+                    encoding + "\", " + fieldName + ")";
+            }
+        }
+        return "Hurz";
+    }
+
+    public String getReservedValue(ReservedField reservedField) {
+        final String languageTypeName = getLanguageTypeNameForTypeReference(reservedField.getType());
+        return reservedField.getReferenceValue().toString();
+    }
+
+    public String toParseExpression(TypedField field, Term term, Argument[] parserArguments) {
+        return toTypedParseExpression((field != null) ? field.getType() : null, term, parserArguments);
+    }
+
+    public String toSerializationExpression(TypedField field, Term term, Argument[] serializerArguments) {
+        return toTypedSerializationExpression((field != null) ? field.getType() : null, term, serializerArguments);
+    }
+
+    public String toBooleanParseExpression(Term term, Argument[] parserArguments) {
+        return toTypedParseExpression(new DefaultBooleanTypeReference(), term, parserArguments);
+    }
+
+    public String toBooleanSerializationExpression(Term term, Argument[] serializerArguments) {
+        return toTypedSerializationExpression(new DefaultBooleanTypeReference(), term, serializerArguments);
+    }
+
+    public String toIntegerParseExpression(int sizeInBits, Term term, Argument[] parserArguments) {
+        return toTypedParseExpression(new DefaultIntegerTypeReference(SimpleTypeReference.SimpleBaseType.UINT, sizeInBits), term, parserArguments);
+    }
+
+    public String toIntegerSerializationExpression(int sizeInBits, Term term, Argument[] serializerArguments) {
+        return toTypedSerializationExpression(new DefaultIntegerTypeReference(SimpleTypeReference.SimpleBaseType.UINT, sizeInBits), term, serializerArguments);
+    }
+
+    public String toTypedParseExpression(TypeReference fieldType, Term term, Argument[] parserArguments) {
+        return toExpression(fieldType, term, parserArguments, null, false, false);
+    }
+
+    public String toTypedSerializationExpression(TypeReference fieldType, Term term, Argument[] serializerArguments) {
+        return toExpression(fieldType, term, null, serializerArguments, true, false);
+    }
+
+    String getCastExpressionForTypeReference(TypeReference typeReference) {
+        if(typeReference instanceof SimpleTypeReference) {
+            return getLanguageTypeNameForTypeReference(typeReference);
+        } else if(typeReference != null) {
+            return "Cast" + getLanguageTypeNameForTypeReference(typeReference);
+        } else {
+            return "";
+        }
+    }
+
+    private String toExpression(TypeReference fieldType, Term term, Argument[] parserArguments, Argument[] serializerArguments, boolean serialize, boolean suppressPointerAccess) {
+        if(term == null) {
+            return "";
+        }
+        if(term instanceof Literal) {
+            if(term instanceof NullLiteral) {
+                return "nil";
+            } else if(term instanceof BooleanLiteral) {
+                return getCastExpressionForTypeReference(fieldType) + "(" + ((BooleanLiteral) term).getValue() + ")";
+            } else if(term instanceof NumericLiteral) {
+                return getCastExpressionForTypeReference(fieldType) + "(" + ((NumericLiteral) term).getNumber().toString() + ")";
+            } else if(term instanceof StringLiteral) {
+                return "\"" + ((StringLiteral) term).getValue() + "\"";
+            } else if(term instanceof VariableLiteral) {
+                return toVariableExpression(fieldType, (VariableLiteral) term, parserArguments, serializerArguments, serialize, suppressPointerAccess);
+            } else {
+                throw new RuntimeException("Unsupported Literal type " + term.getClass().getName());
+            }
+        } else if (term instanceof UnaryTerm) {
+            UnaryTerm ut = (UnaryTerm) term;
+            Term a = ut.getA();
+            switch(ut.getOperation()) {
+                case "!":
+                    return "!(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + ")";
+                case "-":
+                    return "-(" + getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + "))";
+                case "()":
+                    return getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + ")";
+                default:
+                    throw new RuntimeException("Unsupported unary operation type " + ut.getOperation());
+            }
+        } else if (term instanceof BinaryTerm) {
+            BinaryTerm bt = (BinaryTerm) term;
+            Term a = bt.getA();
+            Term b = bt.getB();
+            String operation = bt.getOperation();
+            switch (operation) {
+                case "^":
+                    return "Math.pow(" +
+                        getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + "), " +
+                        getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, b, parserArguments, serializerArguments, serialize, false) + "))";
+                // If we start casting for comparisons, equals or non equals, really messy things happen.
+                case "==":
+                case "!=":
+                case ">":
+                case "<":
+                case ">=":
+                case "<=":
+                    // For every access of optional elements we need pointer access ...
+                    // Except for doing a nil or not-nil check :-(
+                    // So in case of such a check, we need to suppress the pointer-access.
+                    boolean suppressPointerAccessOverride = (operation.equals("==") || operation.equals("!=")) && ((a instanceof NullLiteral) || (b instanceof NullLiteral));
+                    return "bool((" + toExpression(null, a, parserArguments, serializerArguments, serialize, suppressPointerAccessOverride) + ") " +
+                        operation +
+                        " (" + toExpression(null, b, parserArguments, serializerArguments, serialize, suppressPointerAccessOverride) + "))";
+                default:
+                    return getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + ") " +
+                        operation + " " +
+                        getCastExpressionForTypeReference(fieldType) +"(" + toExpression(fieldType, b, parserArguments, serializerArguments, serialize, false) + ")";
+            }
+        } else if (term instanceof TernaryTerm) {
+            TernaryTerm tt = (TernaryTerm) term;
+            if ("if".equals(tt.getOperation())) {
+                Term a = tt.getA();
+                Term b = tt.getB();
+                Term c = tt.getC();
+                // TODO: This is not quite correct with the cast to uint16
+                return "utils.InlineIf(" + toExpression(new DefaultBooleanTypeReference(), a, parserArguments, serializerArguments, serialize, false) + ", " +
+                    "uint16(" + toExpression(fieldType, b, parserArguments, serializerArguments, serialize, false) + "), " +
+                    "uint16(" + toExpression(fieldType, c, parserArguments, serializerArguments, serialize, false) + "))";
+            } else {
+                throw new RuntimeException("Unsupported ternary operation type " + tt.getOperation());
+            }
+        } else {
+            throw new RuntimeException("Unsupported Term type " + term.getClass().getName());
+        }
+    }
+
+    private String toVariableExpression(TypeReference typeReference, VariableLiteral vl, Argument[] parserArguments, Argument[] serializerArguments, boolean serialize, boolean suppressPointerAccess) {
+        if ("lengthInBytes".equals(vl.getName())) {
+            return (serialize ? getCastExpressionForTypeReference(typeReference) + "(m." : "") + "LengthInBytes()" + (serialize ? ")" : "");
+        } else if ("lengthInBits".equals(vl.getName())) {
+            return (serialize ? getCastExpressionForTypeReference(typeReference) + "(m." : "") + "LengthInBits()" + (serialize ? ")" : "");
+        }
+        // If this literal references an Enum type, then we have to output it differently.
+        else if (getTypeDefinitions().get(vl.getName()) instanceof EnumTypeDefinition) {
+            return vl.getName() + "_" + vl.getChild().getName() +
+                ((vl.getChild().getChild() != null) ?
+                    "." + toVariableExpression(typeReference, vl.getChild().getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
+        }
+        // If we are accessing enum constants, these also need to be output differently.
+        else if ((getFieldForNameFromCurrent(vl.getName()) instanceof EnumField) && (vl.getChild() != null)) {
+            return vl.getName() + "." + StringUtils.capitalize(vl.getChild().getName()) + "()" +
+                ((vl.getChild().getChild() != null) ?
+                    "." + toVariableExpression(typeReference, vl.getChild().getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
+        }
+        // If we are accessing optional fields of simple type, we need to use pointer-access.
+        else if (!serialize && (getFieldForNameFromCurrent(vl.getName()) instanceof OptionalField) &&
+            (((OptionalField) getFieldForNameFromCurrent(vl.getName())).getType() instanceof SimpleTypeReference)) {
+            return "(*" + vl.getName() + ")" +
+                ((vl.getChild() != null) ?
+                    "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, serialize, suppressPointerAccess) : "");
+        }
+        // CAST expressions are special as we need to add a ".class" to the second parameter in Java.
+        else if ("CAST".equals(vl.getName())) {
+            if ((vl.getArgs() == null) || (vl.getArgs().size() != 2)) {
+                throw new RuntimeException("A CAST expression expects exactly two arguments.");
+            }
+            VariableLiteral typeLiteral = (VariableLiteral) vl.getArgs().get(1);
+            final TypeDefinition typeDefinition = getTypeDefinitions().get(typeLiteral.getName());
+            TypeReference type = typeDefinition.getTypeReference();
+            StringBuilder sb = new StringBuilder();
+            if (type instanceof ComplexTypeReference) {
+                sb.append("Cast");
+            }
+            sb.append(typeLiteral.getName());
+            sb.append("(").append(toVariableExpression(typeReference, (VariableLiteral) vl.getArgs().get(0), parserArguments, serializerArguments, serialize, suppressPointerAccess)).append(")");
+            return sb.toString() + ((vl.getChild() != null) ? "." + StringUtils.capitalize(toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess)) : "");
+        } else if ("STATIC_CALL".equals(vl.getName())) {
+            StringBuilder sb = new StringBuilder();
+            if (!(vl.getArgs().get(0) instanceof StringLiteral)) {
+                throw new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral");
+            }
+            // Get the class and method name
+            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) {
+                    sb.append(", ");
+                }
+                if (arg instanceof VariableLiteral) {
+                    VariableLiteral va = (VariableLiteral) arg;
+                    // "io" is the default name of the reader argument which is always available.
+                    boolean isParserArg = "io".equals(va.getName()) || ((getThisTypeDefinition() instanceof DataIoTypeDefinition) && "_value".equals(va.getName()));
+                    boolean isTypeArg = "_type".equals(va.getName());
+                    if (!isParserArg && !isTypeArg && parserArguments != null) {
+                        for (Argument parserArgument : parserArguments) {
+                            if (parserArgument.getName().equals(va.getName())) {
+                                isParserArg = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (isParserArg) {
+                        if(va.getName().equals("_value")) {
+                            sb.append(va.getName().substring(1) + ((va.getChild() != null) ?
+                                "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : ""));
+                        } else {
+                            sb.append(va.getName() + ((va.getChild() != null) ?
+                                "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : ""));
+                        }
+                    }
+                    // We have to manually evaluate the type information at code-generation time.
+                    else if (isTypeArg) {
+                        String part = va.getChild().getName();
+                        switch (part) {
+                            case "name":
+//                                sb.append("\"").append(field.getTypeName()).append("\"");
+                                break;
+                            case "length":
+                                sb.append("\"").append(((SimpleTypeReference) typeReference).getSizeInBits()).append("\"");
+                                break;
+                            case "encoding":
+                                String encoding = ((StringTypeReference) typeReference).getEncoding();
+                                // Cut off the single quotes.
+                                encoding = encoding.substring(1, encoding.length() - 1);
+                                sb.append("\"").append(encoding).append("\"");
+                                break;
+                        }
+                    } else {
+                        sb.append(toVariableExpression(typeReference, va, parserArguments, serializerArguments, serialize, suppressPointerAccess));
+                    }
+                } else if (arg instanceof StringLiteral) {
+                    sb.append(((StringLiteral) arg).getValue());
+                }
+            }
+            sb.append(")");
+            return sb.toString();
+        } else if ("COUNT".equals(vl.getName())) {
+            return (typeReference instanceof SimpleTypeReference ? getCastExpressionForTypeReference(typeReference) : "") + "(len(" +
+                toVariableExpression(typeReference, (VariableLiteral) vl.getArgs().get(0), parserArguments, serializerArguments, serialize, suppressPointerAccess) +
+                "))";
+        } else if ("ARRAY_SIZE_IN_BYTES".equals(vl.getName())) {
+            VariableLiteral va = (VariableLiteral) vl.getArgs().get(0);
+            // "io" and "m" are always available in every parser.
+            boolean isSerializerArg = "io".equals(va.getName()) || "m".equals(va.getName()) || "element".equals(va.getName());
+            if (!isSerializerArg && serializerArguments != null) {
+                for (Argument serializerArgument : serializerArguments) {
+                    if (serializerArgument.getName().equals(va.getName())) {
+                        isSerializerArg = true;
+                        break;
+                    }
+                }
+            }
+            StringBuilder sb = new StringBuilder();
+            if (isSerializerArg) {
+                sb.append(va.getName()).append(((va.getChild() != null) ? "." + toVariableExpression(typeReference, va.getChild(), parserArguments, serializerArguments, true, suppressPointerAccess) : ""));
+            } else {
+                sb.append(toVariableExpression(typeReference, va, parserArguments, serializerArguments, true, suppressPointerAccess));
+            }
+            return getCastExpressionForTypeReference(typeReference) + "(" + ((VariableLiteral) vl.getArgs().get(0)).getName() + "ArraySizeInBytes(" + sb.toString() + "))";
+        }
+        else if("CEIL".equals(vl.getName())) {
+            Term va = vl.getArgs().get(0);
+            // The Ceil function expects 64 bit floating point values.
+            TypeReference tr = new DefaultFloatTypeReference(SimpleTypeReference.SimpleBaseType.FLOAT, 11, 52);
+            return "math.Ceil(" + toExpression(tr, va, parserArguments, serializerArguments, serialize, suppressPointerAccess) + ")";
+        }
+        // All uppercase names are not fields, but utility methods.
+        else if (vl.getName().equals(vl.getName().toUpperCase())) {
+            StringBuilder sb = new StringBuilder(vl.getName());
+            if (vl.getArgs() != null) {
+                sb.append("(");
+                boolean firstArg = true;
+                for (Term arg : vl.getArgs()) {
+                    if (!firstArg) {
+                        sb.append(", ");
+                    }
+                    sb.append(toExpression(typeReference, arg, parserArguments, serializerArguments, serialize, suppressPointerAccess));
+                    firstArg = false;
+                }
+                sb.append(")");
+            }
+            if (vl.getIndex() != VariableLiteral.NO_INDEX) {
+                sb.append("[").append(vl.getIndex()).append("]");
+            }
+            return sb.toString() + ((vl.getChild() != null) ?
+                "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
+        }
+        // If the current property references a discriminator value, we have to serialize it differently.
+        else if ((getFieldForNameFromCurrentOrParent(vl.getName()) != null) && (getFieldForNameFromCurrentOrParent(vl.getName()) instanceof DiscriminatorField)) {
+            final DiscriminatorField discriminatorField = (DiscriminatorField) getFieldForNameFromCurrentOrParent(vl.getName());
+            System.out.println(discriminatorField);
+        }
+        // If the current property references a parserArguments property and that is a discriminator property, we also have to serialize it differently..
+        else if ((vl.getChild() != null) && (getTypeReferenceForProperty(((ComplexTypeDefinition) getThisTypeDefinition()), vl.getName()) != null)) {
+            final Optional<TypeReference> typeReferenceForProperty = getTypeReferenceForProperty(((ComplexTypeDefinition) getThisTypeDefinition()), vl.getName());
+            if(typeReferenceForProperty.isPresent() && typeReferenceForProperty.get() instanceof ComplexTypeReference) {
+                final TypeReference complexTypeReference = typeReferenceForProperty.get();
+                TypeDefinition typeDefinition = getTypeDefinitionForTypeReference(complexTypeReference);
+                if(typeDefinition instanceof ComplexTypeDefinition) {
+                    ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) typeDefinition;
+                    String childProperty = vl.getChild().getName();
+                    final Optional<Field> matchingDiscriminatorField = complexTypeDefinition.getFields().stream().filter(field -> (field instanceof DiscriminatorField) && ((DiscriminatorField) field).getName().equals(childProperty)).findFirst();
+                    if(matchingDiscriminatorField.isPresent()) {
+                        return "Cast" + getLanguageTypeNameForTypeReference(complexTypeReference) + "(" + vl.getName() + ")." + StringUtils.capitalize(childProperty) + "()";
+                    }
+                }
+            }
+        }
+        // If the current term references a serialization argument, handle it differently (don't prefix it with "m.")
+        else if((serializerArguments != null) && Arrays.stream(serializerArguments).anyMatch(argument -> argument.getName().equals(vl.getName()))) {
+            return vl.getName() + ((vl.getChild() != null) ?
+                "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
+        }
+        return (serialize ? "m." + StringUtils.capitalize(vl.getName()) : vl.getName()) + ((vl.getChild() != null) ?
+            "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
+    }
+
+    public String getSizeInBits(ComplexTypeDefinition complexTypeDefinition, Argument[] parserArguments) {
+        int sizeInBits = 0;
+        StringBuilder sb = new StringBuilder("");
+        for (Field field : complexTypeDefinition.getFields()) {
+            if(field instanceof ArrayField) {
+                ArrayField arrayField = (ArrayField) field;
+                final SimpleTypeReference type = (SimpleTypeReference) arrayField.getType();
+                switch (arrayField.getLoopType()) {
+                    case COUNT:
+                        sb.append("(").append(toTypedSerializationExpression(type, arrayField.getLoopExpression(), parserArguments)).append(" * ").append(type.getSizeInBits()).append(") + ");
+                        break;
+                    case LENGTH:
+                        sb.append("(").append(toTypedSerializationExpression(type, arrayField.getLoopExpression(), parserArguments)).append(" * 8) + ");
+                        break;
+                    case TERMINATED:
+                        // No terminated.
+                        break;
+                }
+            } else if(field instanceof TypedField) {
+                TypedField typedField = (TypedField) field;
+                final TypeReference type = typedField.getType();
+                if(field instanceof ManualField) {
+                    ManualField manualField = (ManualField) field;
+                    sb.append("(").append(toSerializationExpression(manualField, manualField.getLengthExpression(), parserArguments)).append(") + ");
+                }
+                else if(type instanceof SimpleTypeReference) {
+                    SimpleTypeReference simpleTypeReference = (SimpleTypeReference) type;
+                    sizeInBits += simpleTypeReference.getSizeInBits();
+                } else {
+                    // No ComplexTypeReference supported.
+                }
+            }
+        }
+        return sb.toString() + sizeInBits;
+    }
+
+    public String escapeValue(TypeReference typeReference, String valueString) {
+        if(valueString == null) {
+            return null;
+        }
+        if(typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case UINT:
+                case INT:
+                    // If it's a one character string and is numeric, output it as char.
+                    if(!NumberUtils.isParsable(valueString) && (valueString.length() == 1)) {
+                        return "'" + valueString + "'";
+                    }
+                    break;
+                case STRING:
+                    return "\"" + valueString + "\"";
+            }
+        }
+        return valueString;
+    }
+
+    public String escapeEnumValue(TypeReference typeReference, String valueString) {
+        // Currently the only case in which here complex type references are used are when referencing enum constants.
+        if (typeReference instanceof ComplexTypeReference) {
+            // C doesn't like NULL values for enums, so we have to return something else (we'll treat -1 as NULL)
+            if ("null".equals(valueString)) {
+                return "0";
+            }
+            String typeName = valueString.substring(0, valueString.indexOf('.'));
+            String constantName = valueString.substring(valueString.indexOf('.') + 1);
+            return typeName + "_" + constantName;
+        } else {
+            return escapeValue(typeReference, valueString);
+        }
+    }
+
+    public Collection<EnumValue> getUniqueEnumValues(EnumValue[] enumValues) {
+        Map<String, EnumValue> filteredEnumValues = new TreeMap<>();
+        for (EnumValue enumValue : enumValues) {
+            if (!filteredEnumValues.containsKey(enumValue.getValue())) {
+                filteredEnumValues.put(enumValue.getValue(), enumValue);
+            }
+        }
+        return filteredEnumValues.values();
+    }
+
+    public List<String> getRequiredImports() {
+        ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) getThisTypeDefinition();
+        List<String> imports = new ArrayList<>();
+
+        if(complexTypeDefinition.getAllPropertyFields().stream().anyMatch(field -> isArrayField(field) && getLanguageTypeNameForField(field).equals("int8"))) {
+            imports.add("\"encoding/base64\"");
+        }
+
+        imports.add("\"encoding/xml\"");
+
+        // For "Fields with complex type", constant, typeSwitch,  fields: "errors"
+        if(!complexTypeDefinition.getFields().isEmpty()) {
+            imports.add("\"errors\"");
+        }
+
+        imports.add("\"io\"");
+
+        // At least one reserved field or simple field with complex type
+        if(complexTypeDefinition.getFields().stream().anyMatch(field ->
+            (field instanceof ReservedField))) {
+            imports.add("log \"github.com/sirupsen/logrus\"");
+        }
+
+        // For CEIL functions: "math"
+/*        if(complexTypeDefinition.getFields().stream().anyMatch(field ->
+            FieldUtils.contains(field, "CEIL"))) {
+            imports.add("\"math\"");
+        }*/
+
+        imports.add("\"github.com/apache/plc4x/plc4go/internal/plc4go/utils\"");
+
+        // For Constant field: "strconv"
+        if(complexTypeDefinition.getFields().stream().anyMatch(field ->
+            (field instanceof ConstField))/* || complexTypeDefinition.getAllPropertyFields().stream().anyMatch(
+                propertyField -> isSimpleField(propertyField))*/) {
+            imports.add("\"strconv\"");
+        }
+
+        if(isDiscriminatedParentTypeDefinition()) {
+            imports.add("\"reflect\"");
+            imports.add("\"strings\"");
+        }
+
+        return imports;
+    }
+
+    public List<String> getRequiredImportsForDataIo() {
+        DataIoTypeDefinition dataIo = (DataIoTypeDefinition) getThisTypeDefinition();
+
+        List<String> imports = new ArrayList<>();
+
+        imports.add("\"errors\"");
+        imports.add("\"github.com/apache/plc4x/plc4go/internal/plc4go/model/values\"");
+        imports.add("\"github.com/apache/plc4x/plc4go/internal/plc4go/utils\"");
+        imports.add("api \"github.com/apache/plc4x/plc4go/pkg/plc4go/values\"");
+
+        if(dataIo.getSwitchField().getCases().stream().anyMatch(typeCase ->
+            (typeCase.getName().equals("TIME_OF_DAY") && hasFieldsWithNames(typeCase.getFields(), "hour", "minutes", "seconds")) ||
+                (typeCase.getName().equals("DATE") && hasFieldsWithNames(typeCase.getFields(), "year", "month", "day")) ||
+                (typeCase.getName().equals("DATE_AND_TIME") && hasFieldsWithNames(typeCase.getFields(), "year", "month", "day", "hour", "minutes", "seconds")))) {
+            imports.add("\"time\"");
+        }
+        return imports;
+    }
+
+    public String getVariableName(Field field) {
+        if(!(field instanceof NamedField)) {
+            return "_";
+        }
+        NamedField namedField = (NamedField) field;
+
+        String name = null;
+        for (Field curField : ((ComplexTypeDefinition) getThisTypeDefinition()).getFields()) {
+            if(curField == field) {
+                name = namedField.getName();
+            } else if(name != null) {
+                if(curField instanceof ArrayField) {
+                    ArrayField arrayField = (ArrayField) curField;
+                    if(arrayField.getLoopExpression().contains(name)) {
+                        return name;
+                    }
+                } else if(curField instanceof ChecksumField) {
+                    ChecksumField checksumField = (ChecksumField) curField;
+                    if(checksumField.getChecksumExpression().contains(name)) {
+                        return name;
+                    }
+                } else if(curField instanceof ImplicitField) {
+                    ImplicitField implicitField = (ImplicitField) curField;
+                    if(implicitField.getSerializeExpression().contains(name)) {
+                        return name;
+                    }
+                } else if(curField instanceof ManualArrayField) {
+                    ManualArrayField manualArrayField = (ManualArrayField) curField;
+                    if(manualArrayField.getLengthExpression().contains(name)) {
+                        return name;
+                    }
+                    if(manualArrayField.getLoopExpression().contains(name)) {
+                        return name;
+                    }
+                    if(manualArrayField.getParseExpression().contains(name)) {
+                        return name;
+                    }
+                    if(manualArrayField.getSerializeExpression().contains(name)) {
+                        return name;
+                    }
+                } else if(curField instanceof ManualField) {
+                    ManualField manualField = (ManualField) curField;
+                    if(manualField.getLengthExpression().contains(name)) {
+                        return name;
+                    }
+                    if(manualField.getParseExpression().contains(name)) {
+                        return name;
+                    }
+                    if(manualField.getSerializeExpression().contains(name)) {
+                        return name;
+                    }
+                } else if(curField instanceof OptionalField) {
+                    OptionalField optionalField = (OptionalField) curField;
+                    if(optionalField.getConditionExpression().contains(name)) {
+                        return name;
+                    }
+                } else if(curField instanceof SwitchField) {
+                    SwitchField switchField = (SwitchField) curField;
+                    for (Term discriminatorExpression : switchField.getDiscriminatorExpressions()) {
+                        if(discriminatorExpression.contains(name)) {
+                            return name;
+                        }
+                    }
+                    for (DiscriminatedComplexTypeDefinition curCase : switchField.getCases()) {
+                        for (Argument parserArgument : curCase.getParserArguments()) {
+                            if(parserArgument.getName().equals(name)) {
+                                return name;
+                            }
+                        }
+                    }
+                } else if(curField instanceof VirtualField) {
+                    VirtualField virtualField = (VirtualField) curField;
+                    if(virtualField.getValueExpression().contains(name)) {
+                        return name;
+                    }
+                }
+                if(curField.getParams() != null) {
+                    for (Term param : curField.getParams()) {
+                        if(param.contains(name)) {
+                            return name;
+                        }
+                    }
+                }
+            }
+        }
+
+        return "_";
+    }
+
+    public boolean needsVariable(ArrayField field, String variableName, boolean serialization) {
+        if(!serialization) {
+            if (field.getLoopExpression().contains(variableName)) {
+                return true;
+            }
+        }
+        if((field.getParams() != null) && (field.getParams().length > 0)){
+            for (Term param : field.getParams()) {
+                if(param.contains(variableName)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Right now only the ARRAY_SIZE_IN_BYTES requires helpers to be generated.
+     * Also right now only the Modbus protocol requires this and here the referenced
+     * properties are all also members of the current complex type,
+     * so we'll simplify things here for now.
+     *
+     * @param functionName name of the
+     * @return
+     */
+    public Map<String, String> requiresHelperFunctions(String functionName) {
+        Map<String, String> result = new HashMap<>();
+        boolean usesFunction = false;
+        // As the ARRAY_SIZE_IN_BYTES only applies to ArrayFields, search for these
+        for (Field curField : ((ComplexTypeDefinition) getThisTypeDefinition()).getFields()) {
+            if(curField instanceof ArrayField) {
+                ArrayField arrayField = (ArrayField) curField;
+                if(arrayField.getLoopExpression().contains(functionName)) {
+                    usesFunction = true;
+                }
+                result.put(arrayField.getName(), getLanguageTypeNameForField(arrayField));
+            } else if(curField instanceof ImplicitField) {
+                ImplicitField implicitField = (ImplicitField) curField;
+                if(implicitField.getSerializeExpression().contains(functionName)) {
+                    usesFunction = true;
+                }
+            }
+        }
+        if(usesFunction) {
+            return result;
+        } else {
+            return Collections.emptyMap();
+        }
+    }
+
+    public boolean requiresStartPosAndCurPos() {
+        if(getThisTypeDefinition() instanceof ComplexTypeDefinition) {
+            for (Field curField : ((ComplexTypeDefinition) getThisTypeDefinition()).getFields()) {
+                if (requiresVariable(curField, "curPos")) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean requiresVariable(Field curField, String variable) {
+        if(curField instanceof ArrayField) {
+            ArrayField arrayField = (ArrayField) curField;
+            if(arrayField.getLoopExpression().contains(variable)) {
+                return true;
+            }
+        } else if(curField instanceof OptionalField) {
+            OptionalField optionalField = (OptionalField) curField;
+            if(optionalField.getConditionExpression().contains(variable)) {
+                return true;
+            }
+        }
+        if(curField.getParams() != null) {
+            for (Term paramTerm : curField.getParams()) {
+                if (paramTerm.contains(variable)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public Term findTerm(Term baseTerm, String name) {
+        if(baseTerm instanceof VariableLiteral) {
+            VariableLiteral variableLiteral = (VariableLiteral) baseTerm;
+            if(variableLiteral.getName().equals(name)) {
+                return variableLiteral;
+            }
+            if(variableLiteral.getChild() != null) {
+                Term found = findTerm(variableLiteral.getChild(), name);
+                if(found != null) {
+                    return found;
+                }
+            }
+            for (Term arg : variableLiteral.getArgs()) {
+                Term found = findTerm(arg, name);
+                if(found != null) {
+                    return found;
+                }
+            }
+        } else if(baseTerm instanceof UnaryTerm) {
+            UnaryTerm unaryTerm = (UnaryTerm) baseTerm;
+            Term found = findTerm(unaryTerm.getA(), name);
+            if(found != null) {
+                return found;
+            }
+        } else if(baseTerm instanceof BinaryTerm) {
+            BinaryTerm binaryTerm = (BinaryTerm) baseTerm;
+            Term found = findTerm(binaryTerm.getA(), name);
+            if(found != null) {
+                return found;
+            }
+            found = findTerm(binaryTerm.getB(), name);
+            if(found != null) {
+                return found;
+            }
+        } else if(baseTerm instanceof TernaryTerm) {
+            TernaryTerm ternaryTerm = (TernaryTerm) baseTerm;
+            Term found = findTerm(ternaryTerm.getA(), name);
+            if(found != null) {
+                return found;
+            }
+            found = findTerm(ternaryTerm.getB(), name);
+            if(found != null) {
+                return found;
+            }
+            found = findTerm(ternaryTerm.getC(), name);
+            if(found != null) {
+                return found;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/build-utils/language-cs/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput b/build-utils/language-cs/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput
new file mode 100644
index 0000000..eeaeac5
--- /dev/null
+++ b/build-utils/language-cs/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.plc4x.language.cs.CsLanguageOutput
diff --git a/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh b/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh
new file mode 100644
index 0000000..12aa63c
--- /dev/null
+++ b/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh
@@ -0,0 +1,206 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+<#-- Declare the name and type of variables declared locally inside the template -->
+<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
+<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
+<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
+<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
+<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
+<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
+<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
+<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
+<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
+<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
+<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
+<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
+<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
+<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
+<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
+<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/${type.name}.cs
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFlavor?replace("-", "")}.model
+{
+
+    public class ${type.name}
+    {
+
+        public IPlcValue Parse(ReadBuffer io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>)
+        {
+    <#list type.switchField.cases as case>
+            if (<#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">
+                var internalMap = new Dictionary<string, IPlcValue>();
+            <#assign valueDefined=true>
+        </#if>
+        <#list case.fields as field>
+            <#switch field.typeName>
+                <#case "array">
+                    <#assign arrayField = field>
+
+                // Array Field (${field.name});
+                var ${arrayField.name} = new List<IPlcValue>();
+                for (int i = 0; i < ${helper.toParseExpression(null, field.loopExpression, type.parserArguments)}; i++) {
+                    var internalItem = <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>Complex type array in data-io parsing currently not implemented</#if>;
+                    ${field.name}.Add(new ${helper.getPlcValueTypeForTypeReference(field.type)}(internalItem));
+                }
+                    <#if field.name == "value">
+                        <#assign valueDefined=true>
+                    </#if>
+                    <#break>
+                <#case "manual">
+                    <#assign manualArrayField = field>
+
+                // Manual Field (${field.name})
+                var ${field.name} = ${helper.toParseExpression(field, field.parseExpression, type.parserArguments)};
+                    <#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>
+
+                // Simple Field (${field.name})
+                var ${field.name} = <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}Parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>;
+                    <#if case.name == "Struct">
+                internalMap["${case.name}"] = new ${helper.getPlcValueTypeForTypeReference(field.type)}(${field.name});
+                    </#if>
+                    <#assign valueDefined=true>
+                    <#break>
+            </#switch>
+        </#list>
+        <#if valueDefined>
+
+            <#switch case.name>
+                <#case "TIME_OF_DAY">
+                    <#if helper.hasFieldsWithNames(case.fields, "hour", "minutes", "seconds")>
+                var value = new DateTime(0,0,0, hour, minutes, seconds);
+                    </#if>
+                return new PlcTIME_OF_DAY(value);
+                    <#break>
+                <#case "DATE">
+                    <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day")>
+                var value = new DateTime(year, month, day, 0, 0, 0);
+                    </#if>
+                return new PlcDATE(value);
+                    <#break>
+                <#case "DATE_AND_TIME">
+                    <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds")>
+                var value = new DateTime(year, month, day, hour, minutes, seconds);
+                    </#if>
+                return new PlcDATE_AND_TIME(value);
+                    <#break>
+                <#case "Struct">
+                return new PlcStruct(internalMap);
+                    <#break>
+                <#case "List">
+                return new PlcList(value);
+                    <#break>
+                <#default>
+                return new Plc${case.name}(value);
+            </#switch>
+        </#if>
+            } <#sep>else
+    </#list>
+
+            return null;
+        }
+
+        public void Serialize(WriteBuffer io, IPlcValue value<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>)
+        {
+    <#list type.switchField.cases as case>
+            if (<#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}
+        <#list case.fields as field>
+            <#switch field.typeName>
+                <#case "array">
+                    <#assign arrayField = field>
+
+                // Array Field (${field.name})
+                for (int i = 0; i < ${helper.toSerializationExpression(null, field.loopExpression, type.parserArguments)}; i++) {
+                    <#if helper.isSimpleTypeReference(arrayField.type)>${helper.getWriteBufferWriteMethodCall(arrayField.type, arrayField.name + ".GetIndex(i).Get" + helper.getLanguageTypeNameForTypeReference(arrayField.type)?cap_first + "()")}<#else>Complex type array in data-io serialization currently not implemented</#if>;
+                }
+                    <#break>
+                <#case "manual">
+                    <#assign manualField = field>
+
+                // Manual Field (${field.name})
+                ${helper.toSerializationExpression(field, manualField.serializeExpression, type.parserArguments)};
+                    <#break>
+                <#case "reserved">
+                    <#assign reservedField = field>
+
+                // Reserved Field (Just skip the bytes)
+                ${helper.getWriteBufferWriteMethodCall(field.type, helper.getReservedValue(field))};
+                    <#break>
+                <#case "simple">
+                    <#assign simpleField = field>
+
+                // Simple Field (${field.name})
+                <#if helper.isSimpleTypeReference(field.type)>${helper.getWriteBufferWriteMethodCall(field.type, "value.Get" + helper.getLanguageTypeNameForTypeReference(field.type)?cap_first + "()")}<#else>${field.type.name}Serialize(io, <#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type.parserArguments [...]
+                    <#break>
+            </#switch>
+        </#list>
+            } <#sep>else
+    </#list>
+        }
+
+    }
+
+}
+
+</#outputformat>
diff --git a/sandbox/plc4net/.gitignore b/sandbox/plc4net/.gitignore
index 912bc0a..48b4ead 100644
--- a/sandbox/plc4net/.gitignore
+++ b/sandbox/plc4net/.gitignore
@@ -341,4 +341,9 @@ ASALocalRun/
 healthchecksdb
 
 # Backup folder for Package Reference Convert tool in Visual Studio 2017
-MigrationBackup/
\ No newline at end of file
+MigrationBackup/
+
+# Ignore the bin directories
+/api/bin/
+/spi/bin/
+/drivers/knxnetip/bin/
diff --git a/sandbox/plc4net/api/exceptions/PlcConnectionException.cs b/sandbox/plc4net/api/api/exceptions/PlcConnectionException.cs
similarity index 100%
rename from sandbox/plc4net/api/exceptions/PlcConnectionException.cs
rename to sandbox/plc4net/api/api/exceptions/PlcConnectionException.cs
diff --git a/sandbox/plc4net/api/exceptions/PlcException.cs b/sandbox/plc4net/api/api/exceptions/PlcException.cs
similarity index 100%
rename from sandbox/plc4net/api/exceptions/PlcException.cs
rename to sandbox/plc4net/api/api/exceptions/PlcException.cs
diff --git a/sandbox/plc4net/api/exceptions/PlcInvalidFieldException.cs b/sandbox/plc4net/api/api/exceptions/PlcInvalidFieldException.cs
similarity index 100%
rename from sandbox/plc4net/api/exceptions/PlcInvalidFieldException.cs
rename to sandbox/plc4net/api/api/exceptions/PlcInvalidFieldException.cs
diff --git a/sandbox/plc4net/api/messages/IPlcFieldRequest.cs b/sandbox/plc4net/api/api/messages/IPlcFieldRequest.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcFieldRequest.cs
rename to sandbox/plc4net/api/api/messages/IPlcFieldRequest.cs
diff --git a/sandbox/plc4net/api/messages/IPlcFieldResponse.cs b/sandbox/plc4net/api/api/messages/IPlcFieldResponse.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcFieldResponse.cs
rename to sandbox/plc4net/api/api/messages/IPlcFieldResponse.cs
diff --git a/sandbox/plc4net/api/messages/IPlcMessage.cs b/sandbox/plc4net/api/api/messages/IPlcMessage.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcMessage.cs
rename to sandbox/plc4net/api/api/messages/IPlcMessage.cs
diff --git a/sandbox/plc4net/api/messages/IPlcReadRequest.cs b/sandbox/plc4net/api/api/messages/IPlcReadRequest.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcReadRequest.cs
rename to sandbox/plc4net/api/api/messages/IPlcReadRequest.cs
diff --git a/sandbox/plc4net/api/messages/IPlcReadRequestBuilder.cs b/sandbox/plc4net/api/api/messages/IPlcReadRequestBuilder.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcReadRequestBuilder.cs
rename to sandbox/plc4net/api/api/messages/IPlcReadRequestBuilder.cs
diff --git a/sandbox/plc4net/api/messages/IPlcReadResponse.cs b/sandbox/plc4net/api/api/messages/IPlcReadResponse.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcReadResponse.cs
rename to sandbox/plc4net/api/api/messages/IPlcReadResponse.cs
diff --git a/sandbox/plc4net/api/messages/IPlcRequest.cs b/sandbox/plc4net/api/api/messages/IPlcRequest.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcRequest.cs
rename to sandbox/plc4net/api/api/messages/IPlcRequest.cs
diff --git a/sandbox/plc4net/api/messages/IPlcRequestBuilder.cs b/sandbox/plc4net/api/api/messages/IPlcRequestBuilder.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcRequestBuilder.cs
rename to sandbox/plc4net/api/api/messages/IPlcRequestBuilder.cs
diff --git a/sandbox/plc4net/api/messages/IPlcResponse.cs b/sandbox/plc4net/api/api/messages/IPlcResponse.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcResponse.cs
rename to sandbox/plc4net/api/api/messages/IPlcResponse.cs
diff --git a/sandbox/plc4net/api/messages/IPlcSubscriptionEventArgs.cs b/sandbox/plc4net/api/api/messages/IPlcSubscriptionEventArgs.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcSubscriptionEventArgs.cs
rename to sandbox/plc4net/api/api/messages/IPlcSubscriptionEventArgs.cs
diff --git a/sandbox/plc4net/api/messages/IPlcSubscriptionRequest.cs b/sandbox/plc4net/api/api/messages/IPlcSubscriptionRequest.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcSubscriptionRequest.cs
rename to sandbox/plc4net/api/api/messages/IPlcSubscriptionRequest.cs
diff --git a/sandbox/plc4net/api/messages/IPlcSubscriptionRequestBuilder.cs b/sandbox/plc4net/api/api/messages/IPlcSubscriptionRequestBuilder.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcSubscriptionRequestBuilder.cs
rename to sandbox/plc4net/api/api/messages/IPlcSubscriptionRequestBuilder.cs
diff --git a/sandbox/plc4net/api/messages/IPlcSubscriptionResponse.cs b/sandbox/plc4net/api/api/messages/IPlcSubscriptionResponse.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcSubscriptionResponse.cs
rename to sandbox/plc4net/api/api/messages/IPlcSubscriptionResponse.cs
diff --git a/sandbox/plc4net/api/messages/IPlcUnsubscriptionRequest.cs b/sandbox/plc4net/api/api/messages/IPlcUnsubscriptionRequest.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcUnsubscriptionRequest.cs
rename to sandbox/plc4net/api/api/messages/IPlcUnsubscriptionRequest.cs
diff --git a/sandbox/plc4net/api/messages/IPlcUnsubscriptionRequestBuilder.cs b/sandbox/plc4net/api/api/messages/IPlcUnsubscriptionRequestBuilder.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcUnsubscriptionRequestBuilder.cs
rename to sandbox/plc4net/api/api/messages/IPlcUnsubscriptionRequestBuilder.cs
diff --git a/sandbox/plc4net/api/messages/IPlcUnsubscriptionResponse.cs b/sandbox/plc4net/api/api/messages/IPlcUnsubscriptionResponse.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcUnsubscriptionResponse.cs
rename to sandbox/plc4net/api/api/messages/IPlcUnsubscriptionResponse.cs
diff --git a/sandbox/plc4net/api/messages/IPlcWriteRequest.cs b/sandbox/plc4net/api/api/messages/IPlcWriteRequest.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcWriteRequest.cs
rename to sandbox/plc4net/api/api/messages/IPlcWriteRequest.cs
diff --git a/sandbox/plc4net/api/messages/IPlcWriteRequestBuilder.cs b/sandbox/plc4net/api/api/messages/IPlcWriteRequestBuilder.cs
similarity index 100%
rename from sandbox/plc4net/api/messages/IPlcWriteRequestBuilder.cs
rename to sandbox/plc4net/api/api/messages/IPlcWriteRequestBuilder.cs
diff --git a/sandbox/plc4net/api/model/IPlcField.cs b/sandbox/plc4net/api/api/model/IPlcField.cs
similarity index 100%
rename from sandbox/plc4net/api/model/IPlcField.cs
rename to sandbox/plc4net/api/api/model/IPlcField.cs
diff --git a/sandbox/plc4net/api/model/IPlcSubscriptionHandle.cs b/sandbox/plc4net/api/api/model/IPlcSubscriptionHandle.cs
similarity index 100%
rename from sandbox/plc4net/api/model/IPlcSubscriptionHandle.cs
rename to sandbox/plc4net/api/api/model/IPlcSubscriptionHandle.cs
diff --git a/sandbox/plc4net/api/types/PlcResponseCode.cs b/sandbox/plc4net/api/api/types/PlcResponseCode.cs
similarity index 100%
rename from sandbox/plc4net/api/types/PlcResponseCode.cs
rename to sandbox/plc4net/api/api/types/PlcResponseCode.cs
diff --git a/sandbox/plc4net/api/api/value/IPlcValue.cs b/sandbox/plc4net/api/api/value/IPlcValue.cs
new file mode 100644
index 0000000..e3e29a4
--- /dev/null
+++ b/sandbox/plc4net/api/api/value/IPlcValue.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+
+namespace org.apache.plc4net.api.value
+{
+    public interface IPlcValue
+    {
+        // Simple Types
+        bool IsSimple();
+        bool IsNullable();
+        bool IsNull();
+
+        // Boolean
+        bool IsBool();
+        int GetBoolLength();
+        bool GetBool();
+        bool GetBoolAt(int index);
+        bool[] GetBoolArray();
+
+        // Integer
+        bool IsByte();
+        byte GetByte();
+        bool IsUshort();
+        ushort GetUshort();
+        bool IsUint();
+        uint GetUint();
+        bool IsUlong();
+        ulong GetUlong();
+        bool IsSbyte();
+        sbyte GetSbyte();
+        bool IsShort();
+        short GetShort();
+        bool IsInt();
+        int GetInt();
+        bool IsLong();
+        long GetLong();
+
+        // Floating Point
+        bool IsFloat();
+        float GetFloat();
+        bool IsDouble();
+        double GetDouble();
+
+        // String
+        bool IsString();
+        string GetString();
+
+        // Time
+        bool IsDateTime();
+        DateTime GetDateTime();
+
+        // Raw Access
+        byte[] GetRaw();
+
+        // List Methods
+        bool IsList();
+        int GetLength();
+        IPlcValue GetIndex(int index);
+        IPlcValue[] GetList();
+
+        // Struct Methods
+        bool IsStruct();
+        string[] GetKeys();
+        bool HasKey(string key);
+        IPlcValue GetValue(string key);
+        Dictionary<string, IPlcValue> GetStruct();
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/api/api.csproj b/sandbox/plc4net/api/plc4net-api.csproj
similarity index 66%
copy from sandbox/plc4net/api/api.csproj
copy to sandbox/plc4net/api/plc4net-api.csproj
index eb00812..11ff5a4 100644
--- a/sandbox/plc4net/api/api.csproj
+++ b/sandbox/plc4net/api/plc4net-api.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
@@ -19,9 +19,13 @@
 -->
 <Project Sdk="Microsoft.NET.Sdk">
 
-  <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
-    <RootNamespace>org.apache.plc4net</RootNamespace>
-  </PropertyGroup>
+    <PropertyGroup>
+        <TargetFramework>netstandard2.0</TargetFramework>
+        <RootNamespace>org.apache.plc4net</RootNamespace>
+        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
+        <Authors>Apache PLC4X</Authors>
+        <Copyright>The Apache Software Foundation</Copyright>
+        <PackageProjectUrl>https://plc4x.apache.org</PackageProjectUrl>
+    </PropertyGroup>
 
 </Project>
diff --git a/sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs b/sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs
new file mode 100644
index 0000000..9a9d0b3
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs
@@ -0,0 +1,3955 @@
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class KnxDatapoint
+    {
+
+        public IPlcValue Parse(ReadBuffer io, string formatName)
+        {
+            if (formatName == "B1") { // BOOL
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(7);
+
+                // Simple Field (value)
+                var value = io.ReadBit();
+
+                return new PlcBOOL(value);
+            } else
+            if (formatName == "B2") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(6);
+
+                // Simple Field (control)
+                var control = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(control);
+
+                // Simple Field (value)
+                var value = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(value);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "B1U3") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (control)
+                var control = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(control);
+
+                // Simple Field (value)
+                var value = io.ReadByte(3);
+                internalMap["Struct"] = new PlcUSINT(value);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "A8_ASCII") { // STRING
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadString(8);
+
+                return new PlcSTRING(value);
+            } else
+            if (formatName == "A8_8859_1") { // STRING
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadString(8);
+
+                return new PlcSTRING(value);
+            } else
+            if (formatName == "U8") { // USINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadByte(8);
+
+                return new PlcUSINT(value);
+            } else
+            if (formatName == "V8") { // SINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadSbyte(8);
+
+                return new PlcSINT(value);
+            } else
+            if (formatName == "B5N3") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(3);
+
+                // Simple Field (a)
+                var a = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(a);
+
+                // Simple Field (b)
+                var b = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(b);
+
+                // Simple Field (c)
+                var c = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(c);
+
+                // Simple Field (d)
+                var d = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(d);
+
+                // Simple Field (e)
+                var e = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(e);
+
+                // Simple Field (value)
+                var value = io.ReadSbyte(8);
+                internalMap["Struct"] = new PlcSINT(value);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16") { // UINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadUshort(16);
+
+                return new PlcUINT(value);
+            } else
+            if (formatName == "V16") { // INT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadShort(16);
+
+                return new PlcINT(value);
+            } else
+            if (formatName == "F16") { // REAL
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadFloat(true, 4, 11);
+
+                return new PlcREAL(value);
+            } else
+            if (formatName == "N3N5r2N6r2N6") { // TIME_OF_DAY
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (day)
+                var day = io.ReadByte(3);
+
+                // Simple Field (hour)
+                var hour = io.ReadByte(5);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(2);
+
+                // Simple Field (minutes)
+                var minutes = io.ReadByte(6);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(2);
+
+                // Simple Field (seconds)
+                var seconds = io.ReadByte(6);
+
+                var value = new DateTime(0,0,0, hour, minutes, seconds);
+                return new PlcTIME_OF_DAY(value);
+            } else
+            if (formatName == "r3N5r4N4r1U7") { // DATE
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(3);
+
+                // Simple Field (day)
+                var day = io.ReadByte(5);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (month)
+                var month = io.ReadByte(4);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(1);
+
+                // Simple Field (year)
+                var year = io.ReadByte(7);
+
+                var value = new DateTime(year, month, day, 0, 0, 0);
+                return new PlcDATE(value);
+            } else
+            if (formatName == "U32") { // UDINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadUint(32);
+
+                return new PlcUDINT(value);
+            } else
+            if (formatName == "V32") { // DINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadInt(32);
+
+                return new PlcDINT(value);
+            } else
+            if (formatName == "F32") { // REAL
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadFloat(true, 8, 23);
+
+                return new PlcREAL(value);
+            } else
+            if (formatName == "U4U4U4U4U4U4B4N4") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (d6)
+                var d6 = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(d6);
+
+                // Simple Field (d5)
+                var d5 = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(d5);
+
+                // Simple Field (d4)
+                var d4 = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(d4);
+
+                // Simple Field (d3)
+                var d3 = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(d3);
+
+                // Simple Field (d2)
+                var d2 = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(d2);
+
+                // Simple Field (d1)
+                var d1 = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(d1);
+
+                // Simple Field (e)
+                var e = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(e);
+
+                // Simple Field (p)
+                var p = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(p);
+
+                // Simple Field (d)
+                var d = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(d);
+
+                // Simple Field (c)
+                var c = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(c);
+
+                // Simple Field (index)
+                var index = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(index);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "A112_ASCII") { // STRING
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadString(112);
+
+                return new PlcSTRING(value);
+            } else
+            if (formatName == "A112_8859_1") { // STRING
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadString(112);
+
+                return new PlcSTRING(value);
+            } else
+            if (formatName == "r2U6") { // USINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(2);
+
+                // Simple Field (value)
+                var value = io.ReadByte(6);
+
+                return new PlcUSINT(value);
+            } else
+            if (formatName == "B1r1U6") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (learn)
+                var learn = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(learn);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(1);
+
+                // Simple Field (sceneNumber)
+                var sceneNumber = io.ReadByte(6);
+                internalMap["Struct"] = new PlcUSINT(sceneNumber);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8r4U4r3U5U3U5r2U6r2U6B16") { // DATE_AND_TIME
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (year)
+                var year = io.ReadByte(8);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (month)
+                var month = io.ReadByte(4);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(3);
+
+                // Simple Field (day)
+                var day = io.ReadByte(5);
+
+                // Simple Field (dayOfWeek)
+                var dayOfWeek = io.ReadByte(3);
+
+                // Simple Field (hour)
+                var hour = io.ReadByte(5);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(2);
+
+                // Simple Field (minutes)
+                var minutes = io.ReadByte(6);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(2);
+
+                // Simple Field (seconds)
+                var seconds = io.ReadByte(6);
+
+                // Simple Field (fault)
+                var fault = io.ReadBit();
+
+                // Simple Field (workingDay)
+                var workingDay = io.ReadBit();
+
+                // Simple Field (noWorkingDay)
+                var noWorkingDay = io.ReadBit();
+
+                // Simple Field (noYear)
+                var noYear = io.ReadBit();
+
+                // Simple Field (noMonthAndDay)
+                var noMonthAndDay = io.ReadBit();
+
+                // Simple Field (noDayOfWeek)
+                var noDayOfWeek = io.ReadBit();
+
+                // Simple Field (noTime)
+                var noTime = io.ReadBit();
+
+                // Simple Field (standardSummerTime)
+                var standardSummerTime = io.ReadBit();
+
+                // Simple Field (clockWithSyncSignal)
+                var clockWithSyncSignal = io.ReadBit();
+
+                var value = new DateTime(year, month, day, hour, minutes, seconds);
+                return new PlcDATE_AND_TIME(value);
+            } else
+            if (formatName == "N8") { // USINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadByte(8);
+
+                return new PlcUSINT(value);
+            } else
+            if (formatName == "B8") { // BYTE
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadByte(8);
+
+                return new PlcBYTE(value);
+            } else
+            if (formatName == "B16") { // WORD
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadUshort(16);
+
+                return new PlcWORD(value);
+            } else
+            if (formatName == "U4U4") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (busy)
+                var busy = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(busy);
+
+                // Simple Field (nak)
+                var nak = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(nak);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "r1b1U6") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(1);
+
+                // Simple Field (sceneActive)
+                var sceneActive = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(sceneActive);
+
+                // Simple Field (sceneNumber)
+                var sceneNumber = io.ReadByte(6);
+                internalMap["Struct"] = new PlcUSINT(sceneNumber);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "B32") { // DWORD
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadUint(32);
+
+                return new PlcDWORD(value);
+            } else
+            if (formatName == "V64") { // LINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (value)
+                var value = io.ReadLong(64);
+
+                return new PlcLINT(value);
+            } else
+            if (formatName == "B24") { // List
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Array Field (value);
+                var value = new List<IPlcValue>();
+                for (int i = 0; i < (24); i++) {
+                    var internalItem = io.ReadBit();
+                    value.Add(new PlcBOOL(internalItem));
+                }
+
+                return new PlcList(value);
+            } else
+            if (formatName == "N3") { // USINT
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(5);
+
+                // Simple Field (value)
+                var value = io.ReadByte(3);
+
+                return new PlcUSINT(value);
+            } else
+            if (formatName == "B1Z8HeatingOrCoolingZ") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(7);
+
+                // Simple Field (heating)
+                var heating = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(heating);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "B1Z8BinaryValueZ") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(7);
+
+                // Simple Field (high)
+                var high = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(high);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "N8Z8HvacOperatingMode") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (hvacOperatingMode)
+                var hvacOperatingMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(hvacOperatingMode);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "N8Z8DhwMode") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (dhwMode)
+                var dhwMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(dhwMode);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "N8Z8HvacControllingMode") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (hvacControllingMode)
+                var hvacControllingMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(hvacControllingMode);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "N8Z8EnableHeatingOrCoolingStage") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (enableHeatingOrCoolingStage)
+                var enableHeatingOrCoolingStage = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(enableHeatingOrCoolingStage);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "N8Z8BuildingMode") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (buildingMode)
+                var buildingMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(buildingMode);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "N8Z8OccupancyMode") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (occupancyMode)
+                var occupancyMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(occupancyMode);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "N8Z8EmergencyMode") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (hvacEmergencyMode)
+                var hvacEmergencyMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(hvacEmergencyMode);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8Z8Rel") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (relValue)
+                var relValue = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(relValue);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8Z8Counter") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (counterValue)
+                var counterValue = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(counterValue);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8TimePeriod") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (timePeriod)
+                var timePeriod = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(timePeriod);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8FlowRate") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (flowRate)
+                var flowRate = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(flowRate);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8Counter") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (counterValue)
+                var counterValue = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(counterValue);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8ElectricCurrent") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (electricalCurrent)
+                var electricalCurrent = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(electricalCurrent);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8Power") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (power)
+                var power = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(power);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8AtmPressure") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (atmPressure)
+                var atmPressure = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(atmPressure);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8PercentValue") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (percentValue)
+                var percentValue = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(percentValue);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8HvacAirQuality") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (ppmResolution)
+                var ppmResolution = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(ppmResolution);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8WindSpeed") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (windSpeed)
+                var windSpeed = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(windSpeed);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8SunIntensity") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (sunIntensity)
+                var sunIntensity = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(sunIntensity);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16Z8HvacAirFlow") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (airFlow)
+                var airFlow = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(airFlow);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V8Z8RelSignedValue") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (relSignedValue)
+                var relSignedValue = io.ReadSbyte(8);
+                internalMap["Struct"] = new PlcSINT(relSignedValue);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16Z8DeltaTime") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (deltaTime)
+                var deltaTime = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(deltaTime);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16Z8RelSignedValue") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (relSignedValue)
+                var relSignedValue = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(relSignedValue);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16N8HvacModeAndTimeDelay") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (delayTime)
+                var delayTime = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(delayTime);
+
+                // Simple Field (hvacMode)
+                var hvacMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(hvacMode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16N8DhwModeAndTimeDelay") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (delayTime)
+                var delayTime = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(delayTime);
+
+                // Simple Field (dhwMode)
+                var dhwMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(dhwMode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16N8OccupancyModeAndTimeDelay") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (delayTime)
+                var delayTime = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(delayTime);
+
+                // Simple Field (occupationMode)
+                var occupationMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(occupationMode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16N8BuildingModeAndTimeDelay") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (delayTime)
+                var delayTime = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(delayTime);
+
+                // Simple Field (buildingMode)
+                var buildingMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(buildingMode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8B8StatusBurnerController") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (actualRelativePower)
+                var actualRelativePower = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(actualRelativePower);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (stage2Active)
+                var stage2Active = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(stage2Active);
+
+                // Simple Field (stage1Active)
+                var stage1Active = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(stage1Active);
+
+                // Simple Field (failure)
+                var failure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(failure);
+
+                // Simple Field (actualRelativePowerValid)
+                var actualRelativePowerValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(actualRelativePowerValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8B8LockingSignal") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (requestedPowerReduction)
+                var requestedPowerReduction = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(requestedPowerReduction);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(6);
+
+                // Simple Field (critical)
+                var critical = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(critical);
+
+                // Simple Field (requestedPowerReductionValid)
+                var requestedPowerReductionValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(requestedPowerReductionValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8B8BoilerControllerDemandSignal") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (relativeDemand)
+                var relativeDemand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(relativeDemand);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(6);
+
+                // Simple Field (controlsOperationStage2)
+                var controlsOperationStage2 = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(controlsOperationStage2);
+
+                // Simple Field (controlsOperationStage1)
+                var controlsOperationStage1 = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(controlsOperationStage1);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8B8ActuatorPositionDemand") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (actuatorPositionDemand)
+                var actuatorPositionDemand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(actuatorPositionDemand);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (emergencyDemand)
+                var emergencyDemand = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(emergencyDemand);
+
+                // Simple Field (shiftLoadPriority)
+                var shiftLoadPriority = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(shiftLoadPriority);
+
+                // Simple Field (absoluteLoadPriority)
+                var absoluteLoadPriority = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(absoluteLoadPriority);
+
+                // Simple Field (actuatorPositionDemandValid)
+                var actuatorPositionDemandValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(actuatorPositionDemandValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8B8ActuatorPositionStatus") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (actualActuatorPosition)
+                var actualActuatorPosition = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(actualActuatorPosition);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(3);
+
+                // Simple Field (synchronizationMode)
+                var synchronizationMode = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(synchronizationMode);
+
+                // Simple Field (valveKick)
+                var valveKick = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(valveKick);
+
+                // Simple Field (callibrationMode)
+                var callibrationMode = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(callibrationMode);
+
+                // Simple Field (positionManuallyOverridden)
+                var positionManuallyOverridden = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(positionManuallyOverridden);
+
+                // Simple Field (failure)
+                var failure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(failure);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8B8StatusLightingActuator") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (lightingLevel)
+                var lightingLevel = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(lightingLevel);
+
+                // Simple Field (failure)
+                var failure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(failure);
+
+                // Simple Field (localOverride)
+                var localOverride = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(localOverride);
+
+                // Simple Field (dimming)
+                var dimming = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(dimming);
+
+                // Simple Field (staircaseLightingFunction)
+                var staircaseLightingFunction = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(staircaseLightingFunction);
+
+                // Simple Field (nightMode)
+                var nightMode = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(nightMode);
+
+                // Simple Field (forced)
+                var forced = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(forced);
+
+                // Simple Field (locked)
+                var locked = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(locked);
+
+                // Simple Field (lightingLevelValid)
+                var lightingLevelValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(lightingLevelValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16B8HeatProducerManagerStatus") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (tempFlowProdSegmH)
+                var tempFlowProdSegmH = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(tempFlowProdSegmH);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(3);
+
+                // Simple Field (temporarilyOff)
+                var temporarilyOff = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(temporarilyOff);
+
+                // Simple Field (permanentlyOff)
+                var permanentlyOff = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(permanentlyOff);
+
+                // Simple Field (switchedOffSummerMode)
+                var switchedOffSummerMode = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(switchedOffSummerMode);
+
+                // Simple Field (failure)
+                var failure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(failure);
+
+                // Simple Field (tempFlowProdSegmHValid)
+                var tempFlowProdSegmHValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(tempFlowProdSegmHValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16B8RoomTemperatureDemand") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (roomTemperatureDemand)
+                var roomTemperatureDemand = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(roomTemperatureDemand);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (emergencyDemand)
+                var emergencyDemand = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(emergencyDemand);
+
+                // Simple Field (shiftLoadPriority)
+                var shiftLoadPriority = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(shiftLoadPriority);
+
+                // Simple Field (absoluteLoadPriority)
+                var absoluteLoadPriority = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(absoluteLoadPriority);
+
+                // Simple Field (roomTemperatureDemandValid)
+                var roomTemperatureDemandValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(roomTemperatureDemandValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16B8ColdWaterProducerManagerStatus") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (flowTemperatureProdSegmC)
+                var flowTemperatureProdSegmC = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(flowTemperatureProdSegmC);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (temporarilyOff)
+                var temporarilyOff = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(temporarilyOff);
+
+                // Simple Field (permanentlyOff)
+                var permanentlyOff = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(permanentlyOff);
+
+                // Simple Field (failure)
+                var failure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(failure);
+
+                // Simple Field (flowTemperatureProdSegmCValid)
+                var flowTemperatureProdSegmCValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(flowTemperatureProdSegmCValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16B8WaterTemperatureControllerStatus") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (actualTemperature)
+                var actualTemperature = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(actualTemperature);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(5);
+
+                // Simple Field (controllerWorking)
+                var controllerWorking = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(controllerWorking);
+
+                // Simple Field (failure)
+                var failure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(failure);
+
+                // Simple Field (actualTemperatureValid)
+                var actualTemperatureValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(actualTemperatureValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16B16") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (flowTemperatureDemand)
+                var flowTemperatureDemand = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(flowTemperatureDemand);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (demandFromDhwWhileLegionellaFunctionIsActive)
+                var demandFromDhwWhileLegionellaFunctionIsActive = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(demandFromDhwWhileLegionellaFunctionIsActive);
+
+                // Simple Field (emergencyDemandForFrostProtection)
+                var emergencyDemandForFrostProtection = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(emergencyDemandForFrostProtection);
+
+                // Simple Field (requestForWaterCirculationInPrimaryDistributionSegment)
+                var requestForWaterCirculationInPrimaryDistributionSegment = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(requestForWaterCirculationInPrimaryDistributionSegment);
+
+                // Simple Field (demandFromAuxillaryHeatOrCoolConsumer)
+                var demandFromAuxillaryHeatOrCoolConsumer = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(demandFromAuxillaryHeatOrCoolConsumer);
+
+                // Simple Field (demandFromVentilation)
+                var demandFromVentilation = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(demandFromVentilation);
+
+                // Simple Field (demandForRoomHeatingOrCooling)
+                var demandForRoomHeatingOrCooling = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(demandForRoomHeatingOrCooling);
+
+                // Simple Field (heatDemandFromDhw)
+                var heatDemandFromDhw = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(heatDemandFromDhw);
+
+                // Simple Field (flowTemperatureDemandIsMin)
+                var flowTemperatureDemandIsMin = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(flowTemperatureDemandIsMin);
+
+                // Simple Field (flowTemperatureDemandIsMax)
+                var flowTemperatureDemandIsMax = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(flowTemperatureDemandIsMax);
+
+                // Simple Field (shiftLoadPriority)
+                var shiftLoadPriority = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(shiftLoadPriority);
+
+                // Simple Field (absoluteLoadPriority)
+                var absoluteLoadPriority = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(absoluteLoadPriority);
+
+                // Simple Field (flowTemperatureDemandValid)
+                var flowTemperatureDemandValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(flowTemperatureDemandValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8N8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (energyDemand)
+                var energyDemand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(energyDemand);
+
+                // Simple Field (actualControllerMode)
+                var actualControllerMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(actualControllerMode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16V16V16RoomTemperature") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (temperatureSetpointComfort)
+                var temperatureSetpointComfort = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointComfort);
+
+                // Simple Field (temperatureSetpointStandby)
+                var temperatureSetpointStandby = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointStandby);
+
+                // Simple Field (temperatureSetpointEco)
+                var temperatureSetpointEco = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointEco);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16V16V16RoomTemperatureShift") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (temperatureSetpointShiftComfort)
+                var temperatureSetpointShiftComfort = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftComfort);
+
+                // Simple Field (temperatureSetpointShiftStandby)
+                var temperatureSetpointShiftStandby = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftStandby);
+
+                // Simple Field (temperatureSetpointShiftEco)
+                var temperatureSetpointShiftEco = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftEco);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16V16V16V16RoomTemperature") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (temperatureSetpointComfort)
+                var temperatureSetpointComfort = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointComfort);
+
+                // Simple Field (temperatureSetpointStandby)
+                var temperatureSetpointStandby = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointStandby);
+
+                // Simple Field (temperatureSetpointEco)
+                var temperatureSetpointEco = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointEco);
+
+                // Simple Field (temperatureSetpointBProt)
+                var temperatureSetpointBProt = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointBProt);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16V16V16V16DhwtTemperature") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (temperatureSetpointLegioProtect)
+                var temperatureSetpointLegioProtect = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointLegioProtect);
+
+                // Simple Field (temperatureSetpointNormal)
+                var temperatureSetpointNormal = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointNormal);
+
+                // Simple Field (temperatureSetpointReduced)
+                var temperatureSetpointReduced = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointReduced);
+
+                // Simple Field (temperatureSetpointFrostProtect)
+                var temperatureSetpointFrostProtect = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointFrostProtect);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16V16V16V16RoomTemperatureShift") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (temperatureSetpointShiftComfort)
+                var temperatureSetpointShiftComfort = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftComfort);
+
+                // Simple Field (temperatureSetpointShiftStandby)
+                var temperatureSetpointShiftStandby = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftStandby);
+
+                // Simple Field (temperatureSetpointShiftEco)
+                var temperatureSetpointShiftEco = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftEco);
+
+                // Simple Field (temperatureSetpointShiftBProt)
+                var temperatureSetpointShiftBProt = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftBProt);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16U8B8Heat") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (flowTemperatureDemand)
+                var flowTemperatureDemand = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(flowTemperatureDemand);
+
+                // Simple Field (relativePower)
+                var relativePower = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(relativePower);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(2);
+
+                // Simple Field (boilerEnabled)
+                var boilerEnabled = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(boilerEnabled);
+
+                // Simple Field (stage2Forced)
+                var stage2Forced = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(stage2Forced);
+
+                // Simple Field (stage2Enabled)
+                var stage2Enabled = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(stage2Enabled);
+
+                // Simple Field (stage1Forced)
+                var stage1Forced = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(stage1Forced);
+
+                // Simple Field (stage1Enabled)
+                var stage1Enabled = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(stage1Enabled);
+
+                // Simple Field (flowTemperatureDemandValid)
+                var flowTemperatureDemandValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(flowTemperatureDemandValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16U8B8ChilledWater") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (chilledWaterFlowTemperatureDemand)
+                var chilledWaterFlowTemperatureDemand = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(chilledWaterFlowTemperatureDemand);
+
+                // Simple Field (relativePower)
+                var relativePower = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(relativePower);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(5);
+
+                // Simple Field (chilledWaterPumpEnabled)
+                var chilledWaterPumpEnabled = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(chilledWaterPumpEnabled);
+
+                // Simple Field (relativePowerValid)
+                var relativePowerValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(relativePowerValid);
+
+                // Simple Field (chilledWaterFlowTemperatureDemandValid)
+                var chilledWaterFlowTemperatureDemandValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(chilledWaterFlowTemperatureDemandValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16U8B16Boiler") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (tempBoiler)
+                var tempBoiler = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(tempBoiler);
+
+                // Simple Field (relativePower)
+                var relativePower = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(relativePower);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (chimneySweepFunctionActive)
+                var chimneySweepFunctionActive = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(chimneySweepFunctionActive);
+
+                // Simple Field (reducedAvailability)
+                var reducedAvailability = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(reducedAvailability);
+
+                // Simple Field (powerLimitBoilerReached)
+                var powerLimitBoilerReached = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(powerLimitBoilerReached);
+
+                // Simple Field (powerLimitStage1Reached)
+                var powerLimitStage1Reached = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(powerLimitStage1Reached);
+
+                // Simple Field (stage2Enabled)
+                var stage2Enabled = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(stage2Enabled);
+
+                // Simple Field (stage1Enabled)
+                var stage1Enabled = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(stage1Enabled);
+
+                // Simple Field (boilerTemporarilyNotProvidingHeat)
+                var boilerTemporarilyNotProvidingHeat = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(boilerTemporarilyNotProvidingHeat);
+
+                // Simple Field (permanentlyOff)
+                var permanentlyOff = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(permanentlyOff);
+
+                // Simple Field (boilerSwitchedOffWinterSummerMode)
+                var boilerSwitchedOffWinterSummerMode = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(boilerSwitchedOffWinterSummerMode);
+
+                // Simple Field (boilerFailure)
+                var boilerFailure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(boilerFailure);
+
+                // Simple Field (relativePowerValid)
+                var relativePowerValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(relativePowerValid);
+
+                // Simple Field (tempBoilerValid)
+                var tempBoilerValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(tempBoilerValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16U8B16Chiller") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (tempChiller)
+                var tempChiller = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(tempChiller);
+
+                // Simple Field (relativePower)
+                var relativePower = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(relativePower);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (reducedAvailability)
+                var reducedAvailability = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(reducedAvailability);
+
+                // Simple Field (powerLimitChillerReached)
+                var powerLimitChillerReached = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(powerLimitChillerReached);
+
+                // Simple Field (powerLimitCurrentStageReached)
+                var powerLimitCurrentStageReached = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(powerLimitCurrentStageReached);
+
+                // Simple Field (permanentlyOff)
+                var permanentlyOff = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(permanentlyOff);
+
+                // Simple Field (chillerFailure)
+                var chillerFailure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(chillerFailure);
+
+                // Simple Field (chillerRunningStatus)
+                var chillerRunningStatus = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(chillerRunningStatus);
+
+                // Simple Field (relativePowerValid)
+                var relativePowerValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(relativePowerValid);
+
+                // Simple Field (tempChillerValid)
+                var tempChillerValid = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(tempChillerValid);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16U8N8B8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (nominalPower)
+                var nominalPower = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(nominalPower);
+
+                // Simple Field (relativePowerLimit)
+                var relativePowerLimit = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(relativePowerLimit);
+
+                // Simple Field (burnerType)
+                var burnerType = io.ReadSbyte(8);
+                internalMap["Struct"] = new PlcSINT(burnerType);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(5);
+
+                // Simple Field (solidState)
+                var solidState = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(solidState);
+
+                // Simple Field (gas)
+                var gas = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(gas);
+
+                // Simple Field (oil)
+                var oil = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(oil);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U5U5U6") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (magicNumber)
+                var magicNumber = io.ReadByte(5);
+                internalMap["Struct"] = new PlcUSINT(magicNumber);
+
+                // Simple Field (versionNumber)
+                var versionNumber = io.ReadByte(5);
+                internalMap["Struct"] = new PlcUSINT(versionNumber);
+
+                // Simple Field (revisionNumber)
+                var revisionNumber = io.ReadByte(6);
+                internalMap["Struct"] = new PlcUSINT(revisionNumber);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V32Z8VolumeLiter") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (volumeLiter)
+                var volumeLiter = io.ReadInt(32);
+                internalMap["Struct"] = new PlcDINT(volumeLiter);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V32Z8FlowRate") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (flowRate)
+                var flowRate = io.ReadInt(32);
+                internalMap["Struct"] = new PlcDINT(flowRate);
+
+                // Simple Field (statusCommand)
+                var statusCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8N8N8N8B8B8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (logNumber)
+                var logNumber = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(logNumber);
+
+                // Simple Field (alarmPriority)
+                var alarmPriority = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(alarmPriority);
+
+                // Simple Field (applicationArea)
+                var applicationArea = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(applicationArea);
+
+                // Simple Field (errorClass)
+                var errorClass = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(errorClass);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(4);
+
+                // Simple Field (errorCode_Sup)
+                var errorCode_Sup = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(errorCode_Sup);
+
+                // Simple Field (alarmText_Sup)
+                var alarmText_Sup = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(alarmText_Sup);
+
+                // Simple Field (timeStamp_Sup)
+                var timeStamp_Sup = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(timeStamp_Sup);
+
+                // Simple Field (ack_Sup)
+                var ack_Sup = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(ack_Sup);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(5);
+
+                // Simple Field (alarmUnAck)
+                var alarmUnAck = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(alarmUnAck);
+
+                // Simple Field (locked)
+                var locked = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(locked);
+
+                // Simple Field (inAlarm)
+                var inAlarm = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(inAlarm);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16V16") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (delayTime)
+                var delayTime = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(delayTime);
+
+                // Simple Field (temperature)
+                var temperature = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(temperature);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "N16U32") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (manufacturerCode)
+                var manufacturerCode = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(manufacturerCode);
+
+                // Simple Field (incrementedNumber)
+                var incrementedNumber = io.ReadUint(32);
+                internalMap["Struct"] = new PlcUDINT(incrementedNumber);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "F16F16F16") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (temperatureSetpointComfort)
+                var temperatureSetpointComfort = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointComfort);
+
+                // Simple Field (temperatureSetpointShiftStandby)
+                var temperatureSetpointShiftStandby = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftStandby);
+
+                // Simple Field (temperatureSetpointShiftEco)
+                var temperatureSetpointShiftEco = io.ReadFloat(true, 4, 11);
+                internalMap["Struct"] = new PlcREAL(temperatureSetpointShiftEco);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V8N8N8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (energyDemand)
+                var energyDemand = io.ReadSbyte(8);
+                internalMap["Struct"] = new PlcSINT(energyDemand);
+
+                // Simple Field (hvacControllerMode)
+                var hvacControllerMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(hvacControllerMode);
+
+                // Simple Field (hvacEmergencyMode)
+                var hvacEmergencyMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(hvacEmergencyMode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V16V16N8N8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (tempSetpointCooling)
+                var tempSetpointCooling = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(tempSetpointCooling);
+
+                // Simple Field (tempSetpointHeating)
+                var tempSetpointHeating = io.ReadShort(16);
+                internalMap["Struct"] = new PlcINT(tempSetpointHeating);
+
+                // Simple Field (hvacControllerMode)
+                var hvacControllerMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(hvacControllerMode);
+
+                // Simple Field (hvacEmergencyMode)
+                var hvacEmergencyMode = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(hvacEmergencyMode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16U8Scaling") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (timePeriod)
+                var timePeriod = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(timePeriod);
+
+                // Simple Field (percent)
+                var percent = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(percent);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16U8TariffNext") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (delayTime)
+                var delayTime = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(delayTime);
+
+                // Simple Field (tariff)
+                var tariff = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(tariff);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V32N8Z8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (countVal)
+                var countVal = io.ReadInt(32);
+                internalMap["Struct"] = new PlcDINT(countVal);
+
+                // Simple Field (valInfField)
+                var valInfField = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(valInfField);
+
+                // Simple Field (statusOrCommand)
+                var statusOrCommand = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(statusOrCommand);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U16U32U8N8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (manufacturerId)
+                var manufacturerId = io.ReadUshort(16);
+                internalMap["Struct"] = new PlcUINT(manufacturerId);
+
+                // Simple Field (identNumber)
+                var identNumber = io.ReadUint(32);
+                internalMap["Struct"] = new PlcUDINT(identNumber);
+
+                // Simple Field (version)
+                var version = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(version);
+
+                // Simple Field (medium)
+                var medium = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(medium);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "A8A8A8A8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (languageCode)
+                var languageCode = io.ReadString(16);
+                internalMap["Struct"] = new PlcSTRING(languageCode);
+
+                // Simple Field (regionCode)
+                var regionCode = io.ReadString(16);
+                internalMap["Struct"] = new PlcSTRING(regionCode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8U8U8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (red)
+                var red = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(red);
+
+                // Simple Field (green)
+                var green = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(green);
+
+                // Simple Field (blue)
+                var blue = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(blue);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "A8A8Language") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (languageCode)
+                var languageCode = io.ReadString(16);
+                internalMap["Struct"] = new PlcSTRING(languageCode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "A8A8Region") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (regionCode)
+                var regionCode = io.ReadString(16);
+                internalMap["Struct"] = new PlcSTRING(regionCode);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "V32U8B8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (activeElectricalEnergy)
+                var activeElectricalEnergy = io.ReadInt(32);
+                internalMap["Struct"] = new PlcDINT(activeElectricalEnergy);
+
+                // Simple Field (tariff)
+                var tariff = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(tariff);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(6);
+
+                // Simple Field (noTariff)
+                var noTariff = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(noTariff);
+
+                // Simple Field (noActiveElectricalEnergy)
+                var noActiveElectricalEnergy = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(noActiveElectricalEnergy);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "B1N3N4") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (deactivationOfPriority)
+                var deactivationOfPriority = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(deactivationOfPriority);
+
+                // Simple Field (priorityLevel)
+                var priorityLevel = io.ReadByte(3);
+                internalMap["Struct"] = new PlcUSINT(priorityLevel);
+
+                // Simple Field (modeLevel)
+                var modeLevel = io.ReadByte(4);
+                internalMap["Struct"] = new PlcUSINT(modeLevel);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "B10U6") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(5);
+
+                // Simple Field (convertorError)
+                var convertorError = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(convertorError);
+
+                // Simple Field (ballastFailure)
+                var ballastFailure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(ballastFailure);
+
+                // Simple Field (lampError)
+                var lampError = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(lampError);
+
+                // Simple Field (read)
+                var read = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(read);
+
+                // Simple Field (groupAddress)
+                var groupAddress = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(groupAddress);
+
+                // Simple Field (address)
+                var address = io.ReadByte(6);
+                internalMap["Struct"] = new PlcUSINT(address);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "B2U6") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (sceneActivationInactive)
+                var sceneActivationInactive = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(sceneActivationInactive);
+
+                // Simple Field (storageFunctionDisable)
+                var storageFunctionDisable = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(storageFunctionDisable);
+
+                // Simple Field (sceneNumber)
+                var sceneNumber = io.ReadByte(6);
+                internalMap["Struct"] = new PlcUSINT(sceneNumber);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8r7B1") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (setValue)
+                var setValue = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(setValue);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(7);
+
+                // Simple Field (channelActivationActive)
+                var channelActivationActive = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(channelActivationActive);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8U8B8") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (heightPosition)
+                var heightPosition = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(heightPosition);
+
+                // Simple Field (slatsPosition)
+                var slatsPosition = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(slatsPosition);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(6);
+
+                // Simple Field (validSlatsPos)
+                var validSlatsPos = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(validSlatsPos);
+
+                // Simple Field (validHeightPos)
+                var validHeightPos = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(validHeightPos);
+
+                return new PlcStruct(internalMap);
+            } else
+            if (formatName == "U8U8B16") { // Struct
+                var internalMap = new Dictionary<string, IPlcValue>();
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(8);
+
+                // Simple Field (heightPosition)
+                var heightPosition = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(heightPosition);
+
+                // Simple Field (slatsPosition)
+                var slatsPosition = io.ReadByte(8);
+                internalMap["Struct"] = new PlcUSINT(slatsPosition);
+
+                // Simple Field (validSlatsPos)
+                var validSlatsPos = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(validSlatsPos);
+
+                // Simple Field (validHeightPos)
+                var validHeightPos = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(validHeightPos);
+
+                // Reserved Field (Just skip the bytes)
+                io.ReadByte(3);
+
+                // Simple Field (failure)
+                var failure = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(failure);
+
+                // Simple Field (localOverride)
+                var localOverride = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(localOverride);
+
+                // Simple Field (locked)
+                var locked = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(locked);
+
+                // Simple Field (forced)
+                var forced = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(forced);
+
+                // Simple Field (weatherAlarm)
+                var weatherAlarm = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(weatherAlarm);
+
+                // Simple Field (targetSPosRestrict)
+                var targetSPosRestrict = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(targetSPosRestrict);
+
+                // Simple Field (targetHPosRestrict)
+                var targetHPosRestrict = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(targetHPosRestrict);
+
+                // Simple Field (driveState)
+                var driveState = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(driveState);
+
+                // Simple Field (lowerPredefPos)
+                var lowerPredefPos = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(lowerPredefPos);
+
+                // Simple Field (lowerEndPos)
+                var lowerEndPos = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(lowerEndPos);
+
+                // Simple Field (upperEndPos)
+                var upperEndPos = io.ReadBit();
+                internalMap["Struct"] = new PlcBOOL(upperEndPos);
+
+                return new PlcStruct(internalMap);
+            } 
+            return null;
+        }
+
+        public void Serialize(WriteBuffer io, IPlcValue value, string formatName)
+        {
+            if (formatName == "B1") { // BOOL
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(7, 0x0);
+
+                // Simple Field (value)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "B2") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(6, 0x0);
+
+                // Simple Field (control)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (value)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "B1U3") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x0);
+
+                // Simple Field (control)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (value)
+                io.WriteByte(3, value.GetByte());
+            } else
+            if (formatName == "A8_ASCII") { // STRING
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteString(8, "ASCII", value.GetString());
+            } else
+            if (formatName == "A8_8859_1") { // STRING
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteString(8, "ISO-8859-1", value.GetString());
+            } else
+            if (formatName == "U8") { // USINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "V8") { // SINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteSbyte(8, value.GetSbyte());
+            } else
+            if (formatName == "B5N3") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(3, 0x0);
+
+                // Simple Field (a)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (b)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (c)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (d)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (e)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (value)
+                io.WriteSbyte(8, value.GetSbyte());
+            } else
+            if (formatName == "U16") { // UINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteUshort(16, value.GetUshort());
+            } else
+            if (formatName == "V16") { // INT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteShort(16, value.GetShort());
+            } else
+            if (formatName == "F16") { // REAL
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteFloat(16, value.GetFloat());
+            } else
+            if (formatName == "N3N5r2N6r2N6") { // TIME_OF_DAY
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (day)
+                io.WriteByte(3, value.GetByte());
+
+                // Simple Field (hour)
+                io.WriteByte(5, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(2, 0x00);
+
+                // Simple Field (minutes)
+                io.WriteByte(6, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(2, 0x00);
+
+                // Simple Field (seconds)
+                io.WriteByte(6, value.GetByte());
+            } else
+            if (formatName == "r3N5r4N4r1U7") { // DATE
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(3, 0x00);
+
+                // Simple Field (day)
+                io.WriteByte(5, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (month)
+                io.WriteByte(4, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(1, 0x00);
+
+                // Simple Field (year)
+                io.WriteByte(7, value.GetByte());
+            } else
+            if (formatName == "U32") { // UDINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteUint(32, value.GetUint());
+            } else
+            if (formatName == "V32") { // DINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteInt(32, value.GetInt());
+            } else
+            if (formatName == "F32") { // REAL
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteFloat(32, value.GetFloat());
+            } else
+            if (formatName == "U4U4U4U4U4U4B4N4") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (d6)
+                io.WriteByte(4, value.GetByte());
+
+                // Simple Field (d5)
+                io.WriteByte(4, value.GetByte());
+
+                // Simple Field (d4)
+                io.WriteByte(4, value.GetByte());
+
+                // Simple Field (d3)
+                io.WriteByte(4, value.GetByte());
+
+                // Simple Field (d2)
+                io.WriteByte(4, value.GetByte());
+
+                // Simple Field (d1)
+                io.WriteByte(4, value.GetByte());
+
+                // Simple Field (e)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (p)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (d)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (c)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (index)
+                io.WriteByte(4, value.GetByte());
+            } else
+            if (formatName == "A112_ASCII") { // STRING
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteString(112, "ASCII", value.GetString());
+            } else
+            if (formatName == "A112_8859_1") { // STRING
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteString(112, "ISO-8859-1", value.GetString());
+            } else
+            if (formatName == "r2U6") { // USINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(2, 0x00);
+
+                // Simple Field (value)
+                io.WriteByte(6, value.GetByte());
+            } else
+            if (formatName == "B1r1U6") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (learn)
+                io.WriteBit(value.GetBool());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(1, 0x00);
+
+                // Simple Field (sceneNumber)
+                io.WriteByte(6, value.GetByte());
+            } else
+            if (formatName == "U8r4U4r3U5U3U5r2U6r2U6B16") { // DATE_AND_TIME
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (year)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (month)
+                io.WriteByte(4, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(3, 0x00);
+
+                // Simple Field (day)
+                io.WriteByte(5, value.GetByte());
+
+                // Simple Field (dayOfWeek)
+                io.WriteByte(3, value.GetByte());
+
+                // Simple Field (hour)
+                io.WriteByte(5, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(2, 0x00);
+
+                // Simple Field (minutes)
+                io.WriteByte(6, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(2, 0x00);
+
+                // Simple Field (seconds)
+                io.WriteByte(6, value.GetByte());
+
+                // Simple Field (fault)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (workingDay)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (noWorkingDay)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (noYear)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (noMonthAndDay)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (noDayOfWeek)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (noTime)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (standardSummerTime)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (clockWithSyncSignal)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "N8") { // USINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "B8") { // BYTE
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "B16") { // WORD
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteUshort(16, value.GetUshort());
+            } else
+            if (formatName == "U4U4") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (busy)
+                io.WriteByte(4, value.GetByte());
+
+                // Simple Field (nak)
+                io.WriteByte(4, value.GetByte());
+            } else
+            if (formatName == "r1b1U6") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(1, 0x00);
+
+                // Simple Field (sceneActive)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (sceneNumber)
+                io.WriteByte(6, value.GetByte());
+            } else
+            if (formatName == "B32") { // DWORD
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteUint(32, value.GetUint());
+            } else
+            if (formatName == "V64") { // LINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (value)
+                io.WriteLong(64, value.GetLong());
+            } else
+            if (formatName == "B24") { // List
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Array Field (value)
+                for (int i = 0; i < (24); i++) {
+                    io.WriteBit(value.GetIndex(i).GetBool());
+                }
+            } else
+            if (formatName == "N3") { // USINT
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(5, 0x00);
+
+                // Simple Field (value)
+                io.WriteByte(3, value.GetByte());
+            } else
+            if (formatName == "B1Z8HeatingOrCoolingZ") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(7, 0x00);
+
+                // Simple Field (heating)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "B1Z8BinaryValueZ") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(7, 0x00);
+
+                // Simple Field (high)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "N8Z8HvacOperatingMode") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (hvacOperatingMode)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "N8Z8DhwMode") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (dhwMode)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "N8Z8HvacControllingMode") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (hvacControllingMode)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "N8Z8EnableHeatingOrCoolingStage") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (enableHeatingOrCoolingStage)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "N8Z8BuildingMode") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (buildingMode)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "N8Z8OccupancyMode") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (occupancyMode)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "N8Z8EmergencyMode") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (hvacEmergencyMode)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U8Z8Rel") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (relValue)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U8Z8Counter") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (counterValue)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8TimePeriod") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (timePeriod)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8FlowRate") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (flowRate)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8Counter") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (counterValue)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8ElectricCurrent") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (electricalCurrent)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8Power") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (power)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8AtmPressure") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (atmPressure)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8PercentValue") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (percentValue)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8HvacAirQuality") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (ppmResolution)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8WindSpeed") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (windSpeed)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8SunIntensity") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (sunIntensity)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16Z8HvacAirFlow") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (airFlow)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "V8Z8RelSignedValue") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (relSignedValue)
+                io.WriteSbyte(8, value.GetSbyte());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "V16Z8DeltaTime") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (deltaTime)
+                io.WriteShort(16, value.GetShort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "V16Z8RelSignedValue") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (relSignedValue)
+                io.WriteShort(16, value.GetShort());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16N8HvacModeAndTimeDelay") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (delayTime)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (hvacMode)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16N8DhwModeAndTimeDelay") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (delayTime)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (dhwMode)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16N8OccupancyModeAndTimeDelay") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (delayTime)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (occupationMode)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16N8BuildingModeAndTimeDelay") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (delayTime)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (buildingMode)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U8B8StatusBurnerController") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (actualRelativePower)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (stage2Active)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (stage1Active)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (failure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (actualRelativePowerValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U8B8LockingSignal") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (requestedPowerReduction)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(6, 0x00);
+
+                // Simple Field (critical)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (requestedPowerReductionValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U8B8BoilerControllerDemandSignal") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (relativeDemand)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(6, 0x00);
+
+                // Simple Field (controlsOperationStage2)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (controlsOperationStage1)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U8B8ActuatorPositionDemand") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (actuatorPositionDemand)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (emergencyDemand)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (shiftLoadPriority)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (absoluteLoadPriority)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (actuatorPositionDemandValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U8B8ActuatorPositionStatus") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (actualActuatorPosition)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(3, 0x00);
+
+                // Simple Field (synchronizationMode)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (valveKick)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (callibrationMode)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (positionManuallyOverridden)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (failure)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U8B8StatusLightingActuator") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (lightingLevel)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (failure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (localOverride)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (dimming)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (staircaseLightingFunction)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (nightMode)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (forced)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (locked)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (lightingLevelValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "V16B8HeatProducerManagerStatus") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (tempFlowProdSegmH)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(3, 0x00);
+
+                // Simple Field (temporarilyOff)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (permanentlyOff)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (switchedOffSummerMode)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (failure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (tempFlowProdSegmHValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "V16B8RoomTemperatureDemand") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (roomTemperatureDemand)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (emergencyDemand)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (shiftLoadPriority)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (absoluteLoadPriority)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (roomTemperatureDemandValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "V16B8ColdWaterProducerManagerStatus") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (flowTemperatureProdSegmC)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (temporarilyOff)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (permanentlyOff)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (failure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (flowTemperatureProdSegmCValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "V16B8WaterTemperatureControllerStatus") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (actualTemperature)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(5, 0x00);
+
+                // Simple Field (controllerWorking)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (failure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (actualTemperatureValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "V16B16") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (flowTemperatureDemand)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (demandFromDhwWhileLegionellaFunctionIsActive)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (emergencyDemandForFrostProtection)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (requestForWaterCirculationInPrimaryDistributionSegment)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (demandFromAuxillaryHeatOrCoolConsumer)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (demandFromVentilation)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (demandForRoomHeatingOrCooling)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (heatDemandFromDhw)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (flowTemperatureDemandIsMin)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (flowTemperatureDemandIsMax)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (shiftLoadPriority)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (absoluteLoadPriority)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (flowTemperatureDemandValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U8N8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (energyDemand)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (actualControllerMode)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "V16V16V16RoomTemperature") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (temperatureSetpointComfort)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointStandby)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointEco)
+                io.WriteFloat(16, value.GetFloat());
+            } else
+            if (formatName == "V16V16V16RoomTemperatureShift") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (temperatureSetpointShiftComfort)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointShiftStandby)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointShiftEco)
+                io.WriteFloat(16, value.GetFloat());
+            } else
+            if (formatName == "V16V16V16V16RoomTemperature") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (temperatureSetpointComfort)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointStandby)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointEco)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointBProt)
+                io.WriteFloat(16, value.GetFloat());
+            } else
+            if (formatName == "V16V16V16V16DhwtTemperature") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (temperatureSetpointLegioProtect)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointNormal)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointReduced)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointFrostProtect)
+                io.WriteFloat(16, value.GetFloat());
+            } else
+            if (formatName == "V16V16V16V16RoomTemperatureShift") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (temperatureSetpointShiftComfort)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointShiftStandby)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointShiftEco)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointShiftBProt)
+                io.WriteFloat(16, value.GetFloat());
+            } else
+            if (formatName == "V16U8B8Heat") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (flowTemperatureDemand)
+                io.WriteShort(16, value.GetShort());
+
+                // Simple Field (relativePower)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(2, 0x00);
+
+                // Simple Field (boilerEnabled)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (stage2Forced)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (stage2Enabled)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (stage1Forced)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (stage1Enabled)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (flowTemperatureDemandValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "V16U8B8ChilledWater") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (chilledWaterFlowTemperatureDemand)
+                io.WriteShort(16, value.GetShort());
+
+                // Simple Field (relativePower)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(5, 0x00);
+
+                // Simple Field (chilledWaterPumpEnabled)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (relativePowerValid)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (chilledWaterFlowTemperatureDemandValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "V16U8B16Boiler") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (tempBoiler)
+                io.WriteShort(16, value.GetShort());
+
+                // Simple Field (relativePower)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (chimneySweepFunctionActive)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (reducedAvailability)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (powerLimitBoilerReached)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (powerLimitStage1Reached)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (stage2Enabled)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (stage1Enabled)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (boilerTemporarilyNotProvidingHeat)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (permanentlyOff)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (boilerSwitchedOffWinterSummerMode)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (boilerFailure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (relativePowerValid)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (tempBoilerValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "V16U8B16Chiller") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (tempChiller)
+                io.WriteShort(16, value.GetShort());
+
+                // Simple Field (relativePower)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x00);
+
+                // Simple Field (reducedAvailability)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (powerLimitChillerReached)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (powerLimitCurrentStageReached)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (permanentlyOff)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (chillerFailure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (chillerRunningStatus)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (relativePowerValid)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (tempChillerValid)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U16U8N8B8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (nominalPower)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (relativePowerLimit)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (burnerType)
+                io.WriteSbyte(8, value.GetSbyte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(5, 0x00);
+
+                // Simple Field (solidState)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (gas)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (oil)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U5U5U6") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (magicNumber)
+                io.WriteByte(5, value.GetByte());
+
+                // Simple Field (versionNumber)
+                io.WriteByte(5, value.GetByte());
+
+                // Simple Field (revisionNumber)
+                io.WriteByte(6, value.GetByte());
+            } else
+            if (formatName == "V32Z8VolumeLiter") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (volumeLiter)
+                io.WriteInt(32, value.GetInt());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "V32Z8FlowRate") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (flowRate)
+                io.WriteInt(32, value.GetInt());
+
+                // Simple Field (statusCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U8N8N8N8B8B8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (logNumber)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (alarmPriority)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (applicationArea)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (errorClass)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(4, 0x00);
+
+                // Simple Field (errorCode_Sup)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (alarmText_Sup)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (timeStamp_Sup)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (ack_Sup)
+                io.WriteBit(value.GetBool());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(5, 0x00);
+
+                // Simple Field (alarmUnAck)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (locked)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (inAlarm)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U16V16") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (delayTime)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (temperature)
+                io.WriteShort(16, value.GetShort());
+            } else
+            if (formatName == "N16U32") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (manufacturerCode)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (incrementedNumber)
+                io.WriteUint(32, value.GetUint());
+            } else
+            if (formatName == "F16F16F16") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (temperatureSetpointComfort)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointShiftStandby)
+                io.WriteFloat(16, value.GetFloat());
+
+                // Simple Field (temperatureSetpointShiftEco)
+                io.WriteFloat(16, value.GetFloat());
+            } else
+            if (formatName == "V8N8N8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (energyDemand)
+                io.WriteSbyte(8, value.GetSbyte());
+
+                // Simple Field (hvacControllerMode)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (hvacEmergencyMode)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "V16V16N8N8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (tempSetpointCooling)
+                io.WriteShort(16, value.GetShort());
+
+                // Simple Field (tempSetpointHeating)
+                io.WriteShort(16, value.GetShort());
+
+                // Simple Field (hvacControllerMode)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (hvacEmergencyMode)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16U8Scaling") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (timePeriod)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (percent)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16U8TariffNext") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (delayTime)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (tariff)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "V32N8Z8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (countVal)
+                io.WriteInt(32, value.GetInt());
+
+                // Simple Field (valInfField)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (statusOrCommand)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "U16U32U8N8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (manufacturerId)
+                io.WriteUshort(16, value.GetUshort());
+
+                // Simple Field (identNumber)
+                io.WriteUint(32, value.GetUint());
+
+                // Simple Field (version)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (medium)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "A8A8A8A8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (languageCode)
+                io.WriteString(16, "ASCII", value.GetString());
+
+                // Simple Field (regionCode)
+                io.WriteString(16, "ASCII", value.GetString());
+            } else
+            if (formatName == "U8U8U8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (red)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (green)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (blue)
+                io.WriteByte(8, value.GetByte());
+            } else
+            if (formatName == "A8A8Language") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (languageCode)
+                io.WriteString(16, "ASCII", value.GetString());
+            } else
+            if (formatName == "A8A8Region") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (regionCode)
+                io.WriteString(16, "ASCII", value.GetString());
+            } else
+            if (formatName == "V32U8B8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (activeElectricalEnergy)
+                io.WriteInt(32, value.GetInt());
+
+                // Simple Field (tariff)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(6, 0x00);
+
+                // Simple Field (noTariff)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (noActiveElectricalEnergy)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "B1N3N4") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (deactivationOfPriority)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (priorityLevel)
+                io.WriteByte(3, value.GetByte());
+
+                // Simple Field (modeLevel)
+                io.WriteByte(4, value.GetByte());
+            } else
+            if (formatName == "B10U6") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(5, 0x00);
+
+                // Simple Field (convertorError)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (ballastFailure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (lampError)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (read)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (groupAddress)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (address)
+                io.WriteByte(6, value.GetByte());
+            } else
+            if (formatName == "B2U6") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (sceneActivationInactive)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (storageFunctionDisable)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (sceneNumber)
+                io.WriteByte(6, value.GetByte());
+            } else
+            if (formatName == "U8r7B1") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (setValue)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(7, 0x00);
+
+                // Simple Field (channelActivationActive)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U8U8B8") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (heightPosition)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (slatsPosition)
+                io.WriteByte(8, value.GetByte());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(6, 0x00);
+
+                // Simple Field (validSlatsPos)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (validHeightPos)
+                io.WriteBit(value.GetBool());
+            } else
+            if (formatName == "U8U8B16") { // Struct
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(8, 0x0);
+
+                // Simple Field (heightPosition)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (slatsPosition)
+                io.WriteByte(8, value.GetByte());
+
+                // Simple Field (validSlatsPos)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (validHeightPos)
+                io.WriteBit(value.GetBool());
+
+                // Reserved Field (Just skip the bytes)
+                io.WriteByte(3, 0x00);
+
+                // Simple Field (failure)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (localOverride)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (locked)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (forced)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (weatherAlarm)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (targetSPosRestrict)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (targetHPosRestrict)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (driveState)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (lowerPredefPos)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (lowerEndPos)
+                io.WriteBit(value.GetBool());
+
+                // Simple Field (upperEndPos)
+                io.WriteBit(value.GetBool());
+            }         }
+
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/generated/testing/assets/protocols/knxnetip/ParserSerializerTestsuite.xml b/sandbox/plc4net/drivers/knxnetip/generated/testing/assets/protocols/knxnetip/ParserSerializerTestsuite.xml
new file mode 100644
index 0000000..2eae8b6
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/generated/testing/assets/protocols/knxnetip/ParserSerializerTestsuite.xml
@@ -0,0 +1,500 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  -->
+<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd" bigEndian="true">
+
+  <name>KNXNet/IP</name>
+
+  <!--testcase>
+    <name>Causes Failure 1</name>
+    <raw>0610042000180404ce002b0703010404025002bab8b838bb</raw>
+    Raw CEMI Frame: bab8b838bb
+    Raw CEMI Frame: ba
+
+    Decoded as Extended Frame Format:
+    group address: true
+    hop count: 3
+    extended frame format: 8 (1 0 0 0)
+    source address: 11/8/56
+
+    <raw>061004200018047ddf002b07030104040207029f9c9c9cdc</raw>
+    Raw CEMI Frame: 9f9c9c9cdc
+    Control Field: 9f
+
+    Differences from normal:
+    Repeat: True
+    Last two reserved bits are true
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <TunnelingRequest className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingRequest">
+        <tunnelingRequestDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingRequestDataBlock">
+          <communicationChannelId>125</communicationChannelId>
+          <sequenceCounter>223</sequenceCounter>
+        </tunnelingRequestDataBlock>
+        <cemi className="org.apache.plc4x.java.knxnetip.readwrite.CEMIBusmonInd">
+          <additionalInformationLength>7</additionalInformationLength>
+          <additionalInformation>
+            <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationBusmonitorInfo">
+              <frameErrorFlag>false</frameErrorFlag>
+              <bitErrorFlag>false</bitErrorFlag>
+              <parityErrorFlag>false</parityErrorFlag>
+              <unknownFlag>false</unknownFlag>
+              <lostFlag>false</lostFlag>
+              <sequenceNumber>4</sequenceNumber>
+            </additionalInformation>
+            <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationRelativeTimestamp">
+              <relativeTimestamp className="org.apache.plc4x.java.knxnetip.readwrite.RelativeTimestamp">
+                <timestamp>1794</timestamp>
+              </relativeTimestamp>
+            </additionalInformation>
+          </additionalInformation>
+          <cemiFrame className="org.apache.plc4x.java.knxnetip.readwrite.CEMIFramePollingData">
+            <doNotRepeat>false</doNotRepeat>
+            <priority>LOW</priority>
+            <errorFlag>true</errorFlag>
+          </cemiFrame>
+        </cemi>
+      </TunnelingRequest>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Causes Failure 2</name>
+    <raw>0610042000180401c2002b0703010304025601bab8b838bb</raw>
+    Raw CEMI Frame: bab8b838bb
+    Control Field: ba
+    First of the last two reserved bits is true
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <TunnelingRequest className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingRequest">
+        <tunnelingRequestDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingRequestDataBlock">
+          <communicationChannelId>1</communicationChannelId>
+          <sequenceCounter>194</sequenceCounter>
+        </tunnelingRequestDataBlock>
+        <cemi className="org.apache.plc4x.java.knxnetip.readwrite.CEMIBusmonInd">
+          <additionalInformationLength>7</additionalInformationLength>
+          <additionalInformation>
+            <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationBusmonitorInfo">
+              <frameErrorFlag>false</frameErrorFlag>
+              <bitErrorFlag>false</bitErrorFlag>
+              <parityErrorFlag>false</parityErrorFlag>
+              <unknownFlag>false</unknownFlag>
+              <lostFlag>false</lostFlag>
+              <sequenceNumber>3</sequenceNumber>
+            </additionalInformation>
+            <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationRelativeTimestamp">
+              <relativeTimestamp className="org.apache.plc4x.java.knxnetip.readwrite.RelativeTimestamp">
+                <timestamp>22017</timestamp>
+              </relativeTimestamp>
+            </additionalInformation>
+          </additionalInformation>
+          <cemiFrame className="org.apache.plc4x.java.knxnetip.readwrite.CEMIFramePollingData">
+            <doNotRepeat>true</doNotRepeat>
+            <priority>URGENT</priority>
+            <errorFlag>false</errorFlag>
+          </cemiFrame>
+        </cemi>
+      </TunnelingRequest>
+    </xml>
+  </testcase-->
+
+  <testcase>
+    <name>Search Request</name>
+    <raw>06100201000e0801c0a82a46ef8e</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <SearchRequest className="org.apache.plc4x.java.knxnetip.readwrite.SearchRequest">
+        <hpaiIDiscoveryEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDiscoveryEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqRg==</addr>
+          </ipAddress>
+          <ipPort>61326</ipPort>
+        </hpaiIDiscoveryEndpoint>
+      </SearchRequest>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Search Response</name>
+    <raw>06100202004c0801c0a82a0b0e5736010200ffff000000082d409852e000170c000ab327553647697261204b4e582f49502d5363686e6974747374656c6c6500000000000802020103010401</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <SearchResponse className="org.apache.plc4x.java.knxnetip.readwrite.SearchResponse">
+        <hpaiControlEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIControlEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqCw==</addr>
+          </ipAddress>
+          <ipPort>3671</ipPort>
+        </hpaiControlEndpoint>
+        <dibDeviceInfo className="org.apache.plc4x.java.knxnetip.readwrite.DIBDeviceInfo">
+          <descriptionType>1</descriptionType>
+          <knxMedium>MEDIUM_TP1</knxMedium>
+          <deviceStatus className="org.apache.plc4x.java.knxnetip.readwrite.DeviceStatus">
+            <programMode>false</programMode>
+          </deviceStatus>
+          <knxAddress className="org.apache.plc4x.java.knxnetip.readwrite.KnxAddress">
+            <mainGroup>15</mainGroup>
+            <middleGroup>15</middleGroup>
+            <subGroup>255</subGroup>
+          </knxAddress>
+          <projectInstallationIdentifier className="org.apache.plc4x.java.knxnetip.readwrite.ProjectInstallationIdentifier">
+            <projectNumber>0</projectNumber>
+            <installationNumber>0</installationNumber>
+          </projectInstallationIdentifier>
+          <knxNetIpDeviceSerialNumber>AAgtQJhS</knxNetIpDeviceSerialNumber>
+          <knxNetIpDeviceMulticastAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>4AAXDA==</addr>
+          </knxNetIpDeviceMulticastAddress>
+          <knxNetIpDeviceMacAddress className="org.apache.plc4x.java.knxnetip.readwrite.MACAddress">
+            <addr>AAqzJ1U2</addr>
+          </knxNetIpDeviceMacAddress>
+          <deviceFriendlyName>R2lyYSBLTlgvSVAtU2Nobml0dHN0ZWxsZQAAAAAA</deviceFriendlyName>
+        </dibDeviceInfo>
+        <dibSuppSvcFamilies className="org.apache.plc4x.java.knxnetip.readwrite.DIBSuppSvcFamilies">
+          <descriptionType>2</descriptionType>
+          <serviceIds>
+            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpCore">
+              <version>1</version>
+            </serviceIds>
+            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpDeviceManagement">
+              <version>1</version>
+            </serviceIds>
+            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpTunneling">
+              <version>1</version>
+            </serviceIds>
+          </serviceIds>
+        </dibSuppSvcFamilies>
+      </SearchResponse>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Description Request</name>
+    <raw>06100203000e0801000000000000</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <DescriptionRequest className="org.apache.plc4x.java.knxnetip.readwrite.DescriptionRequest">
+        <hpaiControlEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIControlEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>AAAAAA==</addr>
+          </ipAddress>
+          <ipPort>0</ipPort>
+        </hpaiControlEndpoint>
+      </DescriptionRequest>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Description Response</name>
+    <raw>06100204004436010200ffff000000082d409852e000170c000ab327553647697261204b4e582f49502d5363686e6974747374656c6c6500000000000802020103010401</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <DescriptionResponse className="org.apache.plc4x.java.knxnetip.readwrite.DescriptionResponse">
+        <dibDeviceInfo className="org.apache.plc4x.java.knxnetip.readwrite.DIBDeviceInfo">
+          <descriptionType>1</descriptionType>
+          <knxMedium>MEDIUM_TP1</knxMedium>
+          <deviceStatus className="org.apache.plc4x.java.knxnetip.readwrite.DeviceStatus">
+            <programMode>false</programMode>
+          </deviceStatus>
+          <knxAddress className="org.apache.plc4x.java.knxnetip.readwrite.KnxAddress">
+            <mainGroup>15</mainGroup>
+            <middleGroup>15</middleGroup>
+            <subGroup>255</subGroup>
+          </knxAddress>
+          <projectInstallationIdentifier className="org.apache.plc4x.java.knxnetip.readwrite.ProjectInstallationIdentifier">
+            <projectNumber>0</projectNumber>
+            <installationNumber>0</installationNumber>
+          </projectInstallationIdentifier>
+          <knxNetIpDeviceSerialNumber>AAgtQJhS</knxNetIpDeviceSerialNumber>
+          <knxNetIpDeviceMulticastAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>4AAXDA==</addr>
+          </knxNetIpDeviceMulticastAddress>
+          <knxNetIpDeviceMacAddress className="org.apache.plc4x.java.knxnetip.readwrite.MACAddress">
+            <addr>AAqzJ1U2</addr>
+          </knxNetIpDeviceMacAddress>
+          <deviceFriendlyName>R2lyYSBLTlgvSVAtU2Nobml0dHN0ZWxsZQAAAAAA</deviceFriendlyName>
+        </dibDeviceInfo>
+        <dibSuppSvcFamilies className="org.apache.plc4x.java.knxnetip.readwrite.DIBSuppSvcFamilies">
+          <descriptionType>2</descriptionType>
+          <serviceIds>
+            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpCore">
+              <version>1</version>
+            </serviceIds>
+            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpDeviceManagement">
+              <version>1</version>
+            </serviceIds>
+            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpTunneling">
+              <version>1</version>
+            </serviceIds>
+          </serviceIds>
+        </dibSuppSvcFamilies>
+      </DescriptionResponse>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Connect Request</name>
+    <raw>06100205001a0801c0a82a46f4310801c0a82a46f43204040200</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <ConnectionRequest className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionRequest">
+        <hpaiDiscoveryEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDiscoveryEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqRg==</addr>
+          </ipAddress>
+          <ipPort>62513</ipPort>
+        </hpaiDiscoveryEndpoint>
+        <hpaiDataEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDataEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqRg==</addr>
+          </ipAddress>
+          <ipPort>62514</ipPort>
+        </hpaiDataEndpoint>
+        <connectionRequestInformation className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionRequestInformationTunnelConnection">
+          <knxLayer>TUNNEL_LINK_LAYER</knxLayer>
+        </connectionRequestInformation>
+      </ConnectionRequest>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Connect Response</name>
+    <raw>06100206001466000801c0a82a0b0e5704041101</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <ConnectionResponse className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionResponse">
+        <communicationChannelId>102</communicationChannelId>
+        <status>NO_ERROR</status>
+        <hpaiDataEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDataEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqCw==</addr>
+          </ipAddress>
+          <ipPort>3671</ipPort>
+        </hpaiDataEndpoint>
+        <connectionResponseDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionResponseDataBlockTunnelConnection">
+          <knxAddress className="org.apache.plc4x.java.knxnetip.readwrite.KnxAddress">
+            <mainGroup>1</mainGroup>
+            <middleGroup>1</middleGroup>
+            <subGroup>1</subGroup>
+          </knxAddress>
+        </connectionResponseDataBlock>
+      </ConnectionResponse>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Connection State Request</name>
+    <raw>06100207001066000801c0a82a46f431</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <ConnectionStateRequest className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionStateRequest">
+        <communicationChannelId>102</communicationChannelId>
+        <hpaiControlEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIControlEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqRg==</addr>
+          </ipAddress>
+          <ipPort>62513</ipPort>
+        </hpaiControlEndpoint>
+      </ConnectionStateRequest>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Connection State Response</name>
+    <raw>0610020800086600</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <ConnectionStateResponse className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionStateResponse">
+        <communicationChannelId>102</communicationChannelId>
+        <status>NO_ERROR</status>
+      </ConnectionStateResponse>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Device Configuration Request</name>
+    <raw>06100310001104670000fc000001531001</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <DeviceConfigurationRequest className="org.apache.plc4x.java.knxnetip.readwrite.DeviceConfigurationRequest">
+        <deviceConfigurationRequestDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.DeviceConfigurationRequestDataBlock">
+          <communicationChannelId>103</communicationChannelId>
+          <sequenceCounter>0</sequenceCounter>
+        </deviceConfigurationRequestDataBlock>
+        <cemi className="org.apache.plc4x.java.knxnetip.readwrite.CEMIMPropReadReq">
+          <interfaceObjectType>0</interfaceObjectType>
+          <objectInstance>1</objectInstance>
+          <propertyId>83</propertyId>
+          <numberOfElements>1</numberOfElements>
+          <startIndex>1</startIndex>
+        </cemi>
+      </DeviceConfigurationRequest>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Device Configuration Ack</name>
+    <raw>06100311000a04670000</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <DeviceConfigurationAck className="org.apache.plc4x.java.knxnetip.readwrite.DeviceConfigurationAck">
+        <deviceConfigurationAckDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.DeviceConfigurationAckDataBlock">
+          <communicationChannelId>103</communicationChannelId>
+          <sequenceCounter>0</sequenceCounter>
+          <status>NO_ERROR</status>
+        </deviceConfigurationAckDataBlock>
+      </DeviceConfigurationAck>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Disconnect Request</name>
+    <raw>06100209001067000801c0a82a46f431</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <DisconnectRequest className="org.apache.plc4x.java.knxnetip.readwrite.DisconnectRequest">
+        <communicationChannelId>103</communicationChannelId>
+        <hpaiControlEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIControlEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqRg==</addr>
+          </ipAddress>
+          <ipPort>62513</ipPort>
+        </hpaiControlEndpoint>
+      </DisconnectRequest>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Disconnect Response</name>
+    <raw>0610020a00086600</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <DisconnectResponse className="org.apache.plc4x.java.knxnetip.readwrite.DisconnectResponse">
+        <communicationChannelId>102</communicationChannelId>
+        <status>NO_ERROR</status>
+      </DisconnectResponse>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Tunneling Request</name>
+    <raw>06100420001c046b00002b0703010504024502bc360a1e0ce100810d</raw>
+    <!--
+    Raw CEMI Frame: bc360a1e0ce100810d
+    Control Field: bc
+    -->
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <TunnelingRequest className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingRequest">
+        <tunnelingRequestDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingRequestDataBlock">
+          <communicationChannelId>107</communicationChannelId>
+          <sequenceCounter>0</sequenceCounter>
+        </tunnelingRequestDataBlock>
+        <cemi className="org.apache.plc4x.java.knxnetip.readwrite.CEMIBusmonInd">
+          <additionalInformationLength>7</additionalInformationLength>
+          <additionalInformation>
+            <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationBusmonitorInfo">
+              <frameErrorFlag>false</frameErrorFlag>
+              <bitErrorFlag>false</bitErrorFlag>
+              <parityErrorFlag>false</parityErrorFlag>
+              <unknownFlag>false</unknownFlag>
+              <lostFlag>false</lostFlag>
+              <sequenceNumber>5</sequenceNumber>
+            </additionalInformation>
+            <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationRelativeTimestamp">
+              <relativeTimestamp className="org.apache.plc4x.java.knxnetip.readwrite.RelativeTimestamp">
+                <timestamp>17666</timestamp>
+              </relativeTimestamp>
+            </additionalInformation>
+          </additionalInformation>
+          <cemiFrame className="org.apache.plc4x.java.knxnetip.readwrite.CEMIFrameData">
+            <repeated>true</repeated>
+            <priority>LOW</priority>
+            <acknowledgeRequested>false</acknowledgeRequested>
+            <errorFlag>false</errorFlag>
+            <sourceAddress className="org.apache.plc4x.java.knxnetip.readwrite.KnxAddress">
+              <mainGroup>3</mainGroup>
+              <middleGroup>6</middleGroup>
+              <subGroup>10</subGroup>
+            </sourceAddress>
+            <destinationAddress>Hgw=</destinationAddress>
+            <groupAddress>true</groupAddress>
+            <hopCount>6</hopCount>
+            <dataLength>1</dataLength>
+            <tcpi>UNNUMBERED_DATA_PACKET</tcpi>
+            <counter>0</counter>
+            <apci>GROUP_VALUE_WRITE_PDU</apci>
+            <dataFirstByte>1</dataFirstByte>
+            <data></data>
+            <crc>13</crc>
+          </cemiFrame>
+        </cemi>
+      </TunnelingRequest>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Tunneling Response</name>
+    <raw>06100421000a046b0000</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <TunnelingResponse className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingResponse">
+        <tunnelingResponseDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingResponseDataBlock">
+          <communicationChannelId>107</communicationChannelId>
+          <sequenceCounter>0</sequenceCounter>
+          <status>NO_ERROR</status>
+        </tunnelingResponseDataBlock>
+      </TunnelingResponse>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Default</name>
+    <raw>0610020500180801c0a82a46c4090801c0a82a46c40a0203</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <ConnectionRequest className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionRequest">
+        <hpaiDiscoveryEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDiscoveryEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqRg==</addr>
+          </ipAddress>
+          <ipPort>50185</ipPort>
+        </hpaiDiscoveryEndpoint>
+        <hpaiDataEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDataEndpoint">
+          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
+          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
+            <addr>wKgqRg==</addr>
+          </ipAddress>
+          <ipPort>50186</ipPort>
+        </hpaiDataEndpoint>
+        <connectionRequestInformation className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionRequestInformationDeviceManagement"/>
+      </ConnectionRequest>
+    </xml>
+  </testcase>
+
+</test:testsuite>
\ No newline at end of file
diff --git a/sandbox/plc4net/api/api.csproj b/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
similarity index 70%
copy from sandbox/plc4net/api/api.csproj
copy to sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
index eb00812..e783193 100644
--- a/sandbox/plc4net/api/api.csproj
+++ b/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
@@ -22,6 +22,15 @@
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
     <RootNamespace>org.apache.plc4net</RootNamespace>
+    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
+    <Authors>Apache PLC4X</Authors>
+    <Copyright>The Apache Software Foundation</Copyright>
+    <PackageProjectUrl>https://plc4x.apache.org</PackageProjectUrl>
   </PropertyGroup>
 
+  <ItemGroup>
+    <ProjectReference Include="..\..\api\plc4net-api.csproj" />
+    <ProjectReference Include="..\..\spi\plc4net-spi.csproj" />
+  </ItemGroup>
+
 </Project>
diff --git a/sandbox/plc4net/plc4net.sln b/sandbox/plc4net/plc4net.sln
index a872a2d..8e4ebe1 100644
--- a/sandbox/plc4net/plc4net.sln
+++ b/sandbox/plc4net/plc4net.sln
@@ -19,10 +19,13 @@
 # under the License.
 #
 
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.28803.156
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "api", "plc4net\plc4net.csproj", "{343770DC-ECE5-4131-9066-A09C120BB3D9}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "plc4net-api", "api\plc4net-api.csproj", "{7906988A-C7CA-4886-A343-EBC17C0BAB59}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "plc4net-spi", "spi\plc4net-spi.csproj", "{A92DD9F9-1688-4E70-A95E-709E12DBB8C5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "drivers", "drivers", "{35D8C56A-A721-46B3-A32C-71FCF212E85D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "plc4net-driver-knxproj", "drivers\knxnetip\plc4net-driver-knxproj.csproj", "{640E582A-68DF-4E51-B019-AE5774F31B54}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -30,15 +33,20 @@ Global
 		Release|Any CPU = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{343770DC-ECE5-4131-9066-A09C120BB3D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{343770DC-ECE5-4131-9066-A09C120BB3D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{343770DC-ECE5-4131-9066-A09C120BB3D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{343770DC-ECE5-4131-9066-A09C120BB3D9}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
+		{7906988A-C7CA-4886-A343-EBC17C0BAB59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7906988A-C7CA-4886-A343-EBC17C0BAB59}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7906988A-C7CA-4886-A343-EBC17C0BAB59}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7906988A-C7CA-4886-A343-EBC17C0BAB59}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A92DD9F9-1688-4E70-A95E-709E12DBB8C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A92DD9F9-1688-4E70-A95E-709E12DBB8C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A92DD9F9-1688-4E70-A95E-709E12DBB8C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A92DD9F9-1688-4E70-A95E-709E12DBB8C5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{640E582A-68DF-4E51-B019-AE5774F31B54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{640E582A-68DF-4E51-B019-AE5774F31B54}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{640E582A-68DF-4E51-B019-AE5774F31B54}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{640E582A-68DF-4E51-B019-AE5774F31B54}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {DCB0DDB3-E6AA-4801-844E-5C71EB50CB1B}
+	GlobalSection(NestedProjects) = preSolution
+		{640E582A-68DF-4E51-B019-AE5774F31B54} = {35D8C56A-A721-46B3-A32C-71FCF212E85D}
 	EndGlobalSection
 EndGlobal
diff --git a/sandbox/plc4net/pom.xml b/sandbox/plc4net/pom.xml
index ab7bdb8..418a489 100644
--- a/sandbox/plc4net/pom.xml
+++ b/sandbox/plc4net/pom.xml
@@ -38,9 +38,103 @@
     <sonar.language>c#</sonar.language>
   </properties-->
 
-  <modules>
-    <module>api</module>
-    <module>plc4net.driver</module>
-  </modules>
+  <build>
+    <plugins>
+      <!-- Copy the test-resources in here -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>unpack-protocol-test-suites</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.apache.plc4x</groupId>
+                  <artifactId>plc4x-protocols-knxnetip</artifactId>
+                  <classifier>tests</classifier>
+                  <type>test-jar</type>
+                  <outputDirectory>${project.basedir}/drivers/knxnetip/generated/testing/assets</outputDirectory>
+                  <includes>**/*.xml</includes>
+                  <excludes>META-INF/**,org/**</excludes>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!--
+        Generate the driver code.
+      -->
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-driver-knxnetip</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>knxnetip</protocolName>
+              <languageName>C#</languageName>
+              <outputFlavor>read-write</outputFlavor>
+              <outputDir>${project.basedir}/drivers/knxnetip/generated/sources</outputDir>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Build the project -->
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>dotnet-build</id>
+            <phase>compile</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>dotnet</executable>
+              <workingDirectory>${project.basedir}</workingDirectory>
+              <arguments>
+                <argument>build</argument>
+                <argument>plc4net.sln</argument>
+                <argument>--configuration=Debug</argument>
+                <argument>--output=${project.build.directory}/build</argument>
+                <argument>-p:Version=${project.version}</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-language-cs</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-protocols-knxnetip</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/sandbox/plc4net/api/api.csproj b/sandbox/plc4net/spi/plc4net-spi.csproj
similarity index 57%
rename from sandbox/plc4net/api/api.csproj
rename to sandbox/plc4net/spi/plc4net-spi.csproj
index eb00812..26090c5 100644
--- a/sandbox/plc4net/api/api.csproj
+++ b/sandbox/plc4net/spi/plc4net-spi.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
@@ -19,9 +19,21 @@
 -->
 <Project Sdk="Microsoft.NET.Sdk">
 
-  <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
-    <RootNamespace>org.apache.plc4net</RootNamespace>
-  </PropertyGroup>
+    <PropertyGroup>
+        <TargetFramework>netstandard2.0</TargetFramework>
+        <RootNamespace>org.apache.plc4net</RootNamespace>
+        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
+        <Authors>Apache PLC4X</Authors>
+        <Copyright>The Apache Software Foundation</Copyright>
+        <PackageProjectUrl>https://plc4x.apache.org</PackageProjectUrl>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <ProjectReference Include="..\api\plc4net-api.csproj" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <PackageReference Include="Ayx.BitIO" Version="1.0.0" />
+    </ItemGroup>
 
 </Project>
diff --git a/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs b/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs
new file mode 100644
index 0000000..a14ff8c
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs
@@ -0,0 +1,203 @@
+//
+// 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.
+//
+
+using System;
+using System.Text;
+using Ayx.BitIO;
+
+namespace org.apache.plc4net.spi.generation
+{
+    
+    public class ReadBuffer
+    {
+        private readonly byte[] _data;
+        private readonly BitReader _reader;
+
+        public ReadBuffer(byte[] data)
+        {
+            this._data = data;
+            _reader = new BitReader(data);
+        }
+
+        public void Reset()
+        {
+            _reader.Position = 0;
+        }
+
+        public int GetPos()
+        {
+            return _reader.Position;
+        }
+
+        public byte[] GetBytes()
+        {
+            return _data;
+        }
+    
+        public int GetTotalBytes() 
+        {
+            return _data.Length;
+        }
+
+        public bool HasMore(int bitLength)
+        {
+            return bitLength < _reader.Remain;
+        }
+
+        public byte PeekByte(int offset)
+        {
+            return _data[(_reader.Position / 8) + offset];
+        }
+
+        public bool ReadBit()
+        {
+            return _reader.ReadBool();
+        }
+
+        public byte ReadByte(int bitLength)
+        {
+            if ((bitLength < 0) || (bitLength > 8)) 
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (byte) _reader.ReadInt(0, bitLength);
+        }
+        
+        public ushort ReadUshort(int bitLength)
+        {
+            if ((bitLength < 0) || (bitLength > 16)) 
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (ushort) _reader.ReadInt(0, bitLength);
+        }
+
+        public uint ReadUint(int bitLength)
+        {
+            if ((bitLength < 0) || (bitLength > 32)) 
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (uint) _reader.ReadInt(0, bitLength);
+        }
+
+        public ulong ReadUlong(int bitLength)
+        {
+            if ((bitLength < 0) || (bitLength > 64)) 
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+
+            ulong firstInt = 0;
+            if (bitLength > 32)
+            {
+                firstInt = (ulong) _reader.ReadInt(0, bitLength - 32) << 32;
+            }
+            return firstInt | (ulong) _reader.ReadInt(0, bitLength);
+        }
+
+        public sbyte ReadSbyte(int bitLength)
+        {
+            if ((bitLength < 0) || (bitLength > 8)) 
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (sbyte) _reader.ReadInt(0, bitLength);
+        }
+        
+        public short ReadShort(int bitLength)
+        {
+            if ((bitLength < 0) || (bitLength > 16)) 
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (short) _reader.ReadInt(0, bitLength);
+        }
+
+        public int ReadInt(int bitLength)
+        {
+            if ((bitLength < 0) || (bitLength > 32)) 
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (int) _reader.ReadInt(0, bitLength);
+        }
+
+        public long ReadLong(int bitLength)
+        {
+            if ((bitLength < 0) || (bitLength > 64)) 
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+
+            long firstInt = 0;
+            if (bitLength > 32)
+            {
+                firstInt = (long) _reader.ReadInt(0, bitLength - 32) << 32;
+            }
+            return firstInt | (long) _reader.ReadInt(0, bitLength);
+        }
+
+        public float ReadFloat(bool signed, int exponentBitLength, int mantissaBitLength)
+        {
+            if (signed && exponentBitLength == 8 && mantissaBitLength == 23)
+            {
+                return Convert.ToSingle(ReadInt(32));
+            }
+            // This is the format as described in the KNX spec ... it's not a real half precision floating point.
+            if (signed && exponentBitLength == 4 && mantissaBitLength == 11)
+            {
+                bool sign = true;
+                if (signed) {
+                    sign = _reader.ReadBool();
+                }
+
+                var exp = _reader.ReadInt(exponentBitLength);
+                var mantissa = _reader.ReadInt(mantissaBitLength);
+                // In the mantissa notation actually the first bit is omitted, we need to add it back
+                var f = 0.01 * mantissa * Math.Pow(2, exp);
+                if (sign)
+                {
+                    return (float) f * -1;
+                }
+                return (float) f;
+            }
+            throw new NotImplementedException("This encoding is currently not supported");
+        }
+
+        public double ReadDouble(bool signed, int exponentBitLength, int mantissaBitLength)
+        {
+            if (signed && exponentBitLength == 8 && mantissaBitLength == 23)
+            {
+                return Convert.ToDouble(ReadInt(32));
+            }
+            if (signed && exponentBitLength == 11 && mantissaBitLength == 52)
+            {
+                return Convert.ToDouble(ReadLong(64));
+            }
+            throw new NotImplementedException("This encoding is currently not supported");
+        }
+
+        public string ReadString(int bitLength, Encoding encoding)
+        {
+            return "";
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/generation/WriteBuffer.cs b/sandbox/plc4net/spi/spi/generation/WriteBuffer.cs
new file mode 100644
index 0000000..5f4b3b1
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/generation/WriteBuffer.cs
@@ -0,0 +1,89 @@
+//
+// 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.
+//
+
+namespace org.apache.plc4net.spi.generation
+{
+    public class WriteBuffer
+    {
+        
+        public int GetPos()
+        {
+            return 0;
+        }
+
+        public byte[] GetBytes()
+        {
+            return null;
+        }
+    
+        public int GetTotalBytes() 
+        {
+            return 0;
+        }
+
+        public void WriteBit(bool value)
+        {
+        }
+
+        public void WriteByte(int bitLength, byte value)
+        {
+        }
+        
+        public void WriteUshort(int bitLength, ushort value)
+        {
+        }
+
+        public void WriteUint(int bitLength, uint value)
+        {
+        }
+
+        public void WriteUlong(int bitLength, ulong value)
+        {
+        }
+
+        public void WriteSbyte(int bitLength, sbyte value)
+        {
+        }
+        
+        public void WriteShort(int bitLength, short value)
+        {
+        }
+
+        public void WriteInt(int bitLength, int value)
+        {
+        }
+
+        public void WriteLong(int bitLength, long value)
+        {
+        }
+
+        public void WriteFloat(int bitLength, float value)
+        {
+        }
+
+        public void WriteDouble(int bitLength, double value)
+        {
+        }
+
+        public void WriteString(int bitLength, string encoding, string value)
+        {
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs b/sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs
new file mode 100644
index 0000000..a3a11ad
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcBOOL : PlcSimpleValueAdapter
+    {
+        private bool value;
+        
+        public PlcBOOL(bool value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs b/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs
new file mode 100644
index 0000000..5c3d26e
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcBYTE : PlcBitString
+    {
+        private byte value;
+        public PlcBYTE(byte value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcBitString.cs b/sandbox/plc4net/spi/spi/model/values/PlcBitString.cs
new file mode 100644
index 0000000..4bcbcba
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcBitString.cs
@@ -0,0 +1,7 @@
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcBitString : PlcValueAdapter
+    {
+
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs b/sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs
new file mode 100644
index 0000000..958bb0f
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcCHAR : PlcSimpleValueAdapter
+    {
+        private char value;
+        
+        public PlcCHAR(char value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcDATE.cs b/sandbox/plc4net/spi/spi/model/values/PlcDATE.cs
new file mode 100644
index 0000000..d51b3c4
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcDATE.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+using System;
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcDATE : PlcValueAdapter
+    {
+        private DateTime value;
+        
+        public PlcDATE(DateTime value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcDATE_AND_TIME.cs b/sandbox/plc4net/spi/spi/model/values/PlcDATE_AND_TIME.cs
new file mode 100644
index 0000000..1a9b528
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcDATE_AND_TIME.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using System;
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcDATE_AND_TIME : PlcValueAdapter
+    {
+        private DateTime value;
+        public PlcDATE_AND_TIME(DateTime value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcDINT.cs b/sandbox/plc4net/spi/spi/model/values/PlcDINT.cs
new file mode 100644
index 0000000..948b114
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcDINT.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcDINT : SimpleNumericValueAdapter<int>
+    {
+        public PlcDINT(int value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs
new file mode 100644
index 0000000..dad1973
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcDWORD : PlcBitString
+    {
+        private uint value;
+        
+        public PlcDWORD(uint value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcINT.cs b/sandbox/plc4net/spi/spi/model/values/PlcINT.cs
new file mode 100644
index 0000000..1dfee20
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcINT.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcINT : SimpleNumericValueAdapter<short>
+    {
+        public PlcINT(short value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcLINT.cs b/sandbox/plc4net/spi/spi/model/values/PlcLINT.cs
new file mode 100644
index 0000000..0bdfdd8
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcLINT.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcLINT : SimpleNumericValueAdapter<long>
+    {
+        public PlcLINT(long value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcLREAL.cs b/sandbox/plc4net/spi/spi/model/values/PlcLREAL.cs
new file mode 100644
index 0000000..91dc4b5
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcLREAL.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcLREAL : SimpleNumericValueAdapter<double>
+    {
+        public PlcLREAL(double value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs b/sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs
new file mode 100644
index 0000000..cfd3b7c
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+using System;
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcLTIME : PlcSimpleValueAdapter
+    {
+        private DateTime value;
+        
+        public PlcLTIME(DateTime value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs
new file mode 100644
index 0000000..bfe68af
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcLWORD : PlcBitString
+    {
+        private ulong value;
+        
+        public PlcLWORD(ulong value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcNULL.cs b/sandbox/plc4net/spi/spi/model/values/PlcNULL.cs
new file mode 100644
index 0000000..1822fd1
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcNULL.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcNULL : PlcValueAdapter
+    {
+        public PlcNULL()
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs b/sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs
new file mode 100644
index 0000000..1930a60
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+using System.Collections.Generic;
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcList : PlcValueAdapter
+    {
+        private List<IPlcValue> values;
+        
+        public PlcList(List<IPlcValue> values)
+        {
+            this.values = values;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcREAL.cs b/sandbox/plc4net/spi/spi/model/values/PlcREAL.cs
new file mode 100644
index 0000000..f3c1976
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcREAL.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcREAL : SimpleNumericValueAdapter<float>
+    {
+        public PlcREAL(float value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcSINT.cs b/sandbox/plc4net/spi/spi/model/values/PlcSINT.cs
new file mode 100644
index 0000000..c04fcef
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcSINT.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcSINT : SimpleNumericValueAdapter<sbyte>
+    {
+        public PlcSINT(sbyte value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs b/sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs
new file mode 100644
index 0000000..be41810
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcSTRING : PlcSimpleValueAdapter
+    {
+        private string value;
+        
+        public PlcSTRING(string value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs b/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs
new file mode 100644
index 0000000..2f0cbba
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs
@@ -0,0 +1,175 @@
+using System;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public abstract class SimpleNumericValueAdapter<T> : PlcSimpleValueAdapter where T : IComparable
+    {
+        private IComparable value;
+
+        public SimpleNumericValueAdapter(IComparable value)
+        {
+            this.value = value;
+        }
+        
+        public new bool IsBool()
+        {
+            return true;
+        }
+        
+        public new bool GetBool()
+        {
+            return value.CompareTo(0) != 0;
+        }
+        
+        public new bool IsByte()
+        {
+            return (value.CompareTo(byte.MinValue) >= 0) && (value.CompareTo(byte.MaxValue) <= 0);
+        }
+
+        public new byte GetByte()
+        {
+            if (!IsByte())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (byte) value;
+        }
+
+        public new bool IsUshort()
+        {
+            return (value.CompareTo(ushort.MinValue) >= 0) && (value.CompareTo(ushort.MaxValue) <= 0);
+        }
+
+        public new ushort GetUshort()
+        {
+            if (!IsUshort())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (ushort) value;
+        }
+
+        public new bool IsUint()
+        {
+            return (value.CompareTo(uint.MinValue) >= 0) && (value.CompareTo(uint.MaxValue) <= 0);
+        }
+
+        public new uint GetUint()
+        {
+            if (!IsUint())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (uint) value;
+        }
+
+        public new bool IsUlong()
+        {
+            return (value.CompareTo(ulong.MinValue) >= 0) && (value.CompareTo(ulong.MaxValue) <= 0);
+        }
+
+        public new ulong GetUlong()
+        {
+            if (!IsUlong())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (ulong) value;
+        }
+
+        public new bool IsSbyte()
+        {
+            return (value.CompareTo(sbyte.MinValue) >= 0) && (value.CompareTo(sbyte.MaxValue) <= 0);
+        }
+
+        public new sbyte GetSbyte()
+        {
+            if (!IsSbyte())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (sbyte) value;
+        }
+
+        public new bool IsShort()
+        {
+            return (value.CompareTo(short.MinValue) >= 0) && (value.CompareTo(short.MaxValue) <= 0);
+        }
+
+        public new short GetShort()
+        {
+            if (!IsShort())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (short) value;
+        }
+
+        public new bool IsInt()
+        {
+            return (value.CompareTo(int.MinValue) >= 0) && (value.CompareTo(int.MaxValue) <= 0);
+        }
+
+        public new int GetInt()
+        {
+            if (!IsInt())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (int) value;
+        }
+
+        public new bool IsLong()
+        {
+            return (value.CompareTo(long.MinValue) >= 0) && (value.CompareTo(long.MaxValue) <= 0);
+        }
+
+        public new long GetLong()
+        {
+            if (!IsLong())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (long) value;
+        }
+
+        public new bool IsFloat()
+        {
+            return (value.CompareTo(-float.MaxValue) >= 0) && (value.CompareTo(float.MaxValue) <= 0);
+        }
+
+        public new float GetFloat()
+        {
+            if (!IsFloat())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (float) value;
+        }
+
+        public new bool IsDouble()
+        {
+            return (value.CompareTo(-double.MaxValue) >= 0) && (value.CompareTo(double.MaxValue) <= 0);
+        }
+
+        public new double GetDouble()
+        {
+            if (!IsDouble())
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+            return (double) value;
+        }
+
+        public new bool IsString()
+        {
+            return true;
+        }
+
+        public new String GetString()
+        {
+            return value.ToString();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcSimpleValueAdapter.cs b/sandbox/plc4net/spi/spi/model/values/PlcSimpleValueAdapter.cs
new file mode 100644
index 0000000..52a64b9
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcSimpleValueAdapter.cs
@@ -0,0 +1,17 @@
+namespace org.apache.plc4net.spi.model.values
+{
+    public abstract class PlcSimpleValueAdapter : PlcValueAdapter
+    {
+       
+        public  bool IsSimple()
+        {
+            return true;
+        }
+
+        public int GetLength()
+        {
+            return 1;
+        }
+        
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcStruct.cs b/sandbox/plc4net/spi/spi/model/values/PlcStruct.cs
new file mode 100644
index 0000000..206fac3
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcStruct.cs
@@ -0,0 +1,37 @@
+//
+// 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.
+//
+
+using System.Collections.Generic;
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    
+    public class PlcStruct : PlcValueAdapter
+    {
+        private Dictionary<string, IPlcValue> values;
+        
+        public PlcStruct(Dictionary<string, IPlcValue> values)
+        {
+            this.values = values;
+        }
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcTIME _OF_DAY.cs b/sandbox/plc4net/spi/spi/model/values/PlcTIME _OF_DAY.cs
new file mode 100644
index 0000000..2c3c67a
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcTIME _OF_DAY.cs	
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+using System;
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcTIME_OF_DAY : PlcSimpleValueAdapter
+    {
+        private DateTime value;
+        
+        public PlcTIME_OF_DAY(DateTime value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcTIME.cs b/sandbox/plc4net/spi/spi/model/values/PlcTIME.cs
new file mode 100644
index 0000000..0d78c57
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcTIME.cs
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+using System;
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcTIME : PlcSimpleValueAdapter
+    {
+        private DateTime value;
+         
+        public PlcTIME(DateTime value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcUDINT.cs b/sandbox/plc4net/spi/spi/model/values/PlcUDINT.cs
new file mode 100644
index 0000000..2cd4e00
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcUDINT.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcUDINT : SimpleNumericValueAdapter<uint>
+    {
+        public PlcUDINT(uint value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcUINT.cs b/sandbox/plc4net/spi/spi/model/values/PlcUINT.cs
new file mode 100644
index 0000000..e06e9e2
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcUINT.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcUINT : SimpleNumericValueAdapter<ushort>
+    {
+        public PlcUINT(ushort value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcULINT.cs b/sandbox/plc4net/spi/spi/model/values/PlcULINT.cs
new file mode 100644
index 0000000..a281066
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcULINT.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcULINT : SimpleNumericValueAdapter<ulong>
+    {
+        public PlcULINT(ulong value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcUSINT.cs b/sandbox/plc4net/spi/spi/model/values/PlcUSINT.cs
new file mode 100644
index 0000000..c1b031d
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcUSINT.cs
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcUSINT : SimpleNumericValueAdapter<byte>
+    {
+        public PlcUSINT(byte value) : base(value)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcValueAdapter.cs b/sandbox/plc4net/spi/spi/model/values/PlcValueAdapter.cs
new file mode 100644
index 0000000..f5227f6
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcValueAdapter.cs
@@ -0,0 +1,223 @@
+using System;
+using System.Collections.Generic;
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public abstract class PlcValueAdapter : IPlcValue
+    {
+        public bool IsSimple()
+        {
+            return false;
+        }
+
+        public bool IsNullable()
+        {
+            return false;
+        }
+
+        public bool IsNull()
+        {
+            return false;
+        }
+
+        public bool IsBool()
+        {
+            return false;
+        }
+
+        public int GetBoolLength()
+        {
+            return 1;
+        }
+
+        public bool GetBool()
+        {
+            return default;
+        }
+
+        public bool GetBoolAt(int index)
+        {
+            if (index == 0)
+            {
+                return GetBool();
+            }
+            return default;
+        }
+
+        public bool[] GetBoolArray()
+        {
+            return default;
+        }
+
+        public bool IsByte()
+        {
+            return false;
+        }
+
+        public byte GetByte()
+        {
+            return default;
+        }
+
+        public bool IsUshort()
+        {
+            return false;
+        }
+
+        public ushort GetUshort()
+        {
+            return default;
+        }
+
+        public bool IsUint()
+        {
+            return false;
+        }
+
+        public uint GetUint()
+        {
+            return default;
+        }
+
+        public bool IsUlong()
+        {
+            return false;
+        }
+
+        public ulong GetUlong()
+        {
+            return default;
+        }
+
+        public bool IsSbyte()
+        {
+            return false;
+        }
+
+        public sbyte GetSbyte()
+        {
+            return default;
+        }
+
+        public bool IsShort()
+        {
+            return false;
+        }
+
+        public short GetShort()
+        {
+            return default;
+        }
+
+        public bool IsInt()
+        {
+            return false;
+        }
+
+        public int GetInt()
+        {
+            return default;
+        }
+
+        public bool IsLong()
+        {
+            return false;
+        }
+
+        public long GetLong()
+        {
+            return default;
+        }
+
+        public bool IsFloat()
+        {
+            return false;
+        }
+
+        public float GetFloat()
+        {
+            return default;
+        }
+
+        public bool IsDouble()
+        {
+            return false;
+        }
+
+        public double GetDouble()
+        {
+            return default;
+        }
+
+        public bool IsString()
+        {
+            return false;
+        }
+
+        public string GetString()
+        {
+            return default;
+        }
+
+        public bool IsDateTime()
+        {
+            return false;
+        }
+
+        public DateTime GetDateTime()
+        {
+            return default;
+        }
+
+        public byte[] GetRaw()
+        {
+            return default;
+        }
+
+        public bool IsList()
+        {
+            return false;
+        }
+
+        public int GetLength()
+        {
+            return 1;
+        }
+
+        public IPlcValue GetIndex(int index)
+        {
+            return default;
+        }
+
+        public IPlcValue[] GetList()
+        {
+            return default;
+        }
+
+        public bool IsStruct()
+        {
+            return false;
+        }
+
+        public string[] GetKeys()
+        {
+            return default;
+        }
+
+        public bool HasKey(string key)
+        {
+            return false;
+        }
+
+        public IPlcValue GetValue(string key)
+        {
+            return default;
+        }
+
+        public Dictionary<string, IPlcValue> GetStruct()
+        {
+            return default;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs b/sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs
new file mode 100644
index 0000000..5b34f8a
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcWCHAR : PlcSimpleValueAdapter
+    {
+        private char value;
+        
+        public PlcWCHAR(char value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs
new file mode 100644
index 0000000..2af3b09
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcWORD : PlcBitString
+    {
+        private ushort value;
+        
+        public PlcWORD(ushort value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs b/sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs
new file mode 100644
index 0000000..e344e7e
--- /dev/null
+++ b/sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+using org.apache.plc4net.api.value;
+
+namespace org.apache.plc4net.spi.model.values
+{
+    public class PlcWSTRING : PlcSimpleValueAdapter
+    {
+        private string value;
+        
+        public PlcWSTRING(string value)
+        {
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file

[plc4x] 02/09: - Got the code generation for Reading working again.

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

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

commit 00be64f9ec7d2f2cd5b8528b4c04b2c8ade6d3a7
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Dec 3 13:32:00 2020 +0100

    - Got the code generation for Reading working again.
---
 .../language/cs/CsLanguageTemplateHelper.java      |   3 +-
 .../resources/templates/cs/data-io-template.ftlh   |   3 +-
 .../knxnetip/readwrite/model/KnxDatapoint.cs       | 293 +++++++++++----------
 3 files changed, 151 insertions(+), 148 deletions(-)

diff --git a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
index 223654d..d144a0e 100644
--- a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
+++ b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
@@ -301,7 +301,8 @@ public class CsLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
             }
             case STRING: {
                 StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
-                return "io.ReadString(" + stringTypeReference.getSizeInBits() + ")";
+                return "io.ReadString(" + stringTypeReference.getSizeInBits() + ", Encoding.GetEncoding(\"" +
+                    stringTypeReference.getEncoding().substring(1, stringTypeReference.getEncoding().length() - 1) + "\"))";
             }
         }
         return "Hurz";
diff --git a/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh b/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh
index 12aa63c..ae9c8df 100644
--- a/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh
+++ b/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh
@@ -63,6 +63,7 @@ ${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/m
 
 using System;
 using System.Collections.Generic;
+using System.Text;
 using org.apache.plc4net.api.value;
 using org.apache.plc4net.spi.generation;
 using org.apache.plc4net.spi.model.values;
@@ -109,7 +110,7 @@ namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFl
                 <#case "reserved">
                     <#assign reservedField = field>
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 ${helper.getReadBufferReadMethodCall(field.type)};
                     <#break>
                 <#case "simple">
diff --git a/sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs b/sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs
index 9a9d0b3..5ea12a9 100644
--- a/sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs
+++ b/sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs
@@ -19,6 +19,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Text;
 using org.apache.plc4net.api.value;
 using org.apache.plc4net.spi.generation;
 using org.apache.plc4net.spi.model.values;
@@ -33,7 +34,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
         {
             if (formatName == "B1") { // BOOL
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(7);
 
                 // Simple Field (value)
@@ -44,7 +45,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B2") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(6);
 
                 // Simple Field (control)
@@ -60,7 +61,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B1U3") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (control)
@@ -75,27 +76,27 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "A8_ASCII") { // STRING
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
-                var value = io.ReadString(8);
+                var value = io.ReadString(8, Encoding.GetEncoding("ASCII"));
 
                 return new PlcSTRING(value);
             } else
             if (formatName == "A8_8859_1") { // STRING
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
-                var value = io.ReadString(8);
+                var value = io.ReadString(8, Encoding.GetEncoding("ISO-8859-1"));
 
                 return new PlcSTRING(value);
             } else
             if (formatName == "U8") { // USINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -105,7 +106,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "V8") { // SINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -116,7 +117,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B5N3") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(3);
 
                 // Simple Field (a)
@@ -147,7 +148,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "U16") { // UINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -157,7 +158,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "V16") { // INT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -167,7 +168,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "F16") { // REAL
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -177,7 +178,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "N3N5r2N6r2N6") { // TIME_OF_DAY
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (day)
@@ -186,13 +187,13 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 // Simple Field (hour)
                 var hour = io.ReadByte(5);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(2);
 
                 // Simple Field (minutes)
                 var minutes = io.ReadByte(6);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(2);
 
                 // Simple Field (seconds)
@@ -203,22 +204,22 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "r3N5r4N4r1U7") { // DATE
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(3);
 
                 // Simple Field (day)
                 var day = io.ReadByte(5);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (month)
                 var month = io.ReadByte(4);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(1);
 
                 // Simple Field (year)
@@ -229,7 +230,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "U32") { // UDINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -239,7 +240,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "V32") { // DINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -249,7 +250,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "F32") { // REAL
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -260,7 +261,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U4U4U4U4U4U4B4N4") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (d6)
@@ -311,27 +312,27 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "A112_ASCII") { // STRING
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
-                var value = io.ReadString(112);
+                var value = io.ReadString(112, Encoding.GetEncoding("ASCII"));
 
                 return new PlcSTRING(value);
             } else
             if (formatName == "A112_8859_1") { // STRING
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
-                var value = io.ReadString(112);
+                var value = io.ReadString(112, Encoding.GetEncoding("ISO-8859-1"));
 
                 return new PlcSTRING(value);
             } else
             if (formatName == "r2U6") { // USINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(2);
 
                 // Simple Field (value)
@@ -342,14 +343,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B1r1U6") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (learn)
                 var learn = io.ReadBit();
                 internalMap["Struct"] = new PlcBOOL(learn);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(1);
 
                 // Simple Field (sceneNumber)
@@ -360,19 +361,19 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "U8r4U4r3U5U3U5r2U6r2U6B16") { // DATE_AND_TIME
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (year)
                 var year = io.ReadByte(8);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (month)
                 var month = io.ReadByte(4);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(3);
 
                 // Simple Field (day)
@@ -384,13 +385,13 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 // Simple Field (hour)
                 var hour = io.ReadByte(5);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(2);
 
                 // Simple Field (minutes)
                 var minutes = io.ReadByte(6);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(2);
 
                 // Simple Field (seconds)
@@ -428,7 +429,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "N8") { // USINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -438,7 +439,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "B8") { // BYTE
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -448,7 +449,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "B16") { // WORD
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -459,7 +460,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U4U4") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (busy)
@@ -475,10 +476,10 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "r1b1U6") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(1);
 
                 // Simple Field (sceneActive)
@@ -493,7 +494,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "B32") { // DWORD
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -503,7 +504,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "V64") { // LINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (value)
@@ -513,7 +514,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "B24") { // List
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Array Field (value);
@@ -527,7 +528,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             } else
             if (formatName == "N3") { // USINT
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(5);
 
                 // Simple Field (value)
@@ -538,7 +539,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B1Z8HeatingOrCoolingZ") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(7);
 
                 // Simple Field (heating)
@@ -554,7 +555,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B1Z8BinaryValueZ") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(7);
 
                 // Simple Field (high)
@@ -570,7 +571,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "N8Z8HvacOperatingMode") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (hvacOperatingMode)
@@ -586,7 +587,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "N8Z8DhwMode") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (dhwMode)
@@ -602,7 +603,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "N8Z8HvacControllingMode") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (hvacControllingMode)
@@ -618,7 +619,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "N8Z8EnableHeatingOrCoolingStage") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (enableHeatingOrCoolingStage)
@@ -634,7 +635,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "N8Z8BuildingMode") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (buildingMode)
@@ -650,7 +651,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "N8Z8OccupancyMode") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (occupancyMode)
@@ -666,7 +667,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "N8Z8EmergencyMode") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (hvacEmergencyMode)
@@ -682,7 +683,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8Z8Rel") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (relValue)
@@ -698,7 +699,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8Z8Counter") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (counterValue)
@@ -714,7 +715,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8TimePeriod") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (timePeriod)
@@ -730,7 +731,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8FlowRate") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (flowRate)
@@ -746,7 +747,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8Counter") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (counterValue)
@@ -762,7 +763,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8ElectricCurrent") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (electricalCurrent)
@@ -778,7 +779,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8Power") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (power)
@@ -794,7 +795,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8AtmPressure") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (atmPressure)
@@ -810,7 +811,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8PercentValue") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (percentValue)
@@ -826,7 +827,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8HvacAirQuality") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (ppmResolution)
@@ -842,7 +843,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8WindSpeed") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (windSpeed)
@@ -858,7 +859,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8SunIntensity") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (sunIntensity)
@@ -874,7 +875,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16Z8HvacAirFlow") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (airFlow)
@@ -890,7 +891,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V8Z8RelSignedValue") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (relSignedValue)
@@ -906,7 +907,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16Z8DeltaTime") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (deltaTime)
@@ -922,7 +923,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16Z8RelSignedValue") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (relSignedValue)
@@ -938,7 +939,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16N8HvacModeAndTimeDelay") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (delayTime)
@@ -954,7 +955,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16N8DhwModeAndTimeDelay") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (delayTime)
@@ -970,7 +971,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16N8OccupancyModeAndTimeDelay") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (delayTime)
@@ -986,7 +987,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16N8BuildingModeAndTimeDelay") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (delayTime)
@@ -1002,14 +1003,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8B8StatusBurnerController") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (actualRelativePower)
                 var actualRelativePower = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(actualRelativePower);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (stage2Active)
@@ -1033,14 +1034,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8B8LockingSignal") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (requestedPowerReduction)
                 var requestedPowerReduction = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(requestedPowerReduction);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(6);
 
                 // Simple Field (critical)
@@ -1056,14 +1057,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8B8BoilerControllerDemandSignal") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (relativeDemand)
                 var relativeDemand = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(relativeDemand);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(6);
 
                 // Simple Field (controlsOperationStage2)
@@ -1079,14 +1080,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8B8ActuatorPositionDemand") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (actuatorPositionDemand)
                 var actuatorPositionDemand = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(actuatorPositionDemand);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (emergencyDemand)
@@ -1110,14 +1111,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8B8ActuatorPositionStatus") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (actualActuatorPosition)
                 var actualActuatorPosition = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(actualActuatorPosition);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(3);
 
                 // Simple Field (synchronizationMode)
@@ -1145,7 +1146,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8B8StatusLightingActuator") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (lightingLevel)
@@ -1189,14 +1190,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16B8HeatProducerManagerStatus") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (tempFlowProdSegmH)
                 var tempFlowProdSegmH = io.ReadFloat(true, 4, 11);
                 internalMap["Struct"] = new PlcREAL(tempFlowProdSegmH);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(3);
 
                 // Simple Field (temporarilyOff)
@@ -1224,14 +1225,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16B8RoomTemperatureDemand") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (roomTemperatureDemand)
                 var roomTemperatureDemand = io.ReadFloat(true, 4, 11);
                 internalMap["Struct"] = new PlcREAL(roomTemperatureDemand);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (emergencyDemand)
@@ -1255,14 +1256,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16B8ColdWaterProducerManagerStatus") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (flowTemperatureProdSegmC)
                 var flowTemperatureProdSegmC = io.ReadFloat(true, 4, 11);
                 internalMap["Struct"] = new PlcREAL(flowTemperatureProdSegmC);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (temporarilyOff)
@@ -1286,14 +1287,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16B8WaterTemperatureControllerStatus") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (actualTemperature)
                 var actualTemperature = io.ReadFloat(true, 4, 11);
                 internalMap["Struct"] = new PlcREAL(actualTemperature);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(5);
 
                 // Simple Field (controllerWorking)
@@ -1313,14 +1314,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16B16") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (flowTemperatureDemand)
                 var flowTemperatureDemand = io.ReadFloat(true, 4, 11);
                 internalMap["Struct"] = new PlcREAL(flowTemperatureDemand);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (demandFromDhwWhileLegionellaFunctionIsActive)
@@ -1376,7 +1377,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8N8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (energyDemand)
@@ -1392,7 +1393,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16V16V16RoomTemperature") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (temperatureSetpointComfort)
@@ -1412,7 +1413,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16V16V16RoomTemperatureShift") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (temperatureSetpointShiftComfort)
@@ -1432,7 +1433,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16V16V16V16RoomTemperature") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (temperatureSetpointComfort)
@@ -1456,7 +1457,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16V16V16V16DhwtTemperature") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (temperatureSetpointLegioProtect)
@@ -1480,7 +1481,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16V16V16V16RoomTemperatureShift") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (temperatureSetpointShiftComfort)
@@ -1504,7 +1505,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16U8B8Heat") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (flowTemperatureDemand)
@@ -1515,7 +1516,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var relativePower = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(relativePower);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(2);
 
                 // Simple Field (boilerEnabled)
@@ -1547,7 +1548,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16U8B8ChilledWater") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (chilledWaterFlowTemperatureDemand)
@@ -1558,7 +1559,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var relativePower = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(relativePower);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(5);
 
                 // Simple Field (chilledWaterPumpEnabled)
@@ -1578,7 +1579,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16U8B16Boiler") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (tempBoiler)
@@ -1589,7 +1590,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var relativePower = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(relativePower);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (chimneySweepFunctionActive)
@@ -1645,7 +1646,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16U8B16Chiller") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (tempChiller)
@@ -1656,7 +1657,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var relativePower = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(relativePower);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (reducedAvailability)
@@ -1696,7 +1697,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16U8N8B8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (nominalPower)
@@ -1711,7 +1712,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var burnerType = io.ReadSbyte(8);
                 internalMap["Struct"] = new PlcSINT(burnerType);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(5);
 
                 // Simple Field (solidState)
@@ -1731,7 +1732,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U5U5U6") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (magicNumber)
@@ -1751,7 +1752,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V32Z8VolumeLiter") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (volumeLiter)
@@ -1767,7 +1768,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V32Z8FlowRate") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (flowRate)
@@ -1783,7 +1784,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8N8N8N8B8B8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (logNumber)
@@ -1802,7 +1803,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var errorClass = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(errorClass);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(4);
 
                 // Simple Field (errorCode_Sup)
@@ -1821,7 +1822,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var ack_Sup = io.ReadBit();
                 internalMap["Struct"] = new PlcBOOL(ack_Sup);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(5);
 
                 // Simple Field (alarmUnAck)
@@ -1841,7 +1842,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16V16") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (delayTime)
@@ -1857,7 +1858,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "N16U32") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (manufacturerCode)
@@ -1873,7 +1874,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "F16F16F16") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (temperatureSetpointComfort)
@@ -1893,7 +1894,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V8N8N8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (energyDemand)
@@ -1913,7 +1914,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V16V16N8N8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (tempSetpointCooling)
@@ -1937,7 +1938,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16U8Scaling") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (timePeriod)
@@ -1953,7 +1954,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16U8TariffNext") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (delayTime)
@@ -1969,7 +1970,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V32N8Z8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (countVal)
@@ -1989,7 +1990,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U16U32U8N8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (manufacturerId)
@@ -2013,15 +2014,15 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "A8A8A8A8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (languageCode)
-                var languageCode = io.ReadString(16);
+                var languageCode = io.ReadString(16, Encoding.GetEncoding("ASCII"));
                 internalMap["Struct"] = new PlcSTRING(languageCode);
 
                 // Simple Field (regionCode)
-                var regionCode = io.ReadString(16);
+                var regionCode = io.ReadString(16, Encoding.GetEncoding("ASCII"));
                 internalMap["Struct"] = new PlcSTRING(regionCode);
 
                 return new PlcStruct(internalMap);
@@ -2029,7 +2030,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8U8U8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (red)
@@ -2049,11 +2050,11 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "A8A8Language") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (languageCode)
-                var languageCode = io.ReadString(16);
+                var languageCode = io.ReadString(16, Encoding.GetEncoding("ASCII"));
                 internalMap["Struct"] = new PlcSTRING(languageCode);
 
                 return new PlcStruct(internalMap);
@@ -2061,11 +2062,11 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "A8A8Region") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (regionCode)
-                var regionCode = io.ReadString(16);
+                var regionCode = io.ReadString(16, Encoding.GetEncoding("ASCII"));
                 internalMap["Struct"] = new PlcSTRING(regionCode);
 
                 return new PlcStruct(internalMap);
@@ -2073,7 +2074,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "V32U8B8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (activeElectricalEnergy)
@@ -2084,7 +2085,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var tariff = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(tariff);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(6);
 
                 // Simple Field (noTariff)
@@ -2100,7 +2101,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B1N3N4") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (deactivationOfPriority)
@@ -2120,7 +2121,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B10U6") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(5);
 
                 // Simple Field (convertorError)
@@ -2152,7 +2153,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "B2U6") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (sceneActivationInactive)
@@ -2172,14 +2173,14 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8r7B1") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (setValue)
                 var setValue = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(setValue);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(7);
 
                 // Simple Field (channelActivationActive)
@@ -2191,7 +2192,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8U8B8") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (heightPosition)
@@ -2202,7 +2203,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var slatsPosition = io.ReadByte(8);
                 internalMap["Struct"] = new PlcUSINT(slatsPosition);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(6);
 
                 // Simple Field (validSlatsPos)
@@ -2218,7 +2219,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
             if (formatName == "U8U8B16") { // Struct
                 var internalMap = new Dictionary<string, IPlcValue>();
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(8);
 
                 // Simple Field (heightPosition)
@@ -2237,7 +2238,7 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
                 var validHeightPos = io.ReadBit();
                 internalMap["Struct"] = new PlcBOOL(validHeightPos);
 
-                // Reserved Field (Just skip the bytes)
+                // Reserved Field (Just skip the bits)
                 io.ReadByte(3);
 
                 // Simple Field (failure)

[plc4x] 09/09: refactoring: Updated the plc4net branch to the latest changes on develop. new feature: Now the DataIo generation is almost finished.

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

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

commit 2775ec998eaba81764a87295e95201b80240ac26
Author: cdutz <ch...@c-ware.de>
AuthorDate: Wed Dec 15 19:06:21 2021 +0100

    refactoring: Updated the plc4net branch to the latest changes on develop.
    new feature: Now the DataIo generation is almost finished.
---
 .../language/cs/CsLanguageTemplateHelper.java      | 1054 ---
 .../resources/templates/cs/data-io-template.ftlh   |  207 -
 .../resources/templates/cs/model-template.ftlh     |  134 -
 .../language-cs/pom.xml                            |   14 +-
 .../apache/plc4x/language/cs/CsLanguageOutput.java |   22 +-
 .../language/cs/CsLanguageTemplateHelper.java      | 1201 +++
 ...x.plugins.codegenerator.language.LanguageOutput |    0
 .../templates/cs/data-io-template.cs.ftlh          |  437 ++
 .../resources/templates/cs/enum-template.cs.ftlh   |   49 +-
 .../resources/templates/cs/io-template.cs.ftlh     |  299 +
 .../resources/templates/cs/model-template.cs.ftlh} |  430 +-
 .../plc4x/language/java/JavaLanguageOutput.java    |    2 +-
 ...template.java.ftlh => model-template.java.ftlh} |    0
 code-generation/pom.xml                            |   37 +-
 .../knxnetip/readwrite/model/KnxManufacturer.go    |   26 +-
 sandbox/plc4net/api/api/value/IPlcValue.cs         |    2 +-
 .../knxnetip/ParserSerializerTestsuite.xml         |  939 ++-
 .../knxnetip/readwrite/model/KnxDatapointTests.cs  |    2 +-
 .../drivers/knxnetip/plc4net-driver-knxproj.csproj |    4 +
 .../knxnetip/readwrite/model/AccessLevel.cs        |   89 +
 .../src/drivers/knxnetip/readwrite/model/Apdu.cs   |   49 +
 .../knxnetip/readwrite/model/ApduControl.cs        |   43 +
 .../knxnetip/readwrite/model/ApduControlAck.cs     |   43 +
 .../knxnetip/readwrite/model/ApduControlConnect.cs |   43 +
 .../readwrite/model/ApduControlContainer.cs        |   48 +
 .../readwrite/model/ApduControlDisconnect.cs       |   43 +
 .../knxnetip/readwrite/model/ApduControlNack.cs    |   43 +
 .../drivers/knxnetip/readwrite/model/ApduData.cs   |   43 +
 .../knxnetip/readwrite/model/ApduDataAdcRead.cs    |   43 +
 .../readwrite/model/ApduDataAdcResponse.cs         |   43 +
 .../knxnetip/readwrite/model/ApduDataContainer.cs  |   48 +
 .../model/ApduDataDeviceDescriptorRead.cs          |   47 +
 .../model/ApduDataDeviceDescriptorResponse.cs      |   49 +
 .../knxnetip/readwrite/model/ApduDataExt.cs        |   43 +
 .../readwrite/model/ApduDataExtAuthorizeRequest.cs |   49 +
 .../model/ApduDataExtAuthorizeResponse.cs          |   47 +
 .../model/ApduDataExtDomainAddressRead.cs          |   43 +
 .../model/ApduDataExtDomainAddressResponse.cs      |   43 +
 .../model/ApduDataExtDomainAddressSelectiveRead.cs |   43 +
 .../ApduDataExtDomainAddressSerialNumberRead.cs    |   43 +
 ...ApduDataExtDomainAddressSerialNumberResponse.cs |   43 +
 .../ApduDataExtDomainAddressSerialNumberWrite.cs   |   43 +
 .../model/ApduDataExtDomainAddressWrite.cs         |   43 +
 .../model/ApduDataExtFileStreamInfoReport.cs       |   43 +
 .../ApduDataExtGroupPropertyValueInfoReport.cs     |   43 +
 .../model/ApduDataExtGroupPropertyValueRead.cs     |   43 +
 .../model/ApduDataExtGroupPropertyValueResponse.cs |   43 +
 .../model/ApduDataExtGroupPropertyValueWrite.cs    |   43 +
 ...ApduDataExtIndividualAddressSerialNumberRead.cs |   43 +
 ...DataExtIndividualAddressSerialNumberResponse.cs |   43 +
 ...pduDataExtIndividualAddressSerialNumberWrite.cs |   43 +
 .../readwrite/model/ApduDataExtKeyResponse.cs      |   43 +
 .../readwrite/model/ApduDataExtKeyWrite.cs         |   43 +
 .../readwrite/model/ApduDataExtLinkRead.cs         |   43 +
 .../readwrite/model/ApduDataExtLinkResponse.cs     |   43 +
 .../readwrite/model/ApduDataExtLinkWrite.cs        |   43 +
 .../readwrite/model/ApduDataExtMemoryBitWrite.cs   |   43 +
 .../model/ApduDataExtNetworkParameterRead.cs       |   43 +
 .../model/ApduDataExtNetworkParameterResponse.cs   |   43 +
 .../model/ApduDataExtNetworkParameterWrite.cs      |   43 +
 .../model/ApduDataExtOpenRoutingTableRequest.cs    |   43 +
 .../model/ApduDataExtPropertyDescriptionRead.cs    |   51 +
 .../ApduDataExtPropertyDescriptionResponse.cs      |   61 +
 .../model/ApduDataExtPropertyValueRead.cs          |   53 +
 .../model/ApduDataExtPropertyValueResponse.cs      |   55 +
 .../model/ApduDataExtPropertyValueWrite.cs         |   55 +
 .../model/ApduDataExtReadRouterMemoryRequest.cs    |   43 +
 .../model/ApduDataExtReadRouterMemoryResponse.cs   |   43 +
 .../model/ApduDataExtReadRouterStatusRequest.cs    |   43 +
 .../model/ApduDataExtReadRouterStatusResponse.cs   |   43 +
 .../model/ApduDataExtReadRoutingTableRequest.cs    |   43 +
 .../model/ApduDataExtReadRoutingTableResponse.cs   |   43 +
 .../model/ApduDataExtWriteRouterMemoryRequest.cs   |   43 +
 .../model/ApduDataExtWriteRouterStatusRequest.cs   |   43 +
 .../model/ApduDataExtWriteRoutingTableRequest.cs   |   43 +
 .../readwrite/model/ApduDataGroupValueRead.cs      |   43 +
 .../readwrite/model/ApduDataGroupValueResponse.cs  |   49 +
 .../readwrite/model/ApduDataGroupValueWrite.cs     |   49 +
 .../model/ApduDataIndividualAddressRead.cs         |   43 +
 .../model/ApduDataIndividualAddressResponse.cs     |   43 +
 .../model/ApduDataIndividualAddressWrite.cs        |   43 +
 .../knxnetip/readwrite/model/ApduDataMemoryRead.cs |   49 +
 .../readwrite/model/ApduDataMemoryResponse.cs      |   49 +
 .../readwrite/model/ApduDataMemoryWrite.cs         |   43 +
 .../knxnetip/readwrite/model/ApduDataOther.cs      |   47 +
 .../knxnetip/readwrite/model/ApduDataRestart.cs    |   43 +
 .../readwrite/model/ApduDataUserMessage.cs         |   43 +
 .../src/drivers/knxnetip/readwrite/model/CEMI.cs   |   43 +
 .../readwrite/model/CEMIAdditionalInformation.cs   |   43 +
 .../CEMIAdditionalInformationBusmonitorInfo.cs     |   60 +
 .../CEMIAdditionalInformationRelativeTimestamp.cs  |   50 +
 .../knxnetip/readwrite/model/CEMIPriority.cs       |   34 +
 .../knxnetip/readwrite/model/ChannelInformation.cs |   47 +
 .../knxnetip/readwrite/model/ComObjectTable.cs     |   43 +
 .../readwrite/model/ComObjectTableAddresses.cs     | 7416 +++++++++++++++++++
 .../model/ComObjectTableRealisationType1.cs        |   51 +
 .../model/ComObjectTableRealisationType2.cs        |   51 +
 .../model/ComObjectTableRealisationType6.cs        |   47 +
 .../knxnetip/readwrite/model/ComObjectValueType.cs |  104 +
 .../knxnetip/readwrite/model/ConnectionRequest.cs  |   51 +
 .../model/ConnectionRequestInformation.cs          |   43 +
 ...ConnectionRequestInformationDeviceManagement.cs |   43 +
 ...ConnectionRequestInformationTunnelConnection.cs |   47 +
 .../knxnetip/readwrite/model/ConnectionResponse.cs |   53 +
 .../readwrite/model/ConnectionResponseDataBlock.cs |   43 +
 .../ConnectionResponseDataBlockDeviceManagement.cs |   43 +
 .../ConnectionResponseDataBlockTunnelConnection.cs |   47 +
 .../readwrite/model/ConnectionStateRequest.cs      |   49 +
 .../readwrite/model/ConnectionStateResponse.cs     |   49 +
 .../knxnetip/readwrite/model/DIBDeviceInfo.cs      |   61 +
 .../knxnetip/readwrite/model/DIBSuppSvcFamilies.cs |   47 +
 .../knxnetip/readwrite/model/DescriptionRequest.cs |   47 +
 .../readwrite/model/DescriptionResponse.cs         |   49 +
 .../readwrite/model/DeviceConfigurationAck.cs      |   47 +
 .../model/DeviceConfigurationAckDataBlock.cs       |   49 +
 .../readwrite/model/DeviceConfigurationRequest.cs  |   49 +
 .../model/DeviceConfigurationRequestDataBlock.cs   |   47 +
 .../knxnetip/readwrite/model/DeviceDescriptor.cs   |  257 +
 .../readwrite/model/DeviceDescriptorMediumType.cs  |   36 +
 .../readwrite/model/DeviceDescriptorType2.cs       |   63 +
 .../knxnetip/readwrite/model/DeviceStatus.cs       |   45 +
 .../knxnetip/readwrite/model/DisconnectRequest.cs  |   49 +
 .../knxnetip/readwrite/model/DisconnectResponse.cs |   49 +
 .../knxnetip/readwrite/model/FirmwareType.cs       |   46 +
 .../model/GroupObjectDescriptorRealisationType1.cs |   59 +
 .../model/GroupObjectDescriptorRealisationType2.cs |   61 +
 .../model/GroupObjectDescriptorRealisationType6.cs |   41 +
 .../model/GroupObjectDescriptorRealisationType7.cs |   61 +
 .../model/GroupObjectDescriptorRealisationTypeB.cs |   59 +
 .../readwrite/model/HPAIControlEndpoint.cs         |   49 +
 .../knxnetip/readwrite/model/HPAIDataEndpoint.cs   |   49 +
 .../readwrite/model/HPAIDiscoveryEndpoint.cs       |   49 +
 .../knxnetip/readwrite/model/HostProtocolCode.cs   |   32 +
 .../drivers/knxnetip/readwrite/model/IPAddress.cs  |   45 +
 .../drivers/knxnetip/readwrite/model/KnxAddress.cs |   49 +
 .../knxnetip/readwrite/model/KnxDatapoint.cs       | 7748 ++++++++++++++++++++
 .../readwrite/model/KnxDatapointMainType.cs        |  664 ++
 .../knxnetip/readwrite/model/KnxDatapointType.cs   | 3544 +++++++++
 .../knxnetip/readwrite/model/KnxGroupAddress.cs    |   43 +
 .../readwrite/model/KnxGroupAddress2Level.cs       |   49 +
 .../readwrite/model/KnxGroupAddress3Level.cs       |   51 +
 .../readwrite/model/KnxGroupAddressFreeLevel.cs    |   47 +
 .../readwrite/model/KnxInterfaceObjectProperty.cs  | 2882 ++++++++
 .../readwrite/model/KnxInterfaceObjectType.cs      |  229 +
 .../drivers/knxnetip/readwrite/model/KnxLayer.cs   |   33 +
 .../knxnetip/readwrite/model/KnxManufacturer.cs    | 4065 ++++++++++
 .../drivers/knxnetip/readwrite/model/KnxMedium.cs  |   36 +
 .../knxnetip/readwrite/model/KnxNetIpCore.cs       |   47 +
 .../readwrite/model/KnxNetIpDeviceManagement.cs    |   47 +
 .../knxnetip/readwrite/model/KnxNetIpMessage.cs    |   46 +
 .../knxnetip/readwrite/model/KnxNetIpRouting.cs    |   47 +
 .../knxnetip/readwrite/model/KnxNetIpTunneling.cs  |   47 +
 .../knxnetip/readwrite/model/KnxNetObjectServer.cs |   47 +
 .../model/KnxNetRemoteConfigurationAndDiagnosis.cs |   47 +
 .../readwrite/model/KnxNetRemoteLogging.cs         |   47 +
 .../knxnetip/readwrite/model/KnxProperty.cs        | 1291 ++++
 .../readwrite/model/KnxPropertyDataType.cs         |  564 ++
 .../drivers/knxnetip/readwrite/model/LBusmonInd.cs |   53 +
 .../drivers/knxnetip/readwrite/model/LDataCon.cs   |   51 +
 .../knxnetip/readwrite/model/LDataExtended.cs      |   59 +
 .../drivers/knxnetip/readwrite/model/LDataFrame.cs |   56 +
 .../knxnetip/readwrite/model/LDataFrameACK.cs      |   45 +
 .../drivers/knxnetip/readwrite/model/LDataInd.cs   |   51 +
 .../drivers/knxnetip/readwrite/model/LDataReq.cs   |   51 +
 .../drivers/knxnetip/readwrite/model/LPollData.cs  |   53 +
 .../knxnetip/readwrite/model/LPollDataCon.cs       |   43 +
 .../knxnetip/readwrite/model/LPollDataReq.cs       |   43 +
 .../drivers/knxnetip/readwrite/model/LRawCon.cs    |   43 +
 .../drivers/knxnetip/readwrite/model/LRawInd.cs    |   43 +
 .../drivers/knxnetip/readwrite/model/LRawReq.cs    |   43 +
 .../drivers/knxnetip/readwrite/model/MACAddress.cs |   45 +
 .../readwrite/model/MFuncPropCommandReq.cs         |   43 +
 .../knxnetip/readwrite/model/MFuncPropCon.cs       |   43 +
 .../readwrite/model/MFuncPropStateReadReq.cs       |   43 +
 .../knxnetip/readwrite/model/MPropInfoInd.cs       |   43 +
 .../knxnetip/readwrite/model/MPropReadCon.cs       |   57 +
 .../knxnetip/readwrite/model/MPropReadReq.cs       |   55 +
 .../knxnetip/readwrite/model/MPropWriteCon.cs      |   43 +
 .../knxnetip/readwrite/model/MPropWriteReq.cs      |   43 +
 .../drivers/knxnetip/readwrite/model/MResetInd.cs  |   43 +
 .../drivers/knxnetip/readwrite/model/MResetReq.cs  |   43 +
 .../model/ProjectInstallationIdentifier.cs         |   47 +
 .../knxnetip/readwrite/model/RelativeTimestamp.cs  |   45 +
 .../knxnetip/readwrite/model/RoutingIndication.cs  |   43 +
 .../knxnetip/readwrite/model/SearchRequest.cs      |   47 +
 .../knxnetip/readwrite/model/SearchResponse.cs     |   51 +
 .../drivers/knxnetip/readwrite/model/ServiceId.cs  |   43 +
 .../src/drivers/knxnetip/readwrite/model/Status.cs |   42 +
 .../readwrite/model/SupportedPhysicalMedia.cs      |   46 +-
 .../knxnetip/readwrite/model/TDataConnectedInd.cs  |   43 +
 .../knxnetip/readwrite/model/TDataConnectedReq.cs  |   43 +
 .../knxnetip/readwrite/model/TDataIndividualInd.cs |   43 +
 .../knxnetip/readwrite/model/TDataIndividualReq.cs |   43 +
 .../knxnetip/readwrite/model/TunnelingRequest.cs   |   49 +
 .../readwrite/model/TunnelingRequestDataBlock.cs   |   47 +
 .../knxnetip/readwrite/model/TunnelingResponse.cs  |   47 +
 .../readwrite/model/TunnelingResponseDataBlock.cs  |   49 +
 .../knxnetip/readwrite/model/UnknownMessage.cs     |   47 +
 .../knxnetip/src/knxnetip/readwrite/model/APCI.cs  |   46 -
 .../knxnetip/src/knxnetip/readwrite/model/CEMI.cs  |   34 -
 .../readwrite/model/CEMIAdditionalInformation.cs   |   34 -
 .../CEMIAdditionalInformationBusmonitorInfo.cs     |   53 -
 .../CEMIAdditionalInformationRelativeTimestamp.cs  |   43 -
 .../src/knxnetip/readwrite/model/CEMIBusmonInd.cs  |   44 -
 .../src/knxnetip/readwrite/model/CEMIDataCon.cs    |   44 -
 .../src/knxnetip/readwrite/model/CEMIDataFrame.cs  |   70 -
 .../src/knxnetip/readwrite/model/CEMIDataInd.cs    |   44 -
 .../src/knxnetip/readwrite/model/CEMIDataReq.cs    |   44 -
 .../src/knxnetip/readwrite/model/CEMIFrame.cs      |   46 -
 .../src/knxnetip/readwrite/model/CEMIFrameAck.cs   |   43 -
 .../src/knxnetip/readwrite/model/CEMIFrameData.cs  |   67 -
 .../knxnetip/readwrite/model/CEMIFrameDataExt.cs   |   69 -
 .../readwrite/model/CEMIFramePollingData.cs        |   43 -
 .../readwrite/model/CEMIFramePollingDataExt.cs     |   43 -
 .../knxnetip/readwrite/model/CEMIMPropReadCon.cs   |   50 -
 .../knxnetip/readwrite/model/CEMIMPropReadReq.cs   |   48 -
 .../knxnetip/readwrite/model/CEMIPollDataCon.cs    |   36 -
 .../knxnetip/readwrite/model/CEMIPollDataReq.cs    |   36 -
 .../src/knxnetip/readwrite/model/CEMIPriority.cs   |   34 -
 .../src/knxnetip/readwrite/model/CEMIRawCon.cs     |   36 -
 .../src/knxnetip/readwrite/model/CEMIRawInd.cs     |   36 -
 .../src/knxnetip/readwrite/model/CEMIRawReq.cs     |   36 -
 .../knxnetip/readwrite/model/ConnectionRequest.cs  |   44 -
 .../model/ConnectionRequestInformation.cs          |   34 -
 ...ConnectionRequestInformationDeviceManagement.cs |   36 -
 ...ConnectionRequestInformationTunnelConnection.cs |   40 -
 .../knxnetip/readwrite/model/ConnectionResponse.cs |   46 -
 .../readwrite/model/ConnectionResponseDataBlock.cs |   34 -
 .../ConnectionResponseDataBlockDeviceManagement.cs |   36 -
 .../ConnectionResponseDataBlockTunnelConnection.cs |   40 -
 .../readwrite/model/ConnectionStateRequest.cs      |   42 -
 .../readwrite/model/ConnectionStateResponse.cs     |   42 -
 .../src/knxnetip/readwrite/model/DIBDeviceInfo.cs  |   52 -
 .../knxnetip/readwrite/model/DIBSuppSvcFamilies.cs |   38 -
 .../knxnetip/readwrite/model/DescriptionRequest.cs |   40 -
 .../readwrite/model/DescriptionResponse.cs         |   42 -
 .../readwrite/model/DeviceConfigurationAck.cs      |   40 -
 .../model/DeviceConfigurationAckDataBlock.cs       |   40 -
 .../readwrite/model/DeviceConfigurationRequest.cs  |   42 -
 .../model/DeviceConfigurationRequestDataBlock.cs   |   38 -
 .../src/knxnetip/readwrite/model/DeviceStatus.cs   |   36 -
 .../knxnetip/readwrite/model/DisconnectRequest.cs  |   42 -
 .../knxnetip/readwrite/model/DisconnectResponse.cs |   42 -
 .../readwrite/model/HPAIControlEndpoint.cs         |   40 -
 .../knxnetip/readwrite/model/HPAIDataEndpoint.cs   |   40 -
 .../readwrite/model/HPAIDiscoveryEndpoint.cs       |   40 -
 .../knxnetip/readwrite/model/HostProtocolCode.cs   |   32 -
 .../src/knxnetip/readwrite/model/IPAddress.cs      |   36 -
 .../src/knxnetip/readwrite/model/KnxAddress.cs     |   40 -
 .../src/knxnetip/readwrite/model/KnxDatapoint.cs   | 3956 ----------
 .../knxnetip/readwrite/model/KnxDatapointType.cs   | 3634 ---------
 .../knxnetip/readwrite/model/KnxGroupAddress.cs    |   34 -
 .../readwrite/model/KnxGroupAddress2Level.cs       |   42 -
 .../readwrite/model/KnxGroupAddress3Level.cs       |   44 -
 .../readwrite/model/KnxGroupAddressFreeLevel.cs    |   40 -
 .../src/knxnetip/readwrite/model/KnxLayer.cs       |   33 -
 .../src/knxnetip/readwrite/model/KnxMedium.cs      |   36 -
 .../src/knxnetip/readwrite/model/KnxNetIpCore.cs   |   40 -
 .../readwrite/model/KnxNetIpDeviceManagement.cs    |   40 -
 .../knxnetip/readwrite/model/KnxNetIpMessage.cs    |   37 -
 .../knxnetip/readwrite/model/KnxNetIpTunneling.cs  |   40 -
 .../knxnetip/readwrite/model/KnxNetObjectServer.cs |   40 -
 .../model/KnxNetRemoteConfigurationAndDiagnosis.cs |   40 -
 .../readwrite/model/KnxNetRemoteLogging.cs         |   40 -
 .../src/knxnetip/readwrite/model/MACAddress.cs     |   36 -
 .../model/ProjectInstallationIdentifier.cs         |   38 -
 .../knxnetip/readwrite/model/RelativeTimestamp.cs  |   36 -
 .../knxnetip/readwrite/model/RoutingIndication.cs  |   36 -
 .../src/knxnetip/readwrite/model/SearchRequest.cs  |   40 -
 .../src/knxnetip/readwrite/model/SearchResponse.cs |   44 -
 .../src/knxnetip/readwrite/model/ServiceId.cs      |   34 -
 .../src/knxnetip/readwrite/model/Status.cs         |   42 -
 .../knxnetip/src/knxnetip/readwrite/model/TPCI.cs  |   34 -
 .../knxnetip/readwrite/model/TunnelingRequest.cs   |   42 -
 .../readwrite/model/TunnelingRequestDataBlock.cs   |   38 -
 .../knxnetip/readwrite/model/TunnelingResponse.cs  |   40 -
 .../readwrite/model/TunnelingResponseDataBlock.cs  |   40 -
 .../src/knxnetip/readwrite/model/UnknownMessage.cs |   40 -
 sandbox/plc4net/plc4net.driver/pom.xml             |   67 -
 sandbox/plc4net/pom.xml                            |    6 +-
 sandbox/plc4net/spi/spi/generation/ByteOrder.cs    |   27 +
 .../plc4net/spi/spi/generation/EvaluationHelper.cs |   74 +
 .../plc4net/spi/spi/generation/ParseException.cs   |   26 +
 sandbox/plc4net/spi/spi/generation/ReadBuffer.cs   |   46 +-
 sandbox/plc4net/spi/spi/generation/WriteBuffer.cs  |   26 +-
 sandbox/plc4net/spi/spi/model/values/PlcTIME.cs    |    4 +-
 .../spi/spi/model/values/PlcValueAdapter.cs        |    2 +-
 src/main/script/prerequisiteCheck.groovy           |    8 -
 288 files changed, 39604 insertions(+), 12907 deletions(-)

diff --git a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java b/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
deleted file mode 100644
index d144a0e..0000000
--- a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-package org.apache.plc4x.language.cs;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.BaseFreemarkerLanguageTemplateHelper;
-import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
-import org.apache.plc4x.plugins.codegenerator.types.enums.EnumValue;
-import org.apache.plc4x.plugins.codegenerator.types.fields.*;
-import org.apache.plc4x.plugins.codegenerator.types.references.*;
-import org.apache.plc4x.plugins.codegenerator.types.terms.*;
-
-import java.util.*;
-
-@SuppressWarnings({"unused", "WeakerAccess"})
-public class CsLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelper {
-
-    public CsLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
-        super(thisType, protocolName, flavorName, types);
-    }
-
-    public String fileName(String protocolName, String languageName, String languageFlavorName) {
-        return String.join("", protocolName.split("\\-")) + "." +
-            String.join("", languageFlavorName.split("\\-"));
-    }
-
-    public String packageName(String languageFlavorName) {
-        return String.join("", languageFlavorName.split("\\-"));
-    }
-
-    @Override
-    public String getLanguageTypeNameForField(Field field) {
-        boolean optional = field instanceof OptionalField;
-        // If the referenced type is a DataIo type, the value is of type PlcValue.
-        if(field instanceof PropertyField) {
-            PropertyField propertyField = (PropertyField) field;
-            if(propertyField.getType() instanceof ComplexTypeReference) {
-                ComplexTypeReference complexTypeReference = (ComplexTypeReference) propertyField.getType();
-                final TypeDefinition typeDefinition = getTypeDefinitions().get(complexTypeReference.getName());
-                if(typeDefinition instanceof DataIoTypeDefinition) {
-                    return "PlcValue";
-                }
-            }
-        }
-        return getLanguageTypeNameForTypeReference(((TypedField) field).getType());
-    }
-
-    @Override
-    public String getLanguageTypeNameForTypeReference(TypeReference typeReference) {
-        if(typeReference instanceof SimpleTypeReference) {
-            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
-            switch (simpleTypeReference.getBaseType()) {
-                case BIT: {
-                    return "bool";
-                }
-                case UINT: {
-                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                    if (integerTypeReference.getSizeInBits() <= 8) {
-                        return "byte";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 16) {
-                        return "ushort";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 32) {
-                        return "uint";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 64) {
-                        return "ulong";
-                    }
-                    throw new RuntimeException("Unsupported simple type");
-                }
-                case INT: {
-                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                    if (integerTypeReference.getSizeInBits() <= 8) {
-                        return "sbyte";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 16) {
-                        return "short";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 32) {
-                        return "int";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 64) {
-                        return "long";
-                    }
-                    throw new RuntimeException("Unsupported simple type");
-                }
-                case FLOAT:
-                case UFLOAT: {
-                    FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                    int sizeInBits = ((floatTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) ? 1 : 0) +
-                        floatTypeReference.getExponent() + floatTypeReference.getMantissa();
-                    if (sizeInBits <= 32) {
-                        return "float";
-                    }
-                    if (sizeInBits <= 64) {
-                        return "double";
-                    }
-                    throw new RuntimeException("Unsupported simple type");
-                }
-                case STRING: {
-                    return "string";
-                }
-                case TIME: {
-                    return "time";
-                }
-                case DATE: {
-                    return "date";
-                }
-                case DATETIME: {
-                    return "datetime2";
-                }
-            }
-            throw new RuntimeException("Unsupported simple type");
-        } else {
-            return (typeReference != null) ? ((ComplexTypeReference) typeReference).getName() : "";
-        }
-    }
-
-    public String getPlcValueTypeForTypeReference(TypeReference typeReference) {
-        if(typeReference instanceof SimpleTypeReference) {
-            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
-            switch (simpleTypeReference.getBaseType()) {
-                case BIT: {
-                    return "PlcBOOL";
-                }
-                case UINT: {
-                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                    if (integerTypeReference.getSizeInBits() <= 8) {
-                        return "PlcUSINT";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 16) {
-                        return "PlcUINT";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 32) {
-                        return "PlcUDINT";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 64) {
-                        return "PlcULINT";
-                    }
-                    throw new RuntimeException("Unsupported simple type");
-                }
-                case INT: {
-                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                    if (integerTypeReference.getSizeInBits() <= 8) {
-                        return "PlcSINT";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 16) {
-                        return "PlcINT";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 32) {
-                        return "PlcDINT";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 64) {
-                        return "PlcLINT";
-                    }
-                    throw new RuntimeException("Unsupported simple type");
-                }
-                case FLOAT:
-                case UFLOAT: {
-                    FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                    int sizeInBits = ((floatTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) ? 1 : 0) +
-                        floatTypeReference.getExponent() + floatTypeReference.getMantissa();
-                    if (sizeInBits <= 32) {
-                        return "PlcREAL";
-                    }
-                    if (sizeInBits <= 64) {
-                        return "PlcLREAL";
-                    }
-                    throw new RuntimeException("Unsupported simple type");
-                }
-                case STRING: {
-                    return "PlcSTRING";
-                }
-                case TIME: {
-                    return "PlcTIME";
-                }
-                case DATE: {
-                    return "PlcDATE";
-                }
-                case DATETIME: {
-                    return "PlcDATE_AND_TIME";
-                }
-            }
-            throw new RuntimeException("Unsupported simple type");
-        } else {
-            return (typeReference != null) ? ((ComplexTypeReference) typeReference).getName() : "";
-        }
-    }
-
-    @Override
-    public String getNullValueForTypeReference(TypeReference typeReference) {
-        if(typeReference instanceof SimpleTypeReference) {
-            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
-            switch (simpleTypeReference.getBaseType()) {
-                case BIT: {
-                    return "false";
-                }
-                case UINT:
-                case INT: {
-                    return "0";
-                }
-                case FLOAT: {
-                    return "0.0";
-                }
-                case STRING: {
-                    return "\"\"";
-                }
-            }
-        } else if(typeReference instanceof ComplexTypeReference) {
-            return "0";
-        }
-        return "null";
-    }
-
-    public int getNumBits(SimpleTypeReference simpleTypeReference) {
-        switch (simpleTypeReference.getBaseType()) {
-            case BIT: {
-                return 1;
-            }
-            case UINT:
-            case INT: {
-                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                return integerTypeReference.getSizeInBits();
-            }
-            case FLOAT: {
-                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                return floatTypeReference.getSizeInBits();
-            }
-            case STRING: {
-                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                return integerTypeReference.getSizeInBits();
-            }
-            default: {
-                return 0;
-            }
-        }
-    }
-
-    public String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference, String valueString) {
-        switch (simpleTypeReference.getBaseType()) {
-            case BIT: {
-                return "io.ReadBit()";
-            }
-            case UINT: {
-                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                if (integerTypeReference.getSizeInBits() <= 8) {
-                    return "io.ReadByte(" + integerTypeReference.getSizeInBits() + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 16) {
-                    return "io.ReadUshort(" + integerTypeReference.getSizeInBits() + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 32) {
-                    return "io.ReadUint(" + integerTypeReference.getSizeInBits() + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 64) {
-                    return "io.ReadUlong(" + integerTypeReference.getSizeInBits() + ")";
-                }
-            }
-            case INT: {
-                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                if (integerTypeReference.getSizeInBits() <= 8) {
-                    return "io.ReadSbyte(" + integerTypeReference.getSizeInBits() + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 16) {
-                    return "io.ReadShort(" + integerTypeReference.getSizeInBits() + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 32) {
-                    return "io.ReadInt(" + integerTypeReference.getSizeInBits() + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 64) {
-                    return "io.ReadLong(" + integerTypeReference.getSizeInBits() + ")";
-                }
-            }
-            case FLOAT: {
-                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                if (floatTypeReference.getSizeInBits() <= 32) {
-                    return "io.ReadFloat(true, " + floatTypeReference.getExponent() + ", " + floatTypeReference.getMantissa() + ")";
-                }
-                if (floatTypeReference.getSizeInBits() <= 64) {
-                    return "io.ReadDouble(true, " + floatTypeReference.getExponent() + ", " + floatTypeReference.getMantissa() + ")";
-                }
-            }
-            case STRING: {
-                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
-                return "io.ReadString(" + stringTypeReference.getSizeInBits() + ", Encoding.GetEncoding(\"" +
-                    stringTypeReference.getEncoding().substring(1, stringTypeReference.getEncoding().length() - 1) + "\"))";
-            }
-        }
-        return "Hurz";
-    }
-
-    @Override
-    public String getWriteBufferWriteMethodCall(SimpleTypeReference simpleTypeReference, String fieldName) {
-        switch (simpleTypeReference.getBaseType()) {
-            case BIT: {
-                return "io.WriteBit(" + fieldName + ")";
-            }
-            case UINT: {
-                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                if (integerTypeReference.getSizeInBits() <= 8) {
-                    return "io.WriteByte(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 16) {
-                    return "io.WriteUshort(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 32) {
-                    return "io.WriteUint(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 64) {
-                    return "io.WriteUlong(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-            }
-            case INT: {
-                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                if (integerTypeReference.getSizeInBits() <= 8) {
-                    return "io.WriteSbyte(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 16) {
-                    return "io.WriteShort(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 32) {
-                    return "io.WriteInt(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-                if (integerTypeReference.getSizeInBits() <= 64) {
-                    return "io.WriteLong(" + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-            }
-            case FLOAT:
-            case UFLOAT: {
-                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                if (floatTypeReference.getSizeInBits() <= 32) {
-                    return "io.WriteFloat(" + floatTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-                if (floatTypeReference.getSizeInBits() <= 64) {
-                    return "io.WriteDouble(" + floatTypeReference.getSizeInBits() + ", " + fieldName + ")";
-                }
-            }
-            case STRING: {
-                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
-                String encoding = ((stringTypeReference.getEncoding() != null) && (stringTypeReference.getEncoding().length() > 2)) ?
-                    stringTypeReference.getEncoding().substring(1, stringTypeReference.getEncoding().length() - 1) : "UTF-8";
-                return "io.WriteString(" + stringTypeReference.getSizeInBits() + ", \"" +
-                    encoding + "\", " + fieldName + ")";
-            }
-        }
-        return "Hurz";
-    }
-
-    public String getReservedValue(ReservedField reservedField) {
-        final String languageTypeName = getLanguageTypeNameForTypeReference(reservedField.getType());
-        return reservedField.getReferenceValue().toString();
-    }
-
-    public String toParseExpression(TypedField field, Term term, Argument[] parserArguments) {
-        return toTypedParseExpression((field != null) ? field.getType() : null, term, parserArguments);
-    }
-
-    public String toSerializationExpression(TypedField field, Term term, Argument[] serializerArguments) {
-        return toTypedSerializationExpression((field != null) ? field.getType() : null, term, serializerArguments);
-    }
-
-    public String toBooleanParseExpression(Term term, Argument[] parserArguments) {
-        return toTypedParseExpression(new DefaultBooleanTypeReference(), term, parserArguments);
-    }
-
-    public String toBooleanSerializationExpression(Term term, Argument[] serializerArguments) {
-        return toTypedSerializationExpression(new DefaultBooleanTypeReference(), term, serializerArguments);
-    }
-
-    public String toIntegerParseExpression(int sizeInBits, Term term, Argument[] parserArguments) {
-        return toTypedParseExpression(new DefaultIntegerTypeReference(SimpleTypeReference.SimpleBaseType.UINT, sizeInBits), term, parserArguments);
-    }
-
-    public String toIntegerSerializationExpression(int sizeInBits, Term term, Argument[] serializerArguments) {
-        return toTypedSerializationExpression(new DefaultIntegerTypeReference(SimpleTypeReference.SimpleBaseType.UINT, sizeInBits), term, serializerArguments);
-    }
-
-    public String toTypedParseExpression(TypeReference fieldType, Term term, Argument[] parserArguments) {
-        return toExpression(fieldType, term, parserArguments, null, false, false);
-    }
-
-    public String toTypedSerializationExpression(TypeReference fieldType, Term term, Argument[] serializerArguments) {
-        return toExpression(fieldType, term, null, serializerArguments, true, false);
-    }
-
-    String getCastExpressionForTypeReference(TypeReference typeReference) {
-        if(typeReference instanceof SimpleTypeReference) {
-            return getLanguageTypeNameForTypeReference(typeReference);
-        } else if(typeReference != null) {
-            return "Cast" + getLanguageTypeNameForTypeReference(typeReference);
-        } else {
-            return "";
-        }
-    }
-
-    private String toExpression(TypeReference fieldType, Term term, Argument[] parserArguments, Argument[] serializerArguments, boolean serialize, boolean suppressPointerAccess) {
-        if(term == null) {
-            return "";
-        }
-        if(term instanceof Literal) {
-            if(term instanceof NullLiteral) {
-                return "nil";
-            } else if(term instanceof BooleanLiteral) {
-                return getCastExpressionForTypeReference(fieldType) + "(" + ((BooleanLiteral) term).getValue() + ")";
-            } else if(term instanceof NumericLiteral) {
-                return getCastExpressionForTypeReference(fieldType) + "(" + ((NumericLiteral) term).getNumber().toString() + ")";
-            } else if(term instanceof StringLiteral) {
-                return "\"" + ((StringLiteral) term).getValue() + "\"";
-            } else if(term instanceof VariableLiteral) {
-                return toVariableExpression(fieldType, (VariableLiteral) term, parserArguments, serializerArguments, serialize, suppressPointerAccess);
-            } else {
-                throw new RuntimeException("Unsupported Literal type " + term.getClass().getName());
-            }
-        } else if (term instanceof UnaryTerm) {
-            UnaryTerm ut = (UnaryTerm) term;
-            Term a = ut.getA();
-            switch(ut.getOperation()) {
-                case "!":
-                    return "!(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + ")";
-                case "-":
-                    return "-(" + getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + "))";
-                case "()":
-                    return getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + ")";
-                default:
-                    throw new RuntimeException("Unsupported unary operation type " + ut.getOperation());
-            }
-        } else if (term instanceof BinaryTerm) {
-            BinaryTerm bt = (BinaryTerm) term;
-            Term a = bt.getA();
-            Term b = bt.getB();
-            String operation = bt.getOperation();
-            switch (operation) {
-                case "^":
-                    return "Math.pow(" +
-                        getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + "), " +
-                        getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, b, parserArguments, serializerArguments, serialize, false) + "))";
-                // If we start casting for comparisons, equals or non equals, really messy things happen.
-                case "==":
-                case "!=":
-                case ">":
-                case "<":
-                case ">=":
-                case "<=":
-                    // For every access of optional elements we need pointer access ...
-                    // Except for doing a nil or not-nil check :-(
-                    // So in case of such a check, we need to suppress the pointer-access.
-                    boolean suppressPointerAccessOverride = (operation.equals("==") || operation.equals("!=")) && ((a instanceof NullLiteral) || (b instanceof NullLiteral));
-                    return "bool((" + toExpression(null, a, parserArguments, serializerArguments, serialize, suppressPointerAccessOverride) + ") " +
-                        operation +
-                        " (" + toExpression(null, b, parserArguments, serializerArguments, serialize, suppressPointerAccessOverride) + "))";
-                default:
-                    return getCastExpressionForTypeReference(fieldType) + "(" + toExpression(fieldType, a, parserArguments, serializerArguments, serialize, false) + ") " +
-                        operation + " " +
-                        getCastExpressionForTypeReference(fieldType) +"(" + toExpression(fieldType, b, parserArguments, serializerArguments, serialize, false) + ")";
-            }
-        } else if (term instanceof TernaryTerm) {
-            TernaryTerm tt = (TernaryTerm) term;
-            if ("if".equals(tt.getOperation())) {
-                Term a = tt.getA();
-                Term b = tt.getB();
-                Term c = tt.getC();
-                // TODO: This is not quite correct with the cast to uint16
-                return "utils.InlineIf(" + toExpression(new DefaultBooleanTypeReference(), a, parserArguments, serializerArguments, serialize, false) + ", " +
-                    "uint16(" + toExpression(fieldType, b, parserArguments, serializerArguments, serialize, false) + "), " +
-                    "uint16(" + toExpression(fieldType, c, parserArguments, serializerArguments, serialize, false) + "))";
-            } else {
-                throw new RuntimeException("Unsupported ternary operation type " + tt.getOperation());
-            }
-        } else {
-            throw new RuntimeException("Unsupported Term type " + term.getClass().getName());
-        }
-    }
-
-    private String toVariableExpression(TypeReference typeReference, VariableLiteral vl, Argument[] parserArguments, Argument[] serializerArguments, boolean serialize, boolean suppressPointerAccess) {
-        if ("lengthInBytes".equals(vl.getName())) {
-            return (serialize ? getCastExpressionForTypeReference(typeReference) + "(m." : "") + "LengthInBytes()" + (serialize ? ")" : "");
-        } else if ("lengthInBits".equals(vl.getName())) {
-            return (serialize ? getCastExpressionForTypeReference(typeReference) + "(m." : "") + "LengthInBits()" + (serialize ? ")" : "");
-        }
-        // If this literal references an Enum type, then we have to output it differently.
-        else if (getTypeDefinitions().get(vl.getName()) instanceof EnumTypeDefinition) {
-            return vl.getName() + "_" + vl.getChild().getName() +
-                ((vl.getChild().getChild() != null) ?
-                    "." + toVariableExpression(typeReference, vl.getChild().getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
-        }
-        // If we are accessing enum constants, these also need to be output differently.
-        else if ((getFieldForNameFromCurrent(vl.getName()) instanceof EnumField) && (vl.getChild() != null)) {
-            return vl.getName() + "." + StringUtils.capitalize(vl.getChild().getName()) + "()" +
-                ((vl.getChild().getChild() != null) ?
-                    "." + toVariableExpression(typeReference, vl.getChild().getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
-        }
-        // If we are accessing optional fields of simple type, we need to use pointer-access.
-        else if (!serialize && (getFieldForNameFromCurrent(vl.getName()) instanceof OptionalField) &&
-            (((OptionalField) getFieldForNameFromCurrent(vl.getName())).getType() instanceof SimpleTypeReference)) {
-            return "(*" + vl.getName() + ")" +
-                ((vl.getChild() != null) ?
-                    "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, serialize, suppressPointerAccess) : "");
-        }
-        // CAST expressions are special as we need to add a ".class" to the second parameter in Java.
-        else if ("CAST".equals(vl.getName())) {
-            if ((vl.getArgs() == null) || (vl.getArgs().size() != 2)) {
-                throw new RuntimeException("A CAST expression expects exactly two arguments.");
-            }
-            VariableLiteral typeLiteral = (VariableLiteral) vl.getArgs().get(1);
-            final TypeDefinition typeDefinition = getTypeDefinitions().get(typeLiteral.getName());
-            TypeReference type = typeDefinition.getTypeReference();
-            StringBuilder sb = new StringBuilder();
-            if (type instanceof ComplexTypeReference) {
-                sb.append("Cast");
-            }
-            sb.append(typeLiteral.getName());
-            sb.append("(").append(toVariableExpression(typeReference, (VariableLiteral) vl.getArgs().get(0), parserArguments, serializerArguments, serialize, suppressPointerAccess)).append(")");
-            return sb.toString() + ((vl.getChild() != null) ? "." + StringUtils.capitalize(toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess)) : "");
-        } else if ("STATIC_CALL".equals(vl.getName())) {
-            StringBuilder sb = new StringBuilder();
-            if (!(vl.getArgs().get(0) instanceof StringLiteral)) {
-                throw new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral");
-            }
-            // Get the class and method name
-            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) {
-                    sb.append(", ");
-                }
-                if (arg instanceof VariableLiteral) {
-                    VariableLiteral va = (VariableLiteral) arg;
-                    // "io" is the default name of the reader argument which is always available.
-                    boolean isParserArg = "io".equals(va.getName()) || ((getThisTypeDefinition() instanceof DataIoTypeDefinition) && "_value".equals(va.getName()));
-                    boolean isTypeArg = "_type".equals(va.getName());
-                    if (!isParserArg && !isTypeArg && parserArguments != null) {
-                        for (Argument parserArgument : parserArguments) {
-                            if (parserArgument.getName().equals(va.getName())) {
-                                isParserArg = true;
-                                break;
-                            }
-                        }
-                    }
-                    if (isParserArg) {
-                        if(va.getName().equals("_value")) {
-                            sb.append(va.getName().substring(1) + ((va.getChild() != null) ?
-                                "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : ""));
-                        } else {
-                            sb.append(va.getName() + ((va.getChild() != null) ?
-                                "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : ""));
-                        }
-                    }
-                    // We have to manually evaluate the type information at code-generation time.
-                    else if (isTypeArg) {
-                        String part = va.getChild().getName();
-                        switch (part) {
-                            case "name":
-//                                sb.append("\"").append(field.getTypeName()).append("\"");
-                                break;
-                            case "length":
-                                sb.append("\"").append(((SimpleTypeReference) typeReference).getSizeInBits()).append("\"");
-                                break;
-                            case "encoding":
-                                String encoding = ((StringTypeReference) typeReference).getEncoding();
-                                // Cut off the single quotes.
-                                encoding = encoding.substring(1, encoding.length() - 1);
-                                sb.append("\"").append(encoding).append("\"");
-                                break;
-                        }
-                    } else {
-                        sb.append(toVariableExpression(typeReference, va, parserArguments, serializerArguments, serialize, suppressPointerAccess));
-                    }
-                } else if (arg instanceof StringLiteral) {
-                    sb.append(((StringLiteral) arg).getValue());
-                }
-            }
-            sb.append(")");
-            return sb.toString();
-        } else if ("COUNT".equals(vl.getName())) {
-            return (typeReference instanceof SimpleTypeReference ? getCastExpressionForTypeReference(typeReference) : "") + "(len(" +
-                toVariableExpression(typeReference, (VariableLiteral) vl.getArgs().get(0), parserArguments, serializerArguments, serialize, suppressPointerAccess) +
-                "))";
-        } else if ("ARRAY_SIZE_IN_BYTES".equals(vl.getName())) {
-            VariableLiteral va = (VariableLiteral) vl.getArgs().get(0);
-            // "io" and "m" are always available in every parser.
-            boolean isSerializerArg = "io".equals(va.getName()) || "m".equals(va.getName()) || "element".equals(va.getName());
-            if (!isSerializerArg && serializerArguments != null) {
-                for (Argument serializerArgument : serializerArguments) {
-                    if (serializerArgument.getName().equals(va.getName())) {
-                        isSerializerArg = true;
-                        break;
-                    }
-                }
-            }
-            StringBuilder sb = new StringBuilder();
-            if (isSerializerArg) {
-                sb.append(va.getName()).append(((va.getChild() != null) ? "." + toVariableExpression(typeReference, va.getChild(), parserArguments, serializerArguments, true, suppressPointerAccess) : ""));
-            } else {
-                sb.append(toVariableExpression(typeReference, va, parserArguments, serializerArguments, true, suppressPointerAccess));
-            }
-            return getCastExpressionForTypeReference(typeReference) + "(" + ((VariableLiteral) vl.getArgs().get(0)).getName() + "ArraySizeInBytes(" + sb.toString() + "))";
-        }
-        else if("CEIL".equals(vl.getName())) {
-            Term va = vl.getArgs().get(0);
-            // The Ceil function expects 64 bit floating point values.
-            TypeReference tr = new DefaultFloatTypeReference(SimpleTypeReference.SimpleBaseType.FLOAT, 11, 52);
-            return "math.Ceil(" + toExpression(tr, va, parserArguments, serializerArguments, serialize, suppressPointerAccess) + ")";
-        }
-        // All uppercase names are not fields, but utility methods.
-        else if (vl.getName().equals(vl.getName().toUpperCase())) {
-            StringBuilder sb = new StringBuilder(vl.getName());
-            if (vl.getArgs() != null) {
-                sb.append("(");
-                boolean firstArg = true;
-                for (Term arg : vl.getArgs()) {
-                    if (!firstArg) {
-                        sb.append(", ");
-                    }
-                    sb.append(toExpression(typeReference, arg, parserArguments, serializerArguments, serialize, suppressPointerAccess));
-                    firstArg = false;
-                }
-                sb.append(")");
-            }
-            if (vl.getIndex() != VariableLiteral.NO_INDEX) {
-                sb.append("[").append(vl.getIndex()).append("]");
-            }
-            return sb.toString() + ((vl.getChild() != null) ?
-                "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
-        }
-        // If the current property references a discriminator value, we have to serialize it differently.
-        else if ((getFieldForNameFromCurrentOrParent(vl.getName()) != null) && (getFieldForNameFromCurrentOrParent(vl.getName()) instanceof DiscriminatorField)) {
-            final DiscriminatorField discriminatorField = (DiscriminatorField) getFieldForNameFromCurrentOrParent(vl.getName());
-            System.out.println(discriminatorField);
-        }
-        // If the current property references a parserArguments property and that is a discriminator property, we also have to serialize it differently..
-        else if ((vl.getChild() != null) && (getTypeReferenceForProperty(((ComplexTypeDefinition) getThisTypeDefinition()), vl.getName()) != null)) {
-            final Optional<TypeReference> typeReferenceForProperty = getTypeReferenceForProperty(((ComplexTypeDefinition) getThisTypeDefinition()), vl.getName());
-            if(typeReferenceForProperty.isPresent() && typeReferenceForProperty.get() instanceof ComplexTypeReference) {
-                final TypeReference complexTypeReference = typeReferenceForProperty.get();
-                TypeDefinition typeDefinition = getTypeDefinitionForTypeReference(complexTypeReference);
-                if(typeDefinition instanceof ComplexTypeDefinition) {
-                    ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) typeDefinition;
-                    String childProperty = vl.getChild().getName();
-                    final Optional<Field> matchingDiscriminatorField = complexTypeDefinition.getFields().stream().filter(field -> (field instanceof DiscriminatorField) && ((DiscriminatorField) field).getName().equals(childProperty)).findFirst();
-                    if(matchingDiscriminatorField.isPresent()) {
-                        return "Cast" + getLanguageTypeNameForTypeReference(complexTypeReference) + "(" + vl.getName() + ")." + StringUtils.capitalize(childProperty) + "()";
-                    }
-                }
-            }
-        }
-        // If the current term references a serialization argument, handle it differently (don't prefix it with "m.")
-        else if((serializerArguments != null) && Arrays.stream(serializerArguments).anyMatch(argument -> argument.getName().equals(vl.getName()))) {
-            return vl.getName() + ((vl.getChild() != null) ?
-                "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
-        }
-        return (serialize ? "m." + StringUtils.capitalize(vl.getName()) : vl.getName()) + ((vl.getChild() != null) ?
-            "." + toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess) : "");
-    }
-
-    public String getSizeInBits(ComplexTypeDefinition complexTypeDefinition, Argument[] parserArguments) {
-        int sizeInBits = 0;
-        StringBuilder sb = new StringBuilder("");
-        for (Field field : complexTypeDefinition.getFields()) {
-            if(field instanceof ArrayField) {
-                ArrayField arrayField = (ArrayField) field;
-                final SimpleTypeReference type = (SimpleTypeReference) arrayField.getType();
-                switch (arrayField.getLoopType()) {
-                    case COUNT:
-                        sb.append("(").append(toTypedSerializationExpression(type, arrayField.getLoopExpression(), parserArguments)).append(" * ").append(type.getSizeInBits()).append(") + ");
-                        break;
-                    case LENGTH:
-                        sb.append("(").append(toTypedSerializationExpression(type, arrayField.getLoopExpression(), parserArguments)).append(" * 8) + ");
-                        break;
-                    case TERMINATED:
-                        // No terminated.
-                        break;
-                }
-            } else if(field instanceof TypedField) {
-                TypedField typedField = (TypedField) field;
-                final TypeReference type = typedField.getType();
-                if(field instanceof ManualField) {
-                    ManualField manualField = (ManualField) field;
-                    sb.append("(").append(toSerializationExpression(manualField, manualField.getLengthExpression(), parserArguments)).append(") + ");
-                }
-                else if(type instanceof SimpleTypeReference) {
-                    SimpleTypeReference simpleTypeReference = (SimpleTypeReference) type;
-                    sizeInBits += simpleTypeReference.getSizeInBits();
-                } else {
-                    // No ComplexTypeReference supported.
-                }
-            }
-        }
-        return sb.toString() + sizeInBits;
-    }
-
-    public String escapeValue(TypeReference typeReference, String valueString) {
-        if(valueString == null) {
-            return null;
-        }
-        if(typeReference instanceof SimpleTypeReference) {
-            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
-            switch (simpleTypeReference.getBaseType()) {
-                case UINT:
-                case INT:
-                    // If it's a one character string and is numeric, output it as char.
-                    if(!NumberUtils.isParsable(valueString) && (valueString.length() == 1)) {
-                        return "'" + valueString + "'";
-                    }
-                    break;
-                case STRING:
-                    return "\"" + valueString + "\"";
-            }
-        }
-        return valueString;
-    }
-
-    public String escapeEnumValue(TypeReference typeReference, String valueString) {
-        // Currently the only case in which here complex type references are used are when referencing enum constants.
-        if (typeReference instanceof ComplexTypeReference) {
-            // C doesn't like NULL values for enums, so we have to return something else (we'll treat -1 as NULL)
-            if ("null".equals(valueString)) {
-                return "0";
-            }
-            String typeName = valueString.substring(0, valueString.indexOf('.'));
-            String constantName = valueString.substring(valueString.indexOf('.') + 1);
-            return typeName + "_" + constantName;
-        } else {
-            return escapeValue(typeReference, valueString);
-        }
-    }
-
-    public Collection<EnumValue> getUniqueEnumValues(EnumValue[] enumValues) {
-        Map<String, EnumValue> filteredEnumValues = new TreeMap<>();
-        for (EnumValue enumValue : enumValues) {
-            if (!filteredEnumValues.containsKey(enumValue.getValue())) {
-                filteredEnumValues.put(enumValue.getValue(), enumValue);
-            }
-        }
-        return filteredEnumValues.values();
-    }
-
-    public List<String> getRequiredImports() {
-        ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) getThisTypeDefinition();
-        List<String> imports = new ArrayList<>();
-
-        if(complexTypeDefinition.getAllPropertyFields().stream().anyMatch(field -> isArrayField(field) && getLanguageTypeNameForField(field).equals("int8"))) {
-            imports.add("\"encoding/base64\"");
-        }
-
-        imports.add("\"encoding/xml\"");
-
-        // For "Fields with complex type", constant, typeSwitch,  fields: "errors"
-        if(!complexTypeDefinition.getFields().isEmpty()) {
-            imports.add("\"errors\"");
-        }
-
-        imports.add("\"io\"");
-
-        // At least one reserved field or simple field with complex type
-        if(complexTypeDefinition.getFields().stream().anyMatch(field ->
-            (field instanceof ReservedField))) {
-            imports.add("log \"github.com/sirupsen/logrus\"");
-        }
-
-        // For CEIL functions: "math"
-/*        if(complexTypeDefinition.getFields().stream().anyMatch(field ->
-            FieldUtils.contains(field, "CEIL"))) {
-            imports.add("\"math\"");
-        }*/
-
-        imports.add("\"github.com/apache/plc4x/plc4go/internal/plc4go/utils\"");
-
-        // For Constant field: "strconv"
-        if(complexTypeDefinition.getFields().stream().anyMatch(field ->
-            (field instanceof ConstField))/* || complexTypeDefinition.getAllPropertyFields().stream().anyMatch(
-                propertyField -> isSimpleField(propertyField))*/) {
-            imports.add("\"strconv\"");
-        }
-
-        if(isDiscriminatedParentTypeDefinition()) {
-            imports.add("\"reflect\"");
-            imports.add("\"strings\"");
-        }
-
-        return imports;
-    }
-
-    public List<String> getRequiredImportsForDataIo() {
-        DataIoTypeDefinition dataIo = (DataIoTypeDefinition) getThisTypeDefinition();
-
-        List<String> imports = new ArrayList<>();
-
-        imports.add("\"errors\"");
-        imports.add("\"github.com/apache/plc4x/plc4go/internal/plc4go/model/values\"");
-        imports.add("\"github.com/apache/plc4x/plc4go/internal/plc4go/utils\"");
-        imports.add("api \"github.com/apache/plc4x/plc4go/pkg/plc4go/values\"");
-
-        if(dataIo.getSwitchField().getCases().stream().anyMatch(typeCase ->
-            (typeCase.getName().equals("TIME_OF_DAY") && hasFieldsWithNames(typeCase.getFields(), "hour", "minutes", "seconds")) ||
-                (typeCase.getName().equals("DATE") && hasFieldsWithNames(typeCase.getFields(), "year", "month", "day")) ||
-                (typeCase.getName().equals("DATE_AND_TIME") && hasFieldsWithNames(typeCase.getFields(), "year", "month", "day", "hour", "minutes", "seconds")))) {
-            imports.add("\"time\"");
-        }
-        return imports;
-    }
-
-    public String getVariableName(Field field) {
-        if(!(field instanceof NamedField)) {
-            return "_";
-        }
-        NamedField namedField = (NamedField) field;
-
-        String name = null;
-        for (Field curField : ((ComplexTypeDefinition) getThisTypeDefinition()).getFields()) {
-            if(curField == field) {
-                name = namedField.getName();
-            } else if(name != null) {
-                if(curField instanceof ArrayField) {
-                    ArrayField arrayField = (ArrayField) curField;
-                    if(arrayField.getLoopExpression().contains(name)) {
-                        return name;
-                    }
-                } else if(curField instanceof ChecksumField) {
-                    ChecksumField checksumField = (ChecksumField) curField;
-                    if(checksumField.getChecksumExpression().contains(name)) {
-                        return name;
-                    }
-                } else if(curField instanceof ImplicitField) {
-                    ImplicitField implicitField = (ImplicitField) curField;
-                    if(implicitField.getSerializeExpression().contains(name)) {
-                        return name;
-                    }
-                } else if(curField instanceof ManualArrayField) {
-                    ManualArrayField manualArrayField = (ManualArrayField) curField;
-                    if(manualArrayField.getLengthExpression().contains(name)) {
-                        return name;
-                    }
-                    if(manualArrayField.getLoopExpression().contains(name)) {
-                        return name;
-                    }
-                    if(manualArrayField.getParseExpression().contains(name)) {
-                        return name;
-                    }
-                    if(manualArrayField.getSerializeExpression().contains(name)) {
-                        return name;
-                    }
-                } else if(curField instanceof ManualField) {
-                    ManualField manualField = (ManualField) curField;
-                    if(manualField.getLengthExpression().contains(name)) {
-                        return name;
-                    }
-                    if(manualField.getParseExpression().contains(name)) {
-                        return name;
-                    }
-                    if(manualField.getSerializeExpression().contains(name)) {
-                        return name;
-                    }
-                } else if(curField instanceof OptionalField) {
-                    OptionalField optionalField = (OptionalField) curField;
-                    if(optionalField.getConditionExpression().contains(name)) {
-                        return name;
-                    }
-                } else if(curField instanceof SwitchField) {
-                    SwitchField switchField = (SwitchField) curField;
-                    for (Term discriminatorExpression : switchField.getDiscriminatorExpressions()) {
-                        if(discriminatorExpression.contains(name)) {
-                            return name;
-                        }
-                    }
-                    for (DiscriminatedComplexTypeDefinition curCase : switchField.getCases()) {
-                        for (Argument parserArgument : curCase.getParserArguments()) {
-                            if(parserArgument.getName().equals(name)) {
-                                return name;
-                            }
-                        }
-                    }
-                } else if(curField instanceof VirtualField) {
-                    VirtualField virtualField = (VirtualField) curField;
-                    if(virtualField.getValueExpression().contains(name)) {
-                        return name;
-                    }
-                }
-                if(curField.getParams() != null) {
-                    for (Term param : curField.getParams()) {
-                        if(param.contains(name)) {
-                            return name;
-                        }
-                    }
-                }
-            }
-        }
-
-        return "_";
-    }
-
-    public boolean needsVariable(ArrayField field, String variableName, boolean serialization) {
-        if(!serialization) {
-            if (field.getLoopExpression().contains(variableName)) {
-                return true;
-            }
-        }
-        if((field.getParams() != null) && (field.getParams().length > 0)){
-            for (Term param : field.getParams()) {
-                if(param.contains(variableName)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Right now only the ARRAY_SIZE_IN_BYTES requires helpers to be generated.
-     * Also right now only the Modbus protocol requires this and here the referenced
-     * properties are all also members of the current complex type,
-     * so we'll simplify things here for now.
-     *
-     * @param functionName name of the
-     * @return
-     */
-    public Map<String, String> requiresHelperFunctions(String functionName) {
-        Map<String, String> result = new HashMap<>();
-        boolean usesFunction = false;
-        // As the ARRAY_SIZE_IN_BYTES only applies to ArrayFields, search for these
-        for (Field curField : ((ComplexTypeDefinition) getThisTypeDefinition()).getFields()) {
-            if(curField instanceof ArrayField) {
-                ArrayField arrayField = (ArrayField) curField;
-                if(arrayField.getLoopExpression().contains(functionName)) {
-                    usesFunction = true;
-                }
-                result.put(arrayField.getName(), getLanguageTypeNameForField(arrayField));
-            } else if(curField instanceof ImplicitField) {
-                ImplicitField implicitField = (ImplicitField) curField;
-                if(implicitField.getSerializeExpression().contains(functionName)) {
-                    usesFunction = true;
-                }
-            }
-        }
-        if(usesFunction) {
-            return result;
-        } else {
-            return Collections.emptyMap();
-        }
-    }
-
-    public boolean requiresStartPosAndCurPos() {
-        if(getThisTypeDefinition() instanceof ComplexTypeDefinition) {
-            for (Field curField : ((ComplexTypeDefinition) getThisTypeDefinition()).getFields()) {
-                if (requiresVariable(curField, "curPos")) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public boolean requiresVariable(Field curField, String variable) {
-        if(curField instanceof ArrayField) {
-            ArrayField arrayField = (ArrayField) curField;
-            if(arrayField.getLoopExpression().contains(variable)) {
-                return true;
-            }
-        } else if(curField instanceof OptionalField) {
-            OptionalField optionalField = (OptionalField) curField;
-            if(optionalField.getConditionExpression().contains(variable)) {
-                return true;
-            }
-        }
-        if(curField.getParams() != null) {
-            for (Term paramTerm : curField.getParams()) {
-                if (paramTerm.contains(variable)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public Term findTerm(Term baseTerm, String name) {
-        if(baseTerm instanceof VariableLiteral) {
-            VariableLiteral variableLiteral = (VariableLiteral) baseTerm;
-            if(variableLiteral.getName().equals(name)) {
-                return variableLiteral;
-            }
-            if(variableLiteral.getChild() != null) {
-                Term found = findTerm(variableLiteral.getChild(), name);
-                if(found != null) {
-                    return found;
-                }
-            }
-            for (Term arg : variableLiteral.getArgs()) {
-                Term found = findTerm(arg, name);
-                if(found != null) {
-                    return found;
-                }
-            }
-        } else if(baseTerm instanceof UnaryTerm) {
-            UnaryTerm unaryTerm = (UnaryTerm) baseTerm;
-            Term found = findTerm(unaryTerm.getA(), name);
-            if(found != null) {
-                return found;
-            }
-        } else if(baseTerm instanceof BinaryTerm) {
-            BinaryTerm binaryTerm = (BinaryTerm) baseTerm;
-            Term found = findTerm(binaryTerm.getA(), name);
-            if(found != null) {
-                return found;
-            }
-            found = findTerm(binaryTerm.getB(), name);
-            if(found != null) {
-                return found;
-            }
-        } else if(baseTerm instanceof TernaryTerm) {
-            TernaryTerm ternaryTerm = (TernaryTerm) baseTerm;
-            Term found = findTerm(ternaryTerm.getA(), name);
-            if(found != null) {
-                return found;
-            }
-            found = findTerm(ternaryTerm.getB(), name);
-            if(found != null) {
-                return found;
-            }
-            found = findTerm(ternaryTerm.getC(), name);
-            if(found != null) {
-                return found;
-            }
-        }
-        return null;
-    }
-
-}
diff --git a/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh b/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh
deleted file mode 100644
index ae9c8df..0000000
--- a/build-utils/language-cs/src/main/resources/templates/cs/data-io-template.ftlh
+++ /dev/null
@@ -1,207 +0,0 @@
-<#--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<#-- Prevent freemarker from escaping stuff -->
-<#outputformat "undefined">
-<#-- Declare the name and type of variables passed in to the template -->
-<#-- @ftlvariable name="languageName" type="java.lang.String" -->
-<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
-<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
-<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
-<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
-<#-- Declare the name and type of variables declared locally inside the template -->
-<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
-<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
-<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
-<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
-<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
-<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
-<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
-<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
-<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
-<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
-<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
-<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
-<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
-<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
-<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
-<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
-${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/${type.name}.cs
-//
-// 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.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using org.apache.plc4net.api.value;
-using org.apache.plc4net.spi.generation;
-using org.apache.plc4net.spi.model.values;
-
-namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFlavor?replace("-", "")}.model
-{
-
-    public class ${type.name}
-    {
-
-        public IPlcValue Parse(ReadBuffer io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>)
-        {
-    <#list type.switchField.cases as case>
-            if (<#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">
-                var internalMap = new Dictionary<string, IPlcValue>();
-            <#assign valueDefined=true>
-        </#if>
-        <#list case.fields as field>
-            <#switch field.typeName>
-                <#case "array">
-                    <#assign arrayField = field>
-
-                // Array Field (${field.name});
-                var ${arrayField.name} = new List<IPlcValue>();
-                for (int i = 0; i < ${helper.toParseExpression(null, field.loopExpression, type.parserArguments)}; i++) {
-                    var internalItem = <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>Complex type array in data-io parsing currently not implemented</#if>;
-                    ${field.name}.Add(new ${helper.getPlcValueTypeForTypeReference(field.type)}(internalItem));
-                }
-                    <#if field.name == "value">
-                        <#assign valueDefined=true>
-                    </#if>
-                    <#break>
-                <#case "manual">
-                    <#assign manualArrayField = field>
-
-                // Manual Field (${field.name})
-                var ${field.name} = ${helper.toParseExpression(field, field.parseExpression, type.parserArguments)};
-                    <#if field.name == "value">
-                        <#assign valueDefined=true>
-                    </#if>
-                    <#break>
-                <#case "reserved">
-                    <#assign reservedField = field>
-
-                // Reserved Field (Just skip the bits)
-                ${helper.getReadBufferReadMethodCall(field.type)};
-                    <#break>
-                <#case "simple">
-                    <#assign simpleField = field>
-
-                // Simple Field (${field.name})
-                var ${field.name} = <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}Parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>;
-                    <#if case.name == "Struct">
-                internalMap["${case.name}"] = new ${helper.getPlcValueTypeForTypeReference(field.type)}(${field.name});
-                    </#if>
-                    <#assign valueDefined=true>
-                    <#break>
-            </#switch>
-        </#list>
-        <#if valueDefined>
-
-            <#switch case.name>
-                <#case "TIME_OF_DAY">
-                    <#if helper.hasFieldsWithNames(case.fields, "hour", "minutes", "seconds")>
-                var value = new DateTime(0,0,0, hour, minutes, seconds);
-                    </#if>
-                return new PlcTIME_OF_DAY(value);
-                    <#break>
-                <#case "DATE">
-                    <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day")>
-                var value = new DateTime(year, month, day, 0, 0, 0);
-                    </#if>
-                return new PlcDATE(value);
-                    <#break>
-                <#case "DATE_AND_TIME">
-                    <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds")>
-                var value = new DateTime(year, month, day, hour, minutes, seconds);
-                    </#if>
-                return new PlcDATE_AND_TIME(value);
-                    <#break>
-                <#case "Struct">
-                return new PlcStruct(internalMap);
-                    <#break>
-                <#case "List">
-                return new PlcList(value);
-                    <#break>
-                <#default>
-                return new Plc${case.name}(value);
-            </#switch>
-        </#if>
-            } <#sep>else
-    </#list>
-
-            return null;
-        }
-
-        public void Serialize(WriteBuffer io, IPlcValue value<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>)
-        {
-    <#list type.switchField.cases as case>
-            if (<#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}
-        <#list case.fields as field>
-            <#switch field.typeName>
-                <#case "array">
-                    <#assign arrayField = field>
-
-                // Array Field (${field.name})
-                for (int i = 0; i < ${helper.toSerializationExpression(null, field.loopExpression, type.parserArguments)}; i++) {
-                    <#if helper.isSimpleTypeReference(arrayField.type)>${helper.getWriteBufferWriteMethodCall(arrayField.type, arrayField.name + ".GetIndex(i).Get" + helper.getLanguageTypeNameForTypeReference(arrayField.type)?cap_first + "()")}<#else>Complex type array in data-io serialization currently not implemented</#if>;
-                }
-                    <#break>
-                <#case "manual">
-                    <#assign manualField = field>
-
-                // Manual Field (${field.name})
-                ${helper.toSerializationExpression(field, manualField.serializeExpression, type.parserArguments)};
-                    <#break>
-                <#case "reserved">
-                    <#assign reservedField = field>
-
-                // Reserved Field (Just skip the bytes)
-                ${helper.getWriteBufferWriteMethodCall(field.type, helper.getReservedValue(field))};
-                    <#break>
-                <#case "simple">
-                    <#assign simpleField = field>
-
-                // Simple Field (${field.name})
-                <#if helper.isSimpleTypeReference(field.type)>${helper.getWriteBufferWriteMethodCall(field.type, "value.Get" + helper.getLanguageTypeNameForTypeReference(field.type)?cap_first + "()")}<#else>${field.type.name}Serialize(io, <#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type.parserArguments [...]
-                    <#break>
-            </#switch>
-        </#list>
-            } <#sep>else
-    </#list>
-        }
-
-    }
-
-}
-
-</#outputformat>
diff --git a/build-utils/language-cs/src/main/resources/templates/cs/model-template.ftlh b/build-utils/language-cs/src/main/resources/templates/cs/model-template.ftlh
deleted file mode 100644
index 795a979..0000000
--- a/build-utils/language-cs/src/main/resources/templates/cs/model-template.ftlh
+++ /dev/null
@@ -1,134 +0,0 @@
-<#--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<#-- Prevent freemarker from escaping stuff -->
-<#outputformat "undefined">
-<#-- Declare the name and type of variables passed in to the template -->
-<#-- @ftlvariable name="languageName" type="java.lang.String" -->
-<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
-<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
-<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
-<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
-<#-- Declare the name and type of variables declared locally inside the template -->
-<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
-<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
-<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
-<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
-<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
-<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
-<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
-<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
-<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
-<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
-<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
-<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
-<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
-<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
-<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
-<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
-${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/${type.name}.cs
-//
-// 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.
-//
-
-namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFlavor?replace("-", "")}.model
-{
-
-    public<#if helper.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${type.name}<#if type.parentType??> : ${type.parentType.name}</#if>
-    {
-    <#--
-        If this is a discriminated child type, we need to generate methods for accessing it's discriminator
-        values, as if they were normal java properties.
-    -->
-    <#if helper.isDiscriminatedChildTypeDefinition()>
-        <#assign discriminatedChildType = type>
-
-        <#-- @ftlvariable name="discriminatedChildType" type="org.apache.plc4x.plugins.codegenerator.types.definitions.DiscriminatedComplexTypeDefinition" -->
-        // Accessors for discriminator values.
-        <#list helper.getDiscriminatorValues(discriminatedChildType) as discriminatorName, discriminatorValue>
-        <#-- If the discriminator name matches that of another field, suppress the methods generation -->
-            <#if !helper.isNonDiscriminatorField(discriminatorName)>
-        public override ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])} Get${discriminatorName?cap_first}() {
-            return <#if discriminatorValue??>${discriminatorValue}<#else>${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if>;
-        }
-            </#if>
-        </#list>
-    </#if>
-    <#--
-        If this is a discriminated parent type, we need to generate the abstract methods for accessing it's
-        discriminator values instead.
-    -->
-    <#if helper.isDiscriminatedParentTypeDefinition()>
-        <#assign discriminatedParentType = type>
-
-    <#-- @ftlvariable name="discriminatedParentType" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
-        // Abstract accessors for discriminator values.
-        <#list helper.getDiscriminatorTypes() as discriminatorName, discriminatorType>
-        <#-- If the discriminator name matches that of another field, suppress the methods generation -->
-            <#if !helper.isNonDiscriminatorField(discriminatorName)>
-        public abstract ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} Get${discriminatorName?cap_first}();
-            </#if>
-        </#list>
-    </#if>
-    <#-- If the current type contains "const" fields, generate some java constants for holing their values -->
-    <#if type.constFields?has_content>
-
-        // Constant values.
-        <#list type.constFields as field>
-        public const ${helper.getLanguageTypeNameForField(field)} ${field.name?upper_case} = ${field.referenceValue};
-        </#list>
-    </#if>
-    <#-- Prpoerty fields are fields that require a property in the pojo -->
-    <#if type.propertyFields?has_content>
-
-        // Properties.
-        <#list type.propertyFields as field>
-        public ${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> ${field.name?cap_first} { get; }
-        </#list>
-    </#if>
-
-    <#-- getAllPropertyFields() returns not only the property fields of this type but also of it's parents -->
-        public ${type.name}(<#list type.getAllPropertyFields() as field>${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> ${field.name}<#sep>, </#sep></#list>)
-    <#if type.getParentPropertyFields()?has_content>
-            : base(<#list type.getParentPropertyFields() as field>${field.name}<#sep>, </#sep></#list>)
-    </#if>
-        {
-    <#list type.propertyFields as field>
-            ${field.name?cap_first} = ${field.name};
-    </#list>
-        }
-
-    }
-
-}
-</#outputformat>
\ No newline at end of file
diff --git a/build-utils/language-cs/pom.xml b/code-generation/language-cs/pom.xml
similarity index 75%
rename from build-utils/language-cs/pom.xml
rename to code-generation/language-cs/pom.xml
index 2a02405..b0e951d 100644
--- a/build-utils/language-cs/pom.xml
+++ b/code-generation/language-cs/pom.xml
@@ -19,25 +19,25 @@
   -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
-  <modelVersion>4.0.0</modelVersion>
+  <modelVersion>4.0.0</modelVersion><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>8</source><target>8</target></configuration></plugin></plugins></build>
 
   <parent>
     <groupId>org.apache.plc4x</groupId>
-    <artifactId>plc4x-build-utils</artifactId>
-    <version>0.8.0-SNAPSHOT</version>
+    <artifactId>plc4x-code-generation</artifactId>
+    <version>0.10.0-SNAPSHOT</version>
   </parent>
 
-  <artifactId>plc4x-build-utils-language-cs</artifactId>
+  <artifactId>plc4x-code-generation-language-cs</artifactId>
 
-  <name>PLC4X: Build Utils: Language: C#</name>
+  <name>Code-Generation: Language: C#</name>
   <description>Code generation template for generating C# code</description>
 
   <dependencies>
     <!-- We are using the Freemarker module to generate Java code -->
     <dependency>
       <groupId>org.apache.plc4x</groupId>
-      <artifactId>plc4x-build-utils-language-base-freemarker</artifactId>
-      <version>0.8.0-SNAPSHOT</version>
+      <artifactId>plc4x-code-generation-language-base-freemarker</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
     </dependency>
 
     <dependency>
diff --git a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java b/code-generation/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
similarity index 89%
rename from build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
rename to code-generation/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
index 9009615..71f8a4a 100644
--- a/build-utils/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
+++ b/code-generation/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageOutput.java
@@ -26,10 +26,7 @@ import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLang
 import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
 
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 public class CsLanguageOutput extends FreemarkerLanguageOutput {
 
@@ -44,31 +41,36 @@ public class CsLanguageOutput extends FreemarkerLanguageOutput {
     }
 
     @Override
-    protected List<Template> getSpecTemplates(Configuration freemarkerConfiguration) throws IOException {
+    public Set<String> supportedOptions() {
+        return null;
+    }
+
+    @Override
+    protected List<Template> getSpecTemplates(Configuration freemarkerConfiguration) {
         return Collections.emptyList();
     }
 
     @Override
     protected List<Template> getComplexTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
         return Collections.singletonList(
-            freemarkerConfiguration.getTemplate("templates/cs/model-template.ftlh"));
+            freemarkerConfiguration.getTemplate("templates/cs/model-template.cs.ftlh"));
     }
 
     @Override
     protected List<Template> getEnumTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
         return Collections.singletonList(
-            freemarkerConfiguration.getTemplate("templates/cs/enum-template.ftlh"));
+            freemarkerConfiguration.getTemplate("templates/cs/enum-template.cs.ftlh"));
     }
 
     @Override
     protected List<Template> getDataIoTemplates(Configuration freemarkerConfiguration) throws IOException {
         return Collections.singletonList(
-            freemarkerConfiguration.getTemplate("templates/cs/data-io-template.ftlh"));
+            freemarkerConfiguration.getTemplate("templates/cs/data-io-template.cs.ftlh"));
     }
 
     @Override
-    protected FreemarkerLanguageTemplateHelper getHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
-        return new CsLanguageTemplateHelper(thisType, protocolName, flavorName, types);
+    protected FreemarkerLanguageTemplateHelper getHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types, Map<String, String> options) {
+        return new CsLanguageTemplateHelper(thisType, protocolName, flavorName, types, options);
     }
 
 }
diff --git a/code-generation/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java b/code-generation/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
new file mode 100644
index 0000000..5bbb339
--- /dev/null
+++ b/code-generation/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java
@@ -0,0 +1,1201 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.language.cs;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.commons.text.WordUtils;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.BaseFreemarkerLanguageTemplateHelper;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerException;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
+import org.apache.plc4x.plugins.codegenerator.types.fields.*;
+import org.apache.plc4x.plugins.codegenerator.types.references.*;
+import org.apache.plc4x.plugins.codegenerator.types.terms.*;
+
+import java.util.*;
+import java.util.function.Function;
+
+@SuppressWarnings({"unused", "WeakerAccess"})
+public class CsLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelper {
+
+    private final Map<String, String> options;
+
+    public CsLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types,
+                                      Map<String, String> options) {
+        super(thisType, protocolName, flavorName, types);
+        this.options = options;
+    }
+
+    public String fileName(String protocolName, String languageName, String languageFlavorName) {
+        return "drivers." + String.join("", protocolName.split("\\-")) + "." +
+            String.join("", languageFlavorName.split("\\-"));
+    }
+
+    public String packageName() {
+        return packageName(protocolName, "cs", flavorName);
+    }
+
+    public String packageName(String protocolName, String languageName, String languageFlavorName) {
+        return Optional.ofNullable(options.get("package")).orElseGet(() ->
+            "org.apache.plc4x." + String.join("", languageName.split("-")) + "." +
+                String.join("", protocolName.split("-")) + "." +
+                String.join("", languageFlavorName.split("-")));
+    }
+
+    @Override
+    public String getLanguageTypeNameForField(Field field) {
+        // If the referenced type is a DataIo type, the value is of type PlcValue.
+        if (field.isPropertyField()) {
+            PropertyField propertyField = field.asPropertyField().orElseThrow(IllegalStateException::new);
+            if (propertyField.getType().isComplexTypeReference()) {
+                ComplexTypeReference complexTypeReference = propertyField.getType().asComplexTypeReference().orElseThrow(IllegalStateException::new);
+                final TypeDefinition typeDefinition = getTypeDefinitions().get(complexTypeReference.getName());
+                if (typeDefinition instanceof DataIoTypeDefinition) {
+                    return "PlcValue";
+                }
+            }
+        }
+        return getLanguageTypeNameForTypeReference(((TypedField) field).getType());
+    }
+
+    @Override
+    public String getLanguageTypeNameForTypeReference(TypeReference typeReference) {
+        Objects.requireNonNull(typeReference);
+        if (!(typeReference instanceof SimpleTypeReference)) {
+            return ((ComplexTypeReference) typeReference).getName();
+        }
+        SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return "bool";
+            case BYTE:
+                return "byte";
+            case UINT:
+                IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
+                    return "byte";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
+                    return "ushort";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
+                    return "uint";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
+                    return "ulong";
+                }
+                throw new RuntimeException("Unsupported simple type");
+            case INT:
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "sbyte";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "short";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "int";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "long";
+                }
+                throw new RuntimeException("Unsupported simple type");
+            case FLOAT:
+            case UFLOAT:
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                int sizeInBits = floatTypeReference.getSizeInBits();
+                if (sizeInBits <= 32) {
+                    return "float";
+                }
+                if (sizeInBits <= 64) {
+                    return "double";
+                }
+                throw new RuntimeException("Unsupported simple type");
+            case STRING:
+            case VSTRING:
+                return "string";
+            case TIME:
+                return "time";
+            case DATE:
+                return "date";
+            case DATETIME:
+                return "datetime2";
+
+        }
+        throw new RuntimeException("Unsupported simple type");
+    }
+
+    public String getPlcValueTypeForTypeReference(TypeReference typeReference) {
+        if (!(typeReference instanceof SimpleTypeReference)) {
+            return "PlcStruct";
+        }
+        SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return "PlcBOOL";
+            case BYTE:
+                return "PlcBYTE";
+            case UINT:
+                IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
+                    return "PlcUSINT";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
+                    return "PlcUINT";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
+                    return "PlcUDINT";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
+                    return "PlcULINT";
+                }
+            case INT:
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "PlcSINT";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "PlcINT";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "PlcDINT";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "PlcLINT";
+                }
+
+            case FLOAT:
+            case UFLOAT:
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                int sizeInBits = floatTypeReference.getSizeInBits();
+                if (sizeInBits <= 32) {
+                    return "PlcREAL";
+                }
+                if (sizeInBits <= 64) {
+                    return "PlcLREAL";
+                }
+            case STRING:
+            case VSTRING:
+                return "PlcSTRING";
+            case TIME:
+            case DATE:
+            case DATETIME:
+                return "PlcTIME";
+        }
+        throw new RuntimeException("Unsupported simple type");
+    }
+
+    @Override
+    public String getNullValueForTypeReference(TypeReference typeReference) {
+        if (typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case BIT:
+                    return "false";
+                case BYTE:
+                    return "0";
+                case UINT:
+                    IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
+                        return "0";
+                    }
+                    if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
+                        return "0l";
+                    }
+                    return "null";
+                case INT:
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "0";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 64) {
+                        return "0l";
+                    }
+                    return "null";
+                case FLOAT:
+                    FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                    int sizeInBits = floatTypeReference.getSizeInBits();
+                    if (sizeInBits <= 32) {
+                        return "0.0f";
+                    }
+                    if (sizeInBits <= 64) {
+                        return "0.0";
+                    }
+                    return "null";
+                case STRING:
+                case VSTRING:
+                    return "null";
+            }
+            throw new FreemarkerException("Unmapped base-type" + simpleTypeReference.getBaseType());
+        } else {
+            return "null";
+        }
+    }
+
+    public int getNumBits(SimpleTypeReference simpleTypeReference) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return 1;
+            case BYTE:
+                return 8;
+            case UINT:
+            case INT:
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                return integerTypeReference.getSizeInBits();
+            case FLOAT:
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                return floatTypeReference.getSizeInBits();
+            case STRING:
+                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
+                return stringTypeReference.getSizeInBits();
+            case VSTRING:
+                throw new IllegalArgumentException("getSizeInBits doesn't work for 'vstring' fields");
+            default:
+                return 0;
+        }
+    }
+
+    @Deprecated
+    @Override
+    public String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference, String valueString, TypedField field) {
+        return getReadBufferReadMethodCall("", simpleTypeReference, valueString, field);
+    }
+
+    @Deprecated
+    public String getReadBufferReadMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, String valueString, TypedField field) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return "readBuffer.ReadBit(\"" + logicalName + "\")";
+            case BYTE:
+                return "readBuffer.ReadByte(\"" + logicalName + "\", 8)";
+            case UINT:
+                String unsignedIntegerType;
+                IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
+                    unsignedIntegerType = "Byte";
+                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
+                    unsignedIntegerType = "Ushort";
+                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
+                    unsignedIntegerType = "Uint";
+                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
+                    unsignedIntegerType = "Ulong";
+                } else {
+                    throw new RuntimeException("Unsupported type");
+                }
+                return "readBuffer.Read" + unsignedIntegerType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
+            case INT:
+                String integerType;
+                if (simpleTypeReference.getSizeInBits() <= 8) {
+                    integerType = "Sbyte";
+                } else if (simpleTypeReference.getSizeInBits() <= 16) {
+                    integerType = "Short";
+                } else if (simpleTypeReference.getSizeInBits() <= 32) {
+                    integerType = "Int";
+                } else if (simpleTypeReference.getSizeInBits() <= 64) {
+                    integerType = "Long";
+                } else {
+                    throw new RuntimeException("Unsupported type");
+                }
+                return "readBuffer.Read" + integerType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
+            case FLOAT:
+                String floatType = (simpleTypeReference.getSizeInBits() <= 32) ? "Float" : "Double";
+                return "readBuffer.Read" + floatType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
+            case STRING:
+            case VSTRING:
+                String stringType = "String";
+                final Term encodingTerm = field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"));
+                if (!(encodingTerm instanceof StringLiteral)) {
+                    throw new RuntimeException("Encoding must be a quoted string value");
+                }
+                String encoding = ((StringLiteral) encodingTerm).getValue();
+                String length = Integer.toString(simpleTypeReference.getSizeInBits());
+                if (simpleTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.VSTRING) {
+                    VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
+                    length = toParseExpression(field, INT_TYPE_REFERENCE, vstringTypeReference.getLengthExpression(), null);
+                }
+                return "readBuffer.Read" + stringType + "(\"" + logicalName + "\", " + length + ", System.Text.Encoding.GetEncoding(\"" +
+                    encoding + "\"))";
+        }
+        return "";
+    }
+
+    public String getDataReaderCall(TypeReference typeReference) {
+        return getDataReaderCall(typeReference, "enumForValue");
+    }
+
+    public String getDataReaderCall(TypeReference typeReference, String resolverMethod) {
+        if (isEnumTypeReference(typeReference)) {
+            final String languageTypeName = getLanguageTypeNameForTypeReference(typeReference);
+            final SimpleTypeReference enumBaseTypeReference = getEnumBaseTypeReference(typeReference);
+            return "new DataReaderEnumDefault<>(" + languageTypeName + "::" + resolverMethod + ", " + getDataReaderCall(enumBaseTypeReference) + ")";
+        } else if (typeReference.isSimpleTypeReference()) {
+            SimpleTypeReference simpleTypeReference = typeReference.asSimpleTypeReference().orElseThrow(IllegalStateException::new);
+            return getDataReaderCall(simpleTypeReference);
+        } else if (typeReference.isComplexTypeReference()) {
+            StringBuilder paramsString = new StringBuilder();
+            ComplexTypeReference complexTypeReference = typeReference.asComplexTypeReference().orElseThrow(IllegalStateException::new);
+            TypeDefinition typeDefinition = getTypeDefinitionForTypeReference(typeReference);
+            String parserCallString = getLanguageTypeNameForTypeReference(typeReference);
+            if (typeDefinition.isDiscriminatedChildTypeDefinition()) {
+                parserCallString = "(" + getLanguageTypeNameForTypeReference(typeReference) + ") " + typeDefinition.getParentType().getName();
+            }
+            List<Term> paramTerms = complexTypeReference.getParams().orElse(Collections.emptyList());
+            for (int i = 0; i < paramTerms.size(); i++) {
+                Term paramTerm = paramTerms.get(i);
+                final TypeReference argumentType = getArgumentType(complexTypeReference, i);
+                paramsString
+                    .append(", (")
+                    .append(getLanguageTypeNameForTypeReference(argumentType))
+                    .append(") (")
+                    .append(toParseExpression(null, argumentType, paramTerm, null))
+                    .append(")");
+            }
+            return "new DataReaderComplexDefault<>(() -> " + parserCallString + "IO.staticParse(readBuffer" + paramsString + "), readBuffer)";
+        } else {
+            throw new IllegalStateException("What is this type? " + typeReference);
+        }
+    }
+
+    public String getDataReaderCall(SimpleTypeReference simpleTypeReference) {
+        final int sizeInBits = simpleTypeReference.getSizeInBits();
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return "readBoolean(readBuffer)";
+            case BYTE:
+                return "readByte(readBuffer, " + sizeInBits + ")";
+            case UINT:
+                if (sizeInBits <= 4) return "readUnsignedByte(readBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 8) return "readUnsignedShort(readBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 16) return "readUnsignedInt(readBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 32) return "readUnsignedLong(readBuffer, " + sizeInBits + ")";
+                return "readUnsignedBigInteger(readBuffer, " + sizeInBits + ")";
+            case INT:
+                if (sizeInBits <= 8) return "readSignedByte(readBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 16) return "readSignedShort(readBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 32) return "readSignedInt(readBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 64) return "readSignedLong(readBuffer, " + sizeInBits + ")";
+                return "readSignedBigInteger(readBuffer, " + sizeInBits + ")";
+            case FLOAT:
+                if (sizeInBits <= 32) return "readFloat(readBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 64) return "readDouble(readBuffer, " + sizeInBits + ")";
+                return "readBigDecimal(readBuffer, " + sizeInBits + ")";
+            case STRING:
+                return "readString(readBuffer, " + sizeInBits + ")";
+            case VSTRING:
+                VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
+                return "readString(readBuffer, " + toParseExpression(null, INT_TYPE_REFERENCE, vstringTypeReference.getLengthExpression(), null) + ")";
+            case TIME:
+                return "readTime(readBuffer)";
+            case DATE:
+                return "readDate(readBuffer)";
+            case DATETIME:
+                return "readDateTime(readBuffer)";
+            default:
+                throw new UnsupportedOperationException("Unsupported type " + simpleTypeReference.getBaseType());
+        }
+    }
+
+    public String getDataWriterCall(TypeReference typeReference, String fieldName) {
+        if (typeReference.isSimpleTypeReference()) {
+            SimpleTypeReference simpleTypeReference = typeReference.asSimpleTypeReference().orElseThrow(IllegalStateException::new);
+            return getDataWriterCall(simpleTypeReference);
+        } else if (typeReference.isComplexTypeReference()) {
+            return "new DataWriterComplexDefault<>(writeBuffer)";
+        } else {
+            throw new IllegalStateException("What is this type? " + typeReference);
+        }
+    }
+
+    public String getEnumDataWriterCall(TypeReference typeReference, String fieldName, String attributeName) {
+        if (!isEnumTypeReference(typeReference)) {
+            throw new IllegalArgumentException("this method should only be called for enum types");
+        }
+        final String languageTypeName = getLanguageTypeNameForTypeReference(typeReference);
+        SimpleTypeReference outputTypeReference;
+        if ("value".equals(attributeName)) {
+            outputTypeReference = getEnumBaseTypeReference(typeReference);
+        } else {
+            outputTypeReference = getEnumFieldSimpleTypeReference(typeReference, attributeName);
+        }
+        return "new DataWriterEnumDefault<>(" + languageTypeName + "::get" + StringUtils.capitalize(attributeName) + ", " + languageTypeName + "::name, " + getDataWriterCall(outputTypeReference, fieldName) + ")";
+    }
+
+    public String getDataWriterCall(SimpleTypeReference simpleTypeReference) {
+        final int sizeInBits = simpleTypeReference.getSizeInBits();
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return "writeBoolean(writeBuffer)";
+            case BYTE:
+                return "writeByte(writeBuffer, " + sizeInBits + ")";
+            case UINT:
+                if (sizeInBits <= 4) return "writeUnsignedByte(writeBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 8) return "writeUnsignedShort(writeBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 16) return "writeUnsignedInt(writeBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 32) return "writeUnsignedLong(writeBuffer, " + sizeInBits + ")";
+                return "writeUnsignedBigInteger(writeBuffer, " + sizeInBits + ")";
+            case INT:
+                if (sizeInBits <= 8) return "writeSignedByte(writeBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 16) return "writeSignedShort(writeBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 32) return "writeSignedInt(writeBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 64) return "writeSignedLong(writeBuffer, " + sizeInBits + ")";
+                return "writeSignedBigInteger(writeBuffer, " + sizeInBits + ")";
+            case FLOAT:
+                if (sizeInBits <= 32) return "writeFloat(writeBuffer, " + sizeInBits + ")";
+                if (sizeInBits <= 64) return "writeDouble(writeBuffer, " + sizeInBits + ")";
+                return "writeBigDecimal(writeBuffer, " + sizeInBits + ")";
+            case STRING:
+                return "writeString(writeBuffer, " + sizeInBits + ")";
+            case VSTRING:
+                VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
+                return "writeString(writeBuffer, " + toParseExpression(null, INT_TYPE_REFERENCE, vstringTypeReference.getLengthExpression(), null) + ")";
+            case TIME:
+                return "writeTime(writeBuffer)";
+            case DATE:
+                return "writeDate(writeBuffer)";
+            case DATETIME:
+                return "writeDateTime(readBuffer)";
+            default:
+                throw new UnsupportedOperationException("Unsupported type " + simpleTypeReference.getBaseType());
+        }
+    }
+
+    @Deprecated
+    @Override
+    public String getWriteBufferWriteMethodCall(SimpleTypeReference simpleTypeReference, String fieldName, TypedField field) {
+        return getWriteBufferWriteMethodCall("", simpleTypeReference, fieldName, field);
+    }
+
+    @Deprecated
+    public String getWriteBufferWriteMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, String fieldName, TypedField field, String... writerArgs) {
+        String writerArgsString = "";
+        if (writerArgs.length > 0) {
+            writerArgsString += ", " + StringUtils.join(writerArgs, ", ");
+        }
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return "writeBuffer.WriteBit(\"" + logicalName + "\", " + fieldName + "" + writerArgsString + ")";
+            case BYTE:
+                ByteTypeReference byteTypeReference = (ByteTypeReference) simpleTypeReference;
+                return "writeBuffer.WriteByte(\"" + logicalName + "\", " + fieldName + writerArgsString + ", 8)";
+            case UINT:
+                IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
+                    return "writeBuffer.WriteByte(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", (byte) " + fieldName + writerArgsString + ")";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
+                    return "writeBuffer.WriteUshort(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", (ushort) " + fieldName + writerArgsString + ")";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
+                    return "writeBuffer.WriteUint(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint) " + fieldName + writerArgsString + ")";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
+                    return "writeBuffer.WriteUlong(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", (ulong) " + fieldName + writerArgsString + ")";
+                }
+                throw new RuntimeException("Unsupported uint type");
+            case INT:
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "writeBuffer.WriteSbyte(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", (sbyte) " + fieldName + writerArgsString + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "writeBuffer.WriteShort(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", (short) " + fieldName + writerArgsString + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "writeBuffer.WriteInt(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", (int) " + fieldName + writerArgsString + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "writeBuffer.WriteLong(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", (long) " + fieldName + writerArgsString + ")";
+                }
+                throw new RuntimeException("Unsupported int type");
+            case FLOAT:
+            case UFLOAT:
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                if (floatTypeReference.getSizeInBits() <= 32) {
+                    return "writeBuffer.WriteFloat(\"" + logicalName + "\", " + floatTypeReference.getSizeInBits() + "," + fieldName + writerArgsString + ")";
+                } else if (floatTypeReference.getSizeInBits() <= 64) {
+                    return "writeBuffer.WriteDouble(\"" + logicalName + "\", " + floatTypeReference.getSizeInBits() + "," + fieldName + writerArgsString + ")";
+                } else {
+                    throw new RuntimeException("Unsupported float type");
+                }
+            case STRING:
+            case VSTRING:
+                final Term encodingTerm = field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"));
+                if (!(encodingTerm instanceof StringLiteral)) {
+                    throw new RuntimeException("Encoding must be a quoted string value");
+                }
+                String encoding = ((StringLiteral) encodingTerm).getValue();
+                String length = Integer.toString(simpleTypeReference.getSizeInBits());
+                if (simpleTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.VSTRING) {
+                    VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
+                    length = toSerializationExpression(field, INT_TYPE_REFERENCE, vstringTypeReference.getLengthExpression(), thisType.getParserArguments().orElse(Collections.emptyList()));
+                }
+                return "writeBuffer.WriteString(\"" + logicalName + "\", " + length + ", \"" +
+                    encoding + "\", (string) " + fieldName + "" + writerArgsString + ")";
+        }
+        throw new FreemarkerException("Unmapped basetype" + simpleTypeReference.getBaseType());
+    }
+
+    public String getReservedValue(ReservedField reservedField) {
+        final String languageTypeName = getLanguageTypeNameForTypeReference(reservedField.getType());
+        if ("BigInteger".equals(languageTypeName)) {
+            return "BigInteger.valueOf(" + reservedField.getReferenceValue() + ")";
+        } else {
+            return "" + reservedField.getReferenceValue();
+        }
+    }
+
+    /**
+     * @param field           this generally only is needed in order to access field attributes such as encoding etc.
+     * @param resultType      the type the resulting expression should have
+     * @param term            the term representing the expression
+     * @param parserArguments any parser arguments, which could be referenced in expressions (Needed for getting the type)
+     * @return Java code which does the things defined in 'term'
+     */
+    public String toParseExpression(Field field, TypeReference resultType, Term term, List<Argument> parserArguments) {
+        Tracer tracer = Tracer.start("toParseExpression");
+        return tracer + toExpression(field, resultType, term, variableLiteral -> tracer.dive("variableExpressionGenerator") + toVariableParseExpression(field, resultType, variableLiteral, parserArguments));
+    }
+
+    /**
+     * @param field               this generally only is needed in order to access field attributes such as encoding etc.
+     * @param resultType          the type the resulting expression should have
+     * @param term                the term representing the expression
+     * @param serializerArguments any serializer arguments, which could be referenced in expressions (Needed for getting the type)
+     * @return Java code which does the things defined in 'term'
+     */
+    public String toSerializationExpression(Field field, TypeReference resultType, Term term, List<Argument> serializerArguments) {
+        Tracer tracer = Tracer.start("toSerializationExpression");
+        return tracer + toExpression(field, resultType, term, variableLiteral -> tracer.dive("variableExpressionGenerator") + toVariableSerializationExpression(field, resultType, variableLiteral, serializerArguments));
+    }
+
+    private String toExpression(Field field, TypeReference resultType, Term term, Function<VariableLiteral, String> variableExpressionGenerator) {
+        Tracer tracer = Tracer.start("toExpression");
+        if (term == null) {
+            return tracer + "";
+        }
+        if (term instanceof Literal) {
+            return toLiteralTermExpression(field, resultType, (Literal) term, variableExpressionGenerator, tracer);
+        } else if (term instanceof UnaryTerm) {
+            return toUnaryTermExpression(field, resultType, (UnaryTerm) term, variableExpressionGenerator, tracer);
+        } else if (term instanceof BinaryTerm) {
+            return toBinaryTermExpression(field, resultType, (BinaryTerm) term, variableExpressionGenerator, tracer);
+        } else if (term instanceof TernaryTerm) {
+            return toTernaryTermExpression(field, resultType, (TernaryTerm) term, variableExpressionGenerator, tracer);
+        } else {
+            throw new RuntimeException("Unsupported Term type " + term.getClass().getName());
+        }
+    }
+
+    private String toLiteralTermExpression(Field field, TypeReference resultType, Literal literal, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
+        tracer = tracer.dive("literal term instanceOf");
+        if (literal instanceof NullLiteral) {
+            tracer = tracer.dive("null literal instanceOf");
+            return tracer + "null";
+        } else if (literal instanceof BooleanLiteral) {
+            tracer = tracer.dive("boolean literal instanceOf");
+            return tracer + Boolean.toString(((BooleanLiteral) literal).getValue());
+        } else if (literal instanceof NumericLiteral) {
+            tracer = tracer.dive("numeric literal instanceOf");
+            final String numberString = ((NumericLiteral) literal).getNumber().toString();
+            if (resultType.isIntegerTypeReference()) {
+                final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(RuntimeException::new);
+                if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
+                    tracer = tracer.dive("uint >= 32bit");
+                    return tracer + numberString + "L";
+                } else if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
+                    tracer = tracer.dive("int > 32bit");
+                    return tracer + numberString + "L";
+                }
+            } else if (resultType.isFloatTypeReference()) {
+                final FloatTypeReference floatTypeReference = resultType.asFloatTypeReference().orElseThrow(RuntimeException::new);
+                if (floatTypeReference.getSizeInBits() <= 32) {
+                    tracer = tracer.dive("float < 32bit");
+                    return tracer + numberString + "F";
+                }
+            }
+            return tracer + numberString;
+        } else if (literal instanceof HexadecimalLiteral) {
+            tracer = tracer.dive("hexadecimal literal instanceOf");
+            final String hexString = ((HexadecimalLiteral) literal).getHexString();
+            if (resultType.isIntegerTypeReference()) {
+                final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(RuntimeException::new);
+                if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
+                    tracer = tracer.dive("uint >= 32bit");
+                    return tracer + hexString + "L";
+                } else if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
+                    tracer = tracer.dive("int > 32bit");
+                    return tracer + hexString + "L";
+                }
+            }
+            return tracer + hexString;
+        } else if (literal instanceof StringLiteral) {
+            tracer = tracer.dive("string literal instanceOf");
+            return tracer + "\"" + ((StringLiteral) literal).getValue() + "\"";
+        } else if (literal instanceof VariableLiteral) {
+            tracer = tracer.dive("variable literal instanceOf");
+            VariableLiteral variableLiteral = (VariableLiteral) literal;
+            if ("curPos".equals(((VariableLiteral) literal).getName())) {
+                return "(readBuffer.getPos() - startPos)";
+            }
+            // If this literal references an Enum type, then we have to output it differently.
+            if (getTypeDefinitions().get(variableLiteral.getName()) instanceof EnumTypeDefinition) {
+                tracer = tracer.dive("enum definition instanceOf");
+                VariableLiteral enumDefinitionChild = variableLiteral.getChild()
+                    .orElseThrow(() -> new RuntimeException("enum definitions should have childs"));
+                return tracer + variableLiteral.getName() + "." + enumDefinitionChild.getName() +
+                    enumDefinitionChild.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+            } else {
+                return tracer + variableExpressionGenerator.apply(variableLiteral);
+            }
+        } else {
+            throw new RuntimeException("Unsupported Literal type " + literal.getClass().getName());
+        }
+    }
+
+    private String toUnaryTermExpression(Field field, TypeReference resultType, UnaryTerm unaryTerm, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
+        tracer = tracer.dive("unary term instanceOf");
+        Term a = unaryTerm.getA();
+        switch (unaryTerm.getOperation()) {
+            case "!":
+                tracer = tracer.dive("case !");
+                if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
+                    throw new IllegalArgumentException("'!(...)' expression requires boolean type");
+                }
+                return tracer + "!(" + toExpression(field, resultType, a, variableExpressionGenerator) + ")";
+            case "-":
+                tracer = tracer.dive("case -");
+                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
+                    throw new IllegalArgumentException("'-(...)' expression requires integer or floating-point type");
+                }
+                return tracer + "-(" + toExpression(field, resultType, a, variableExpressionGenerator) + ")";
+            case "()":
+                tracer = tracer.dive("case ()");
+                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ")";
+            default:
+                throw new RuntimeException("Unsupported unary operation type " + unaryTerm.getOperation());
+        }
+    }
+
+    private String toBinaryTermExpression(Field field, TypeReference resultType, BinaryTerm binaryTerm, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
+        tracer = tracer.dive("binary term instanceOf");
+        Term a = binaryTerm.getA();
+        Term b = binaryTerm.getB();
+        String operation = binaryTerm.getOperation();
+        switch (operation) {
+            case "^": {
+                tracer = tracer.dive(operation);
+                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
+                    throw new IllegalArgumentException("'A^B' expression requires numeric result type");
+                }
+                return tracer + "Math.pow((" + toExpression(field, resultType, a, variableExpressionGenerator) + "), (" + toExpression(field, resultType, b, variableExpressionGenerator) + "))";
+            }
+            case "*":
+            case "/":
+            case "%":
+            case "+":
+            case "-": {
+                tracer = tracer.dive(operation);
+                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
+                    throw new IllegalArgumentException("'A" + operation + "B' expression requires numeric result type");
+                }
+                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
+            }
+            case ">>":
+            case "<<": {
+                tracer = tracer.dive(operation);
+                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, INT_TYPE_REFERENCE, b, variableExpressionGenerator) + ")";
+            }
+            case ">=":
+            case "<=":
+            case ">":
+            case "<":
+            case "==":
+            case "!=": {
+                if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
+                    throw new IllegalArgumentException("'A" + operation + "B' expression requires boolean result type");
+                }
+                // TODO: Try to infer the types of the arguments in this case
+                return tracer + "(" + toExpression(field, ANY_TYPE_REFERENCE, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, ANY_TYPE_REFERENCE, b, variableExpressionGenerator) + ")";
+            }
+            case "&&":
+            case "||": {
+                if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
+                    throw new IllegalArgumentException("'A" + operation + "B' expression requires boolean result type");
+                }
+                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
+            }
+            case "&":
+            case "|": {
+                throw new IllegalArgumentException("Implement this some day ...");
+            }
+            default: {
+                throw new IllegalArgumentException("Unsupported ternary operation type " + operation);
+            }
+        }
+    }
+
+    private String toTernaryTermExpression(Field field, TypeReference resultType, TernaryTerm ternaryTerm, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
+        tracer = tracer.dive("ternary term instanceOf");
+        if ("if".equals(ternaryTerm.getOperation())) {
+            Term a = ternaryTerm.getA();
+            Term b = ternaryTerm.getB();
+            Term c = ternaryTerm.getC();
+            return tracer +
+                "(" +
+                "(" + toExpression(field, BOOL_TYPE_REFERENCE, a, variableExpressionGenerator) + ") ? " +
+                toExpression(field, resultType, b, variableExpressionGenerator) + " : " +
+                toExpression(field, resultType, c, variableExpressionGenerator) + "" +
+                ")";
+        } else {
+            throw new IllegalArgumentException("Unsupported ternary operation type " + ternaryTerm.getOperation());
+        }
+    }
+
+    public String toVariableEnumAccessExpression(VariableLiteral variableLiteral) {
+        return variableLiteral.getName();
+    }
+
+    private String toVariableParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> parserArguments) {
+        Tracer tracer = Tracer.start("toVariableParseExpression");
+        // CAST expressions are special as we need to add a ".class" to the second parameter in Java.
+        if ("CAST".equals(variableLiteral.getName())) {
+            return toCastVariableParseExpression(field, resultType, variableLiteral, parserArguments, tracer);
+        }
+        // Special handling for ByteOrder enums (Built in enums)
+        else if ("BIG_ENDIAN".equals(variableLiteral.getName())) {
+            return "ByteOrder.BIG_ENDIAN";
+        } else if ("LITTLE_ENDIAN".equals(variableLiteral.getName())) {
+            return "ByteOrder.LITTLE_ENDIAN";
+        }
+        // If we're referencing an implicit field, we need to handle that differently.
+        else if (isVariableLiteralImplicitField(variableLiteral)) { // If we are accessing implicit fields, we need to rely on a local variable instead.
+            return toImplicitVariableParseExpression(field, resultType, variableLiteral, tracer);
+        }
+        // Call a static function in the drivers StaticHelper
+        else if ("STATIC_CALL".equals(variableLiteral.getName())) {
+            return toStaticCallParseExpression(field, resultType, variableLiteral, parserArguments, tracer);
+        }
+        // Call a built-in global static function
+        else if (variableLiteral.getName().equals(variableLiteral.getName().toUpperCase())) { // All uppercase names are not fields, but utility methods.
+            return toFunctionCallParseExpression(field, resultType, variableLiteral, parserArguments, tracer);
+        }
+        // The synthetic checksumRawData is a local field and should not be accessed as bean property.
+        boolean isParserArg = "readBuffer".equals(variableLiteral.getName());
+        boolean isTypeArg = "_type".equals(variableLiteral.getName());
+        if (!isParserArg && !isTypeArg && parserArguments != null) {
+            for (Argument serializerArgument : parserArguments) {
+                if (serializerArgument.getName().equals(variableLiteral.getName())) {
+                    isParserArg = true;
+                    break;
+                }
+            }
+        }
+        if (isParserArg) {
+            tracer = tracer.dive("parser arg");
+            return tracer + variableLiteral.getName() + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+        } else if (isTypeArg) {
+            tracer = tracer.dive("type arg");
+            String part = variableLiteral.getChild().map(VariableLiteral::getName).orElse("");
+            switch (part) {
+                case "name":
+                    return tracer + "\"" + field.getTypeName() + "\"";
+                case "length":
+                    return tracer + "\"" + ((SimpleTypeReference) field).getSizeInBits() + "\"";
+                case "encoding":
+                    String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
+                    return tracer + "\"" + encoding + "\"";
+                default:
+                    return tracer + "";
+            }
+        } else {
+            return tracer + variableLiteral.getName() + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+        }
+    }
+
+    private String toCastVariableParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> parserArguments, Tracer tracer) {
+        tracer = tracer.dive("CAST");
+        List<Term> arguments = variableLiteral.getArgs().orElseThrow(() -> new RuntimeException("A Cast expression needs arguments"));
+        if (arguments.size() != 2) {
+            throw new RuntimeException("A CAST expression expects exactly two arguments.");
+        }
+        VariableLiteral firstArgument = arguments.get(0).asLiteral()
+            .orElseThrow(() -> new RuntimeException("First argument should be a literal"))
+            .asVariableLiteral()
+            .orElseThrow(() -> new RuntimeException("First argument should be a Variable literal"));
+        StringLiteral typeArgument = arguments.get(1).asLiteral().orElseThrow(() -> new RuntimeException("Second argument should be a String literal"))
+            .asStringLiteral()
+            .orElseThrow(() -> new RuntimeException("Second argument should be a String literal"));
+        String sb = "CAST" + "(" +
+            toVariableParseExpression(field, ANY_TYPE_REFERENCE, firstArgument, parserArguments) +
+            ", " +
+            typeArgument.getValue() + ".class)";
+        return tracer + sb + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+    }
+
+    private String toImplicitVariableParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, Tracer tracer) {
+        tracer = tracer.dive("implicit");
+        return tracer + variableLiteral.getName();
+    }
+
+    private String toStaticCallParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> parserArguments, Tracer tracer) {
+        tracer = tracer.dive("STATIC_CALL");
+        List<Term> arguments = variableLiteral.getArgs().orElseThrow(() -> new RuntimeException("A STATIC_CALL expression needs arguments"));
+        if (arguments.size() < 1) {
+            throw new RuntimeException("A STATIC_CALL expression expects at least one argument.");
+        }
+        // TODO: make it as static import with a emitImport so if a static call is present a "utils" package must be present in the import
+        StringBuilder sb = new StringBuilder();
+        sb.append(packageName()).append(".utils.StaticHelper.");
+        // Get the class and method name
+        String methodName = arguments.get(0).asLiteral()
+            .orElseThrow(() -> new RuntimeException("First argument should be a literal"))
+            .asStringLiteral()
+            .orElseThrow(() -> new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral")).
+            getValue();
+        sb.append(methodName).append("(");
+        for (int i = 1; i < arguments.size(); i++) {
+            Term arg = arguments.get(i);
+            if (i > 1) {
+                sb.append(", ");
+            }
+            sb.append(toParseExpression(field, ANY_TYPE_REFERENCE, arg, parserArguments));
+           /*if (arg instanceof VariableLiteral) {
+                VariableLiteral variableLiteralArg = (VariableLiteral) arg;
+                // "readBuffer" is the default name of the reader argument which is always available.
+                boolean isParserArg = "readBuffer".equals(variableLiteralArg.getName());
+                boolean isTypeArg = "_type".equals(variableLiteralArg.getName());
+                if (!isParserArg && !isTypeArg && parserArguments != null) {
+                    for (Argument parserArgument : parserArguments) {
+                        if (parserArgument.getName().equals(variableLiteralArg.getName())) {
+                            isParserArg = true;
+                            break;
+                        }
+                    }
+                }
+                if (isParserArg) {
+                    sb.append(variableLiteralArg.getName()).append(variableLiteralArg.getChild().map(child -> "." + toVariableExpressionRest(child)).orElse(""));
+                } else if (isTypeArg) {// We have to manually evaluate the type information at code-generation time.
+                    String part = variableLiteralArg.getChild().map(VariableLiteral::getName).orElse("");
+                    switch (part) {
+                        case "name":
+                            sb.append("\"").append(field.getTypeName()).append("\"");
+                            break;
+                        case "length":
+                            sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
+                            break;
+                        case "encoding":
+                            String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
+                            sb.append("\"").append(encoding).append("\"");
+                            break;
+                    }
+                } else {
+                    sb.append(toVariableParseExpression(field, variableLiteralArg, null));
+                }
+            } else if (arg instanceof StringLiteral) {
+                sb.append(((StringLiteral) arg).getValue());
+            }*/
+        }
+        sb.append(")");
+        if (variableLiteral.getIndex() != VariableLiteral.NO_INDEX) {
+            // TODO: If this is a byte typed field, this needs to be an array accessor instead.
+            sb.append(".get(").append(variableLiteral.getIndex()).append(")");
+        }
+        return tracer + sb.toString();
+    }
+
+    private String toFunctionCallParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> parserArguments, Tracer tracer) {
+        tracer = tracer.dive("FunctionCall");
+        StringBuilder sb = new StringBuilder(variableLiteral.getName());
+        if (variableLiteral.getArgs().isPresent()) {
+            sb.append("(");
+            boolean firstArg = true;
+            for (Term arg : variableLiteral.getArgs().get()) {
+                if (!firstArg) {
+                    sb.append(", ");
+                }
+                // TODO: Try to infer the type of the argument ...
+                sb.append(toParseExpression(field, ANY_TYPE_REFERENCE, arg, parserArguments));
+                firstArg = false;
+            }
+            sb.append(")");
+        }
+        if (variableLiteral.getIndex() != VariableLiteral.NO_INDEX) {
+            // TODO: If this is a byte typed field, this needs to be an array accessor instead.
+            sb.append(".get(").append(variableLiteral.getIndex()).append(")");
+        }
+        return tracer + sb.toString() + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+    }
+
+    private String toVariableSerializationExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> serialzerArguments) {
+        Tracer tracer = Tracer.start("variable serialization expression");
+        if ("STATIC_CALL".equals(variableLiteral.getName())) {
+            return toStaticCallSerializationExpression(field, resultType, variableLiteral, serialzerArguments, tracer);
+        }
+        // All uppercase names are not fields, but utility methods.
+        else if (variableLiteral.getName().equals(variableLiteral.getName().toUpperCase())) {
+            return toGlobalFunctionCallSerializationExpression(field, resultType, variableLiteral, serialzerArguments, tracer);
+        } else if (isVariableLiteralImplicitField(variableLiteral)) { // If we are accessing implicit fields, we need to rely on a local variable instead.
+            tracer = tracer.dive("implicit field");
+            final ImplicitField referencedImplicitField = getReferencedImplicitField(variableLiteral);
+            return tracer + toSerializationExpression(referencedImplicitField, referencedImplicitField.getType(), getReferencedImplicitField(variableLiteral).getSerializeExpression(), serialzerArguments);
+        } else if (isVariableLiteralVirtualField(variableLiteral)) {
+            tracer = tracer.dive("virtual field");
+            return tracer + toVariableExpressionRest(field, resultType, variableLiteral);
+        }
+        // The synthetic checksumRawData is a local field and should not be accessed as bean property.
+        boolean isSerializerArg = "writeBuffer".equals(variableLiteral.getName()) || "checksumRawData".equals(variableLiteral.getName()) || "_value".equals(variableLiteral.getName()) || "element".equals(variableLiteral.getName()) || "size".equals(variableLiteral.getName());
+        boolean isTypeArg = "_type".equals(variableLiteral.getName());
+        if (!isSerializerArg && !isTypeArg && serialzerArguments != null) {
+            for (Argument serializerArgument : serialzerArguments) {
+                if (serializerArgument.getName().equals(variableLiteral.getName())) {
+                    isSerializerArg = true;
+                    break;
+                }
+            }
+        }
+        if (isSerializerArg) {
+            tracer = tracer.dive("serializer arg");
+            return tracer + variableLiteral.getName() + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+        } else if (isTypeArg) {
+            tracer = tracer.dive("type arg");
+            String part = variableLiteral.getChild().map(VariableLiteral::getName).orElse("");
+            switch (part) {
+                case "name":
+                    return tracer + "\"" + field.getTypeName() + "\"";
+                case "length":
+                    return tracer + "\"" + ((SimpleTypeReference) field).getSizeInBits() + "\"";
+                case "encoding":
+                    String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
+                    return tracer + "\"" + encoding + "\"";
+                default:
+                    return tracer + "";
+            }
+        } else {
+            return tracer + toVariableExpressionRest(field, resultType, variableLiteral);
+        }
+    }
+
+    private String toGlobalFunctionCallSerializationExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> serialzerArguments, Tracer tracer) {
+        tracer = tracer.dive("GLOBAL_FUNCTION_CALL");
+        StringBuilder sb = new StringBuilder(variableLiteral.getName());
+        if (variableLiteral.getArgs().isPresent()) {
+            sb.append("(");
+            boolean firstArg = true;
+            for (Term arg : variableLiteral.getArgs().get()) {
+                if (!firstArg) {
+                    sb.append(", ");
+                }
+                sb.append(toSerializationExpression(field, ANY_TYPE_REFERENCE, arg, serialzerArguments));
+                firstArg = false;
+                /*if (arg instanceof VariableLiteral) {
+                    VariableLiteral va = (VariableLiteral) arg;
+                    boolean isSerializerArg = "readBuffer".equals(va.getName()) || "writeBuffer".equals(va.getName());
+                    boolean isTypeArg = "_type".equals(va.getName());
+                    if (!isSerializerArg && !isTypeArg && serialzerArguments != null) {
+                        for (Argument serializerArgument : serialzerArguments) {
+                            if (serializerArgument.getName().equals(va.getName())) {
+                                isSerializerArg = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (isSerializerArg) {
+                        sb.append(va.getName()).append(va.getChild().map(child -> "." + toVariableExpressionRest(child)).orElse(""));
+                    } else if (isTypeArg) {
+                        String part = va.getChild().map(VariableLiteral::getName).orElse("");
+                        switch (part) {
+                            case "name":
+                                sb.append("\"").append(field.getTypeName()).append("\"");
+                                break;
+                            case "length":
+                                sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
+                                break;
+                            case "encoding":
+                                String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
+                                sb.append("\"").append(encoding).append("\"");
+                                break;
+                        }
+                    } else {
+                        sb.append(toVariableSerializationExpression(field, va, serialzerArguments));
+                    }
+                } else if (arg instanceof StringLiteral) {
+                    sb.append(((StringLiteral) arg).getValue());
+                }*/
+            }
+            sb.append(")");
+        }
+        return tracer + sb.toString();
+    }
+
+    private String toStaticCallSerializationExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> serialzerArguments, Tracer tracer) {
+        tracer = tracer.dive("STATIC_CALL");
+        StringBuilder sb = new StringBuilder();
+        List<Term> arguments = variableLiteral.getArgs().orElseThrow(() -> new RuntimeException("A STATIC_CALL expression needs arguments"));
+        if (arguments.size() < 1) {
+            throw new RuntimeException("A STATIC_CALL expression expects at least one argument.");
+        }
+        // TODO: make it as static import with a emitImport so if a static call is present a "utils" package must be present in the import
+        sb.append(packageName()).append(".utils.StaticHelper.");
+        // Get the class and method name
+        String methodName = arguments.get(0).asLiteral()
+            .orElseThrow(() -> new RuntimeException("First argument should be a literal"))
+            .asStringLiteral()
+            .orElseThrow(() -> new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral")).
+            getValue();
+        //methodName = methodName.substring(1, methodName.length() - 1);
+        sb.append(methodName).append("(");
+        for (int i = 1; i < arguments.size(); i++) {
+            Term arg = arguments.get(i);
+            if (i > 1) {
+                sb.append(", ");
+            }
+            sb.append(toSerializationExpression(field, ANY_TYPE_REFERENCE, arg, serialzerArguments));
+            /*if (arg instanceof VariableLiteral) {
+                VariableLiteral va = (VariableLiteral) arg;
+                // "readBuffer" and "_value" are always available in every parser.
+                boolean isSerializerArg = "readBuffer".equals(va.getName()) || "writeBuffer".equals(va.getName()) || "_value".equals(va.getName()) || "element".equals(va.getName());
+                boolean isTypeArg = "_type".equals(va.getName());
+                if (!isSerializerArg && !isTypeArg && serialzerArguments != null) {
+                    for (Argument serializerArgument : serialzerArguments) {
+                        if (serializerArgument.getName().equals(va.getName())) {
+                            isSerializerArg = true;
+                            break;
+                        }
+                    }
+                }
+                if (isSerializerArg) {
+                    sb.append(va.getName()).append(va.getChild().map(child -> "." + toVariableExpressionRest(child)).orElse(""));
+                } else if (isTypeArg) {
+                    String part = va.getChild().map(VariableLiteral::getName).orElse("");
+                    switch (part) {
+                        case "name":
+                            sb.append("\"").append(field.getTypeName()).append("\"");
+                            break;
+                        case "length":
+                            sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
+                            break;
+                        case "encoding":
+                            String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
+                            sb.append("\"").append(encoding).append("\"");
+                            break;
+                    }
+                } else {
+                    sb.append(toVariableSerializationExpression(field, va, serialzerArguments));
+                }
+            } else if (arg instanceof StringLiteral) {
+                sb.append(((StringLiteral) arg).getValue());
+            }*/
+        }
+        sb.append(")");
+        return tracer + sb.toString();
+    }
+
+    private String toVariableExpressionRest(Field field, TypeReference resultType, VariableLiteral variableLiteral) {
+        Tracer tracer = Tracer.start("variable expression rest");
+        // length is kind of a keyword in mspec, so we shouldn't be naming variables length. if we ask for the length of a object we can just return length().
+        // This way we can get the length of a string when serializing
+        String variableLiteralName = variableLiteral.getName();
+        if (variableLiteralName.equals("length")) {
+            tracer = tracer.dive("length");
+            return tracer + variableLiteralName + "()" + ((variableLiteral.isIndexed() ? ".get(" + variableLiteral.getIndex() + ")" : "") +
+                variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse(""));
+        }
+        return tracer + "get" + WordUtils.capitalize(variableLiteralName) + "()" + ((variableLiteral.isIndexed() ? ".get(" + variableLiteral.getIndex() + ")" : "") +
+            variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse(""));
+    }
+
+    public String getSizeInBits(ComplexTypeDefinition complexTypeDefinition, List<Argument> parserArguments) {
+        int sizeInBits = 0;
+        StringBuilder sb = new StringBuilder();
+        for (Field field : complexTypeDefinition.getFields()) {
+            if (field instanceof ArrayField) {
+                ArrayField arrayField = (ArrayField) field;
+                final SimpleTypeReference type = (SimpleTypeReference) arrayField.getType();
+                switch (arrayField.getLoopType()) {
+                    case COUNT:
+                        sb.append("(").append(toSerializationExpression(null, INT_TYPE_REFERENCE, arrayField.getLoopExpression(), parserArguments)).append(" * ").append(type.getSizeInBits()).append(") + ");
+                        break;
+                    case LENGTH:
+                        sb.append("(").append(toSerializationExpression(null, INT_TYPE_REFERENCE, arrayField.getLoopExpression(), parserArguments)).append(" * 8) + ");
+                        break;
+                    case TERMINATED:
+                        // No terminated.
+                        break;
+                }
+            } else if (field instanceof TypedField) {
+                TypedField typedField = (TypedField) field;
+                final TypeReference type = typedField.getType();
+                if (field instanceof ManualField) {
+                    ManualField manualField = (ManualField) field;
+                    sb.append("(").append(toSerializationExpression(null, INT_TYPE_REFERENCE, manualField.getLengthExpression(), parserArguments)).append(") + ");
+                } else if (type instanceof SimpleTypeReference) {
+                    SimpleTypeReference simpleTypeReference = (SimpleTypeReference) type;
+                    if (simpleTypeReference instanceof VstringTypeReference) {
+                        sb.append(toSerializationExpression(null, INT_TYPE_REFERENCE, ((VstringTypeReference) simpleTypeReference).getLengthExpression(), parserArguments)).append(" + ");
+                    } else {
+                        sizeInBits += simpleTypeReference.getSizeInBits();
+                    }
+                }
+            }
+        }
+        return sb.toString() + sizeInBits;
+    }
+
+    public String escapeValue(TypeReference typeReference, String valueString) {
+        if (valueString == null) {
+            return null;
+        }
+        if (typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case UINT:
+                case INT:
+                    // If it's a one character string and is numeric, output it as char.
+                    if (!NumberUtils.isParsable(valueString) && (valueString.length() == 1)) {
+                        return "'" + valueString + "'";
+                    }
+                    break;
+                case STRING:
+                case VSTRING:
+                    return "\"" + valueString + "\"";
+            }
+        } else if (isEnumTypeReference(typeReference)) {
+            return "model." + typeReference.asComplexTypeReference().orElseThrow().getName() + "." + valueString;
+        }
+        return valueString;
+    }
+
+    public String getFieldOptions(TypedField field, List<Argument> parserArguments) {
+        StringBuilder sb = new StringBuilder();
+        final Optional<Term> encodingOptional = field.getEncoding();
+        if (encodingOptional.isPresent()) {
+            final String encoding = toParseExpression(field, field.getType(), encodingOptional.get(), parserArguments);
+            sb.append(", WithOption.WithEncoding(").append(encoding).append(")");
+        }
+        final Optional<Term> byteOrderOptional = field.getByteOrder();
+        if (byteOrderOptional.isPresent()) {
+            final String byteOrder = toParseExpression(field, field.getType(), byteOrderOptional.get(), parserArguments);
+            sb.append(", WithOption.WithByteOrder(").append(byteOrder).append(")");
+        }
+        return sb.toString();
+    }
+
+}
diff --git a/build-utils/language-cs/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput b/code-generation/language-cs/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput
similarity index 100%
rename from build-utils/language-cs/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput
rename to code-generation/language-cs/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput
diff --git a/code-generation/language-cs/src/main/resources/templates/cs/data-io-template.cs.ftlh b/code-generation/language-cs/src/main/resources/templates/cs/data-io-template.cs.ftlh
new file mode 100644
index 0000000..38572af
--- /dev/null
+++ b/code-generation/language-cs/src/main/resources/templates/cs/data-io-template.cs.ftlh
@@ -0,0 +1,437 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
+<#-- @ftlvariable name="tracer" type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/${type.name}.cs
+/*
+ * 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.
+ */
+
+// Code generated by code-generation. DO NOT EDIT.
+
+using System;
+using System.Collections.Generic;
+using NLog;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+<#-- TODO: the code below implies that parserArguments will be null if not present... not pretty  -->
+<#if type.parserArguments.isPresent()><#assign parserArguments=type.parserArguments.orElseThrow()></#if>
+namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFlavor?replace("-", "")}.model
+{
+
+    public class ${type.name}
+    {
+
+        private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
+
+        public static IPlcValue StaticParse(ReadBuffer readBuffer<#if type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>)
+        {
+        <#assign defaultCaseOutput=false>
+        <#assign dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
+        <#list dataIoTypeDefinition.switchField.cases as case>
+            <@compress single_line=true>
+                <#if case.discriminatorValueTerms?has_content>
+                    if(
+                    <#list case.discriminatorValueTerms as discriminatorValueTerm>
+                        <#assign discriminatorExpression=dataIoTypeDefinition.switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
+                        <#assign discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
+                        ${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorExpression, parserArguments)} ==
+                        <#if helper.isEnumTypeReference(discriminatorType)>
+                        ${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
+                        <#else>
+                        ${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
+                        </#if>
+                        <#sep> && </#sep>
+                    </#list>
+                    )
+                <#else>
+                    <#assign defaultCaseOutput=true>
+                </#if>
+            </...@compress> { // ${case.name}
+            <#assign valueDefined=false>
+            <#list case.fields as field>
+                <#switch field.typeName>
+                    <#case "array">
+                        <#assign arrayField = field.asArrayField().orElseThrow()>
+                // Array field (${arrayField.name})
+                <#-- Only update curPos if the length expression uses it -->
+                        <#if arrayField.loopExpression.contains("curPos")>
+                curPos = readBuffer.getPos() - startPos;
+                        </#if>
+                <#-- If this is a count array, we can directly initialize an array with the given size -->
+                        <#if field.isCountArrayField()>
+                // Count array
+                List<IPlcValue> ${arrayField.name};
+                {
+                    var itemCount = ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression,parserArguments)};
+                    ${arrayField.name} = new List<IPlcValue>();
+                    for (var curItem = 0; curItem < itemCount; curItem++) {
+                        ${arrayField.name}.Add(new ${helper.getPlcValueTypeForTypeReference(arrayField.type)}(<#if helper.isSimpleTypeReference(arrayField.type)>${helper.getReadBufferReadMethodCall(arrayField.type.asSimpleTypeReference().orElseThrow(), "", arrayField)})<#else>${arrayField.type.asComplexTypeReference().orElseThrow().name}IO.StaticParse(readBuffer<#if arrayField.params.isPresent()>, <#list arrayField.params.orElseThrow() as parserArgument>(${helper.getLanguageTypeNameForTy [...]
+                    }
+                }
+                <#-- In all other cases do we have to work with a list, that is later converted to an array -->
+                        <#else>
+                <#-- For a length array, we read data till the read position of the buffer reaches a given position -->
+                            <#if arrayField.isLengthArrayField()>
+                // Length array
+                var _${arrayField.name}Length = ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression,parserArguments)};
+                var ${arrayField.name}EndPos = readBuffer.getPos() + _${arrayField.name}Length;
+                var value = new List<IPlcValue>();
+                while(readBuffer.getPos() < ${arrayField.name}EndPos) {
+                    value.Add(
+                <#if helper.isSimpleTypeReference(arrayField.type)>
+                        new ${helper.getPlcValueTypeForTypeReference(arrayField.type)}(${helper.getReadBufferReadMethodCall(arrayField.type.asSimpleTypeReference().orElseThrow(), "", arrayField)})
+                <#else>${arrayField.type.asComplexTypeReference().orElseThrow().name}IO.StaticParse(readBuffer
+                    <#if arrayField.params.isPresent()>,
+                        <#list arrayField.params.orElseThrow() as parserArgument>
+                                (${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(arrayField.type, parserArgument?index))}) (${helper.toParseExpression(arrayField,arrayField.type, parserArgument,parserArguments)})
+                            <#sep>, </#sep>
+                        </#list>
+                    </#if>
+                        )
+                </#if>
+                    );
+                }
+                <#-- A terminated array keeps on reading data as long as the termination expression evaluates to false -->
+                            <#elseif arrayField.isTerminatedArrayField()>
+                // Terminated array
+                var ${arrayField.name} = new List<${helper.getLanguageTypeNameForField(arrayField)}>();
+                while(!((boolean) (${helper.toParseExpression(arrayField, helper.boolTypeReference, arrayField.loopExpression,parserArguments)}))) {
+                    ${arrayField.name}.Add(<#if helper.isSimpleTypeReference(arrayField.type)>${helper.getReadBufferReadMethodCall(arrayField.type.asSimpleTypeReference().orElseThrow(), "", arrayField)}<#else>${arrayField.type.asComplexTypeReference().orElseThrow().name}IO.StaticParse(readBuffer<#if arrayField.params.isPresent()>, <#list arrayField.params.orElseThrow() as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(arrayField.type, parserArgument?i [...]
+
+                <#-- After parsing, update the current position, but only if it's needed -->
+                                <#if arrayField.loopExpression.contains("curPos")>
+                    curPos = readBuffer.getPos() - startPos;
+                                </#if>
+                }
+                            </#if>
+                        </#if>
+                        <#if arrayField.name == "value">
+                            <#assign valueDefined=true>
+                        </#if>
+                    <#break>
+                    <#case "const">
+                        <#assign constField=field.asConstField().orElseThrow()>
+
+                // Const Field (${constField.name})
+                var ${constField.name} = ${helper.getReadBufferReadMethodCall(constField.type.asSimpleTypeReference().orElseThrow(), "", constField)};
+                if(${constField.name} != ${dataIoTypeDefinition.name}.${constField.name?upper_case}) {
+                    throw new ParseException("Expected constant value " + ${dataIoTypeDefinition.name}.${constField.name?upper_case} + " but got " + ${constField.name});
+                }
+                        <#if constField.name == "value">
+                            <#assign valueDefined=true>
+                        </#if>
+                    <#break>
+                    <#case "enum">
+                        <#assign enumField=field.asEnumField().orElseThrow()>
+
+                // Enum field (${enumField.name})
+                var ${enumField.name} = ${helper.getLanguageTypeNameForField(enumField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(enumField.type.asSimpleTypeReference().orElseThrow()), "", enumField)});
+                        <#if enumField.name == "value">
+                            <#assign valueDefined=true>
+                        </#if>
+                    <#break>
+                    <#case "manual">
+                        <#assign manualField=field.asManualField().orElseThrow()>
+
+                // Manual Field (${manualField.name})
+                var ${manualField.name} = (${helper.getLanguageTypeNameForField(manualField)}) (${helper.toParseExpression(manualField, manualField.type, manualField.parseExpression,parserArguments)});
+                        <#if manualField.name == "value">
+                            <#assign valueDefined=true>
+                        </#if>
+                    <#break>
+                    <#case "reserved">
+                        <#assign reservedField=field.asReservedField().orElseThrow()>
+
+                // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+                {
+                    var reserved = ${helper.getReadBufferReadMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(), "", reservedField)};
+                    if(reserved != ${helper.getReservedValue(reservedField)}) {
+                        Logger.Info("Expected constant value {expected} but got {got} for reserved field.", ${reservedField.referenceValue}, reserved);
+                    }
+                }
+                    <#break>
+                    <#case "simple">
+                        <#assign simpleField=field.asSimpleField().orElseThrow()>
+
+                        <#if helper.isEnumField(simpleField)>
+                // Enum field (${simpleField.name})
+                var ${simpleField.name} = ${helper.getLanguageTypeNameForField(simpleField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(simpleField.type), "", simpleField)});
+                        <#else>
+                // Simple Field (${simpleField.name})
+                var ${simpleField.name} = <#if helper.isSimpleTypeReference(simpleField.type)>${helper.getReadBufferReadMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(), "", simpleField)}<#else>${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.StaticParse(readBuffer<#if simpleField.params.isPresent()>, <#list field.params.orElseThrow() as parserArgument>(${helper.getLanguageTypeNameForField(helper.getArgumentType(simpleField.type, parserArgument?index), t [...]
+                        </#if>
+                        <#if case.name == "Struct" ||
+                            ((case.name == "DATE_AND_TIME") && ((simpleField.name == "year") || (simpleField.name == "month") || (simpleField.name == "day") || (simpleField.name == "hour") || (simpleField.name == "minutes") || (simpleField.name == "seconds"))) ||
+                            ((case.name == "DATE_AND_TIME") && (simpleField.name == "secondsSinceEpoch")) ||
+                            ((case.name == "DATE") && ((simpleField.name == "year") || (simpleField.name == "month") || (simpleField.name == "day"))) ||
+                            ((case.name == "TIME_OF_DAY") && ((simpleField.name == "hour") || (simpleField.name == "minutes") || (simpleField.name == "seconds"))) ||
+                        simpleField.name == "value">
+                            <#assign valueDefined=true>
+                        </#if>
+                    <#break>
+                </#switch>
+            </#list>
+            <#if case.name == "Struct">
+
+                <#-- In this case we need to wrap each field in a IPlcValue that matches it's natural type -->
+                var _map = new Dictionary<string, IPlcValue>();
+                <#list case.fields as field>
+                    <#if field.isArrayField()>
+                        <#assign field=field.asArrayField().orElseThrow()>
+                _map["${field.name}"] = new PlcList(${field.name});
+                    <#elseif field.isPropertyField()>
+                        <#assign field=field.asPropertyField().orElseThrow()>
+                        <#switch helper.getLanguageTypeNameForTypeReference(field.type)>
+                            <#case "Boolean">
+                _map["${field.name}"] = new PlcBOOL(${field.name});
+                                <#break>
+                            <#case "Byte">
+                _map["${field.name}"] = new PlcSINT(${field.name});
+                                <#break>
+                            <#case "Short">
+                _map["${field.name}"] = new PlcINT(${field.name});
+                                <#break>
+                            <#case "Integer">
+                _map["${field.name}"] = new PlcDINT(${field.name});
+                                <#break>
+                            <#case "Long">
+                _map["${field.name}"] = new PlcLINT(${field.name});
+                                <#break>
+                            <#case "BigInteger">
+                _map["${field.name}"] = new PlcBigInteger(${field.name});
+                                <#break>
+                            <#case "Float">
+                _map["${field.name}"] = new PlcREAL(${field.name});
+                                <#break>
+                            <#case "Double">
+                _map["${field.name}"] = new PlcLREAL(${field.name});
+                                <#break>
+                            <#case "BigDecimal">
+                _map["${field.name}"] = new PlcBigDecimal(${field.name});
+                                <#break>
+                            <#case "String">
+                _map["${field.name}"] = new PlcSTRING(${field.name});
+                                <#break>
+                            <#case "LocalTime">
+                _map["${field.name}"] = new PlcTIME_OF_DAY(${field.name});
+                                <#break>
+                            <#case "LocalDate">
+                _map["${field.name}"] = new PlcDATE(${field.name});
+                                <#break>
+                            <#case "LocalDateTime">
+                _map["${field.name}"] = new PlcDATE_AND_TIME(${field.name});
+                                <#break>
+                        </#switch>
+                    </#if>
+                </#list>
+                <#assign valueDefined=true>
+            </#if>
+
+            <#if valueDefined>
+                <#switch case.name>
+                    <#case "TIME">
+                return new PlcTIME(TimeSpan.FromSeconds(value));
+                    <#break>
+                    <#case "LTIME">
+                return new PlcTIME(TimeSpan.FromMilliseconds(value));
+                    <#break>
+                    <#case "TIME_OF_DAY">
+                return new PlcTIME_OF_DAY(DateTime.Now); <#-- TODO: Convert uint to time-of-day ... -->
+                    <#break>
+                    <#case "DATE">
+                    <#if helper.hasFieldsWithNames(case.fields, "value")>
+                return new PlcDATE(DateTime.Now); <#-- TODO: Convert ushort to date ... -->
+                    <#elseif helper.hasFieldsWithNames(case.fields, "year", "month", "day")>
+                return new PlcDATE(LocalDate.of(year.intValue(), (month == 0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue());
+                    </#if>
+                    <#break>
+                    <#case "TIME_OF_DAY">
+                    <#if helper.hasFieldsWithNames(case.fields, "hour", "minutes", "seconds", "nanos")>
+                LocalTime value = LocalTime.of(hour.intValue(), minutes.intValue(), seconds.intValue(), (int) (nanos / 1000000));
+                    <#elseif helper.hasFieldsWithNames(case.fields, "hour", "minutes", "seconds")>
+                LocalTime value = LocalTime.of(hour.intValue(), minutes.intValue(), seconds.intValue());
+                    </#if>
+                return new PlcTIME_OF_DAY(value);
+                    <#break>
+                    <#case "DATE_AND_TIME">
+                    <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds", "nanos")>
+                var value = new DateTime(year, (month == 0) ? 1 : month, (day == 0) ? 1 : day, hour, minutes, seconds, (int) (nanos / 1000000));
+                    <#elseif helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds")>
+                var value = new DateTime(year, (month == 0) ? 1 : month, (day == 0) ? 1 : day, hour, minutes, seconds, 0);
+                    <#elseif helper.hasFieldsWithNames(case.fields, "secondsSinceEpoch")>
+                var value = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(value);
+                    </#if>
+                return new PlcDATE_AND_TIME(value);
+                    <#break>
+                    <#case "CHAR">
+                return new PlcCHAR(Convert.ToChar(value));
+                    <#break>
+                    <#case "WCHAR">
+                return new PlcWCHAR(Convert.ToChar(value));
+                    <#break>
+                    <#case "Struct">
+                return new PlcStruct(_map);
+                    <#break>
+                    <#case "List">
+                return new PlcList(value);
+                    <#break>
+                    <#default>
+                return new Plc${case.name}(value);
+                </#switch>
+            </#if>
+            }<#sep> else </#sep></#list>
+        <#if !defaultCaseOutput>
+            return null;
+        </#if>
+        }
+
+<#if outputFlavor != "passive">
+            public static WriteBuffer StaticSerialize(IPlcValue _value<#if type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>)
+            {
+                return StaticSerialize(_value<#if type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>, ByteOrder.BIG_ENDIAN);
+            }
+
+            public static WriteBuffer StaticSerialize(IPlcValue _value<#if type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>, ByteOrder byteOrder)
+            {
+        <#assign defaultCaseOutput=false>
+        <#assign dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
+        <#list dataIoTypeDefinition.switchField.cases as case>
+        <@compress single_line=true>
+            <#if case.discriminatorValueTerms?has_content>
+                    if(
+                <#list case.discriminatorValueTerms as discriminatorValueTerm>
+                    <#assign discriminatorExpression=dataIoTypeDefinition.switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
+                    <#assign discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
+                            ${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorExpression, parserArguments)} ==
+                    <#if helper.isEnumTypeReference(discriminatorType)>
+                            ${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
+                    <#else>
+                            ${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
+                    </#if>
+                    <#sep> && </#sep>
+                </#list>
+                )
+            <#else>
+                <#assign defaultCaseOutput=true>
+            </#if>
+        </...@compress> { // ${case.name}
+                var writeBuffer = new WriteBuffer();
+
+            <#list case.fields as field>
+                <#switch field.typeName>
+                    <#case "array">
+                        <#assign arrayField=field.asArrayField().orElseThrow()>
+                PlcList values = (PlcList) _value;
+
+                        <#if case.name == "Struct">
+                foreach (IPlcValue val in values.GetStruct()["${arrayField.name}"].GetList()) {
+                    ${helper.getLanguageTypeNameForField(arrayField)} value = (${helper.getLanguageTypeNameForField(arrayField)}) val.Get${helper.getLanguageTypeNameForField(arrayField)?cap_first}();
+                    ${helper.getWriteBufferWriteMethodCall(arrayField.type.asSimpleTypeReference().orElseThrow(), "value", arrayField)};
+                }
+                        <#else>
+                foreach (IPlcValue val in values.GetList()) {
+                    ${helper.getLanguageTypeNameForField(arrayField)} value = val.Get${helper.getLanguageTypeNameForField(arrayField)?cap_first}();
+                    ${helper.getWriteBufferWriteMethodCall(arrayField.type.asSimpleTypeReference().orElseThrow(), "(" + arrayField.name + ")", arrayField)};
+                }
+                        </#if>
+
+                    <#if case.name == "BOOL">
+                while (writeBuffer.getPos() < writeBuffer.getData().length) {
+                    writeBuffer.writeBit(false);
+                }
+                    </#if>
+                    <#break>
+                    <#case "const">
+                        <#assign constField=field.asConstField().orElseThrow()>
+                // Const Field (${constField.name})
+                ${helper.getWriteBufferWriteMethodCall(constField.type.asSimpleTypeReference().orElseThrow(), constField.referenceValue, constField)};
+                    <#break>
+                    <#case "enum">
+                        <#assign enumField=field.asEnumField().orElseThrow()>
+                // Enum field (${enumField.name})
+                var ${enumField.name} = (${helper.getLanguageTypeNameForField(field)}) _value.get${enumField.name?cap_first}();
+                ${helper.getWriteBufferWriteMethodCall(helper.getEnumBaseTypeReference(field.asTypedField().orElseThrow().type), "(" + enumField.name + ".getValue())", enumField)};
+                    <#break>
+                    <#case "manual">
+                        <#assign manualField=field.asManualField().orElseThrow()>
+                // Manual Field (${manualField.name})
+                ${helper.toSerializationExpression(manualField, manualField.type, manualField.serializeExpression, type.parserArguments.orElse(null))};
+                    <#break>
+                    <#case "reserved">
+                        <#assign reservedField=field.asReservedField().orElseThrow()>
+                // Reserved Field
+                ${helper.getWriteBufferWriteMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(), helper.getReservedValue(reservedField), reservedField)};
+                    <#break>
+                    <#case "simple">
+                        <#assign simpleField=field.asSimpleField().orElseThrow()>
+                // Simple Field (${simpleField.name})
+                        <#if case.name == "Struct">
+                var ${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) _value.GetStruct()["${simpleField.name}"].Get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();
+                        <#else>
+                            <#if simpleField.name == "value">
+                var ${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) _value.Get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();
+                            <#else>
+                                <#-- Just for now -->
+                var ${simpleField.name} = ${helper.getNullValueForTypeReference(simpleField.type)};
+                            </#if>
+                        </#if>
+                        <#if helper.isSimpleTypeReference(simpleField.type)>
+                ${helper.getWriteBufferWriteMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(), "(" + simpleField.name + ")", simpleField)};
+                        <#else>
+                ${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.StaticSerialize(writeBuffer, ${simpleField.name});
+                        </#if>
+                    <#break>
+                </#switch>
+            </#list>
+            return writeBuffer;
+        }<#sep> else </#sep></#list>
+        <#if !defaultCaseOutput>
+        return null;
+        </#if>
+        }
+    }
+</#if>
+
+}
+</#outputformat>
diff --git a/build-utils/language-cs/src/main/resources/templates/cs/enum-template.ftlh b/code-generation/language-cs/src/main/resources/templates/cs/enum-template.cs.ftlh
similarity index 64%
rename from build-utils/language-cs/src/main/resources/templates/cs/enum-template.ftlh
rename to code-generation/language-cs/src/main/resources/templates/cs/enum-template.cs.ftlh
index f65432d..5a5de69 100644
--- a/build-utils/language-cs/src/main/resources/templates/cs/enum-template.ftlh
+++ b/code-generation/language-cs/src/main/resources/templates/cs/enum-template.cs.ftlh
@@ -1,4 +1,5 @@
 <#--
+<#--
   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
@@ -23,38 +24,38 @@
 <#-- @ftlvariable name="protocolName" type="java.lang.String" -->
 <#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
 <#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
+<#-- @ftlvariable name="tracer" type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
 <#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.EnumTypeDefinition" -->
-<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
 ${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/${type.name}.cs
-//
-// 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.
-//
+/*
+ * 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.
+ */
+
+// Code generated by code-generation. DO NOT EDIT.
 
 namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFlavor?replace("-", "")}.model
 {
 
-    public enum ${type.name}<#if !helper.isStringTypeReference(type.type)> : ${helper.getLanguageTypeNameForTypeReference(type.type)}</#if>
+    public enum ${type.name}
     {
-
     <#list type.enumValues as enumValue>
         ${enumValue.name}<#if !helper.isStringTypeReference(type.type)> = ${enumValue.value}</#if>,
     </#list>
-
     }
 
     <#if type.constantNames?has_content>
@@ -62,13 +63,13 @@ namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFl
     {
         <#list type.constantNames as constantName>
 
-        public static ${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName))} ${constantName?cap_first}(this ${type.name} value)
+        public static ${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName))}<#if helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName)) != 'string'>?</#if> ${constantName?cap_first}(this ${type.name} value)
         {
             switch (value)
             {
             <#list helper.getUniqueEnumValues(type.enumValues) as enumValue>
                 case ${type.name}.${enumValue.name}: { /* '${enumValue.value}' */
-                    return ${helper.escapeEnumValue(type.getConstantType(constantName), enumValue.getConstant(constantName))};
+                    return ${helper.escapeValue(type.getConstantType(constantName), enumValue.getConstant(constantName).orElseThrow())};
                 }
             </#list>
                 default: {
diff --git a/code-generation/language-cs/src/main/resources/templates/cs/io-template.cs.ftlh b/code-generation/language-cs/src/main/resources/templates/cs/io-template.cs.ftlh
new file mode 100644
index 0000000..346eb90
--- /dev/null
+++ b/code-generation/language-cs/src/main/resources/templates/cs/io-template.cs.ftlh
@@ -0,0 +1,299 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
+<#-- @ftlvariable name="tracer" type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/io/${type.name}.cs
+/*
+ * 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.
+ */
+
+// Code generated by code-generation. DO NOT EDIT.
+
+<#-- TODO: the code below implies that parserArguments will be null if not present... not pretty  -->
+<#if type.parserArguments.isPresent()><#assign parserArguments=type.allParserArguments.orElseThrow()></#if>
+public class ${type.name}IO implements MessageInput<${type.name}> {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(${type.name}IO.class);
+
+<#-- The parse and serialize methods here are just proxies for forwardning the requests to static counterparts -->
+<#if !type.isDiscriminatedChildTypeDefinition()>
+    @Override
+    public ${type.name} parse(ReadBuffer readBuffer, Object... args) throws ParseException {
+        <#if parserArguments?has_content>
+        if((args == null) || (args.length != ${parserArguments?size})) {
+            throw new PlcRuntimeException("Wrong number of arguments, expected ${parserArguments?size}, but got " + args.length);
+        }
+            <#list parserArguments as parserArgument>
+        ${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} ${parserArgument.name};
+        if(args[${parserArgument?index}] instanceof ${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)}) {
+            ${parserArgument.name} = (${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)}) args[${parserArgument?index}];
+            <#if helper.isSimpleTypeReference(parserArgument.type)>
+        } else if (args[${parserArgument?index}] instanceof String) {
+            ${parserArgument.name} = ${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)}.valueOf((String) args[${parserArgument?index}]);
+            </#if>
+        } else {
+            throw new PlcRuntimeException("Argument ${parserArgument?index} expected to be of type ${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} or a string which is parseable but was " + args[${parserArgument?index}].getClass().getName());
+        }
+            </#list>
+        </#if>
+        return ${type.name}IO.staticParse(readBuffer<#if parserArguments?has_content>, <#list parserArguments as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>);
+    }
+
+<#else>
+    @Override
+    public ${type.name} parse(ReadBuffer readBuffer, Object... args) throws ParseException {
+        return (${type.name}) new ${type.parentType.name}IO().parse(readBuffer, args);
+    }
+
+</#if>
+<#-- Here come the actual parse and serialize methods that actually do the parsing and serlaizing -->
+    <#assign hasParserArguments=parserArguments?has_content/>
+    <#assign parserArgumentList><#if hasParserArguments><#list parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} ${parserArgument.name}<#sep>, </#sep></#list></#if></#assign>
+    public static ${type.name}<#if type.isDiscriminatedChildTypeDefinition()>Builder</#if> staticParse(ReadBuffer readBuffer<#if hasParserArguments>, ${parserArgumentList}</#if>) throws ParseException {
+        readBuffer.pullContext("${type.name}");
+        int startPos = readBuffer.getPos();
+        int curPos;
+<#list type.fields as field>
+<#switch field.typeName>
+    <#case "array">
+        <#assign arrayField = field.asArrayField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        <#if typedField.type.isByteBased()>
+            <#if !field.isCountArrayField() && !field.isLengthArrayField()>
+        throw new ParseException("array fields of type byte only support 'count' and 'length' loop-types.");
+            </#if>
+        byte[] ${namedField.name} = readBuffer.readByteArray("${namedField.name}", (int) ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#else>
+        <#-- If this is a count array, we can directly initialize an array with the given size -->
+            <#if field.isCountArrayField()>
+        List<${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}> ${arrayField.name} = readCountArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#-- In all other cases do we have to work with a list, that is later converted to an array -->
+            <#else>
+            <#-- For a length array, we read data till the read position of the buffer reaches a given position -->
+                <#if field.isLengthArrayField()>
+        List<${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}> ${arrayField.name} = readLengthArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
+            <#-- A terminated array keeps on reading data as long as the termination expression evaluates to false -->
+                <#elseif field.isTerminatedArrayField()>
+        List<${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}> ${arrayField.name} = readTerminatedArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, () -> ((boolean) (${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}))${helper.getFieldOptions(typedField, parserArguments)});
+                </#if>
+            </#if>
+        </#if>
+        <#break>
+    <#case "assert">
+        <#assign assertField = field.asAssertField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getDataReaderCall(typedField.type)}, ${helper.toParseExpression(assertField, assertField.type, assertField.conditionExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "checksum">
+        <#assign checksumField = field.asChecksumField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getDataReaderCall(typedField.type)}, ${helper.toParseExpression(checksumField, checksumField.type, checksumField.checksumExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "const">
+        <#assign constField = field.asConstField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getDataReaderCall(typedField.type)}, ${type.name}.${namedField.name?upper_case}${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "discriminator">
+        <#assign discriminatorField = field.asDiscriminatorField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getDataReaderCall(typedField.type)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "enum">
+        <#assign enumField = field.asEnumField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", "${helper.getTypeDefinitionForTypeReference(enumField.type).name}", readEnum(${helper.getTypeDefinitionForTypeReference(enumField.type).name}::firstEnumForField${enumField.fieldName?cap_first}, ${helper.getDataReaderCall(helper.getEnumFieldTypeReference(enumField.type, enumField.fieldName))})${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "implicit">
+        <#assign implicitField = field.asImplicitField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getDataReaderCall(typedField.type)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "manualArray">
+        <#assign manualArrayField = field.asManualArrayField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        <#if manualArrayField.type.isByteBased()>
+        byte[] ${namedField.name} = readManualByteArrayField("${namedField.name}", readBuffer, () -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualArrayField, manualArrayField.type, manualArrayField.parseExpression, parserArguments)})${helper.getFieldOptions(typedField, parserArguments)});
+        <#else>
+        List<${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)}> ${namedField.name} = readManualArrayField("${namedField.name}", readBuffer, () -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualArrayField, manualArrayField.type, manualArrayField.parseExpression, parserArguments)})${helper [...]
+        </#if>
+        <#break>
+    <#case "manual">
+        <#assign manualField = field.asManualField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${manualField.name} = readManualField("${namedField.name}", readBuffer, () -> (${helper.getLanguageTypeNameForField(manualField)}) (${helper.toParseExpression(manualField, manualField.type, manualField.parseExpression, parserArguments)})${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "optional">
+        <#assign optionalField = field.asOptionalField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getDataReaderCall(typedField.type)}<#if optionalField.conditionExpression.present>, ${helper.toParseExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)}</#if>${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "padding">
+        <#assign paddingField = field.asPaddingField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign simpleTypeReference = paddingField.type.asSimpleTypeReference().orElseThrow()>
+
+        read${field.typeName?cap_first}Field(${helper.getDataReaderCall(typedField.type)}, (int) (${helper.toParseExpression(paddingField, paddingField.type, paddingField.paddingCondition, parserArguments)})${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "reserved">
+        <#assign reservedField = field.asReservedField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+
+        read${field.typeName?cap_first}Field("reserved", ${helper.getDataReaderCall(typedField.type)}, ${helper.getReservedValue(reservedField)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "simple">
+        <#assign simpleField = field.asSimpleField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = <#if helper.isEnumTypeReference(typedField.type)>readEnumField("${namedField.name}", "${helper.getLanguageTypeNameForField(field)}", ${helper.getDataReaderCall(typedField.type)}${helper.getFieldOptions(typedField, parserArguments)});<#else>read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getDataReaderCall(typedField.type)}${helper.getFieldOptions(typedField, parserArguments)});</#if>
+        <#break>
+    <#case "switch">
+        <#assign switchField = field.asSwitchField().orElseThrow()>
+
+        // Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
+        ${type.name}Builder builder = null;
+        <#list switchField.cases as case>
+            <@compress single_line=true>
+            <#if case.discriminatorValueTerms?has_content>
+                if(
+                <#list case.discriminatorValueTerms as discriminatorValueTerm>
+                    <#assign discriminatorExpression=switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
+                    <#assign discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.discriminatorName]>
+                    EvaluationHelper.equals(
+                    ${helper.toParseExpression(switchField, discriminatorType, discriminatorExpression, parserArguments)},
+                    <#if helper.isEnumTypeReference(discriminatorType)>
+                    ${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
+                    <#else>
+                    ${helper.toParseExpression(switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
+                    </#if>
+                    )
+                    <#sep> && </#sep>
+                    </#list>
+                )
+            </#if>{
+            </...@compress>
+            <@compress single_line=true>
+            <#assign hasCaseParseArguments=case.allParserArguments.isPresent() && case.allParserArguments.orElseThrow()?has_content>
+            <#assign caseParseArguments><#if hasCaseParseArguments><#list case.allParserArguments.orElseThrow() as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if></#assign>
+            builder = ${case.name}IO.staticParse(readBuffer<#if hasCaseParseArguments>, ${tracer.dive("case parse arguments")} ${caseParseArguments}</#if>);
+            </...@compress>
+        }<#sep> else </#sep>
+        </#list>
+        if (builder == null) {
+            throw new ParseException("Unsupported case for discriminated type");
+        }
+        <#break>
+    <#case "unknown">
+        <#assign unknownField = field.asUnknownField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+
+        read${field.typeName?cap_first}Field("unknown", ${helper.getDataReaderCall(typedField.type)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+    <#case "virtual">
+        <#assign virtualField = field.asVirtualField().orElseThrow()>
+        <#assign typedField = field.asTypedField().orElseThrow()>
+        <#assign namedField = field.asNamedField().orElseThrow()>
+
+        ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field(${helper.getLanguageTypeNameForField(field)}.class, ${helper.toParseExpression(virtualField, virtualField.type, virtualField.valueExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
+        <#break>
+</#switch>
+</#list>
+
+        readBuffer.closeContext("${type.name}");
+        // Create the instance
+        <#if type.isDiscriminatedChildTypeDefinition()>
+        return new ${type.name}Builder(<#list type.propertyFields as field>${field.name}<#sep>, </#sep></#list>);
+        <#elseif type.isDiscriminatedParentTypeDefinition()>
+        return builder.build(<#list type.propertyFields as field>${field.name}<#sep>, </#sep></#list>);
+        <#else>
+        return new ${type.name}(<#list type.propertyFields as field>${field.name}<#sep>, </#sep></#list>);
+        </#if>
+    }
+
+<#if type.isDiscriminatedParentTypeDefinition()>
+    public static interface ${type.name}Builder {
+        ${type.name} build(<#list type.propertyFields as field><#if field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name}<#sep>, </#sep></#list>);
+    }
+
+</#if>
+<#if type.isDiscriminatedChildTypeDefinition()>
+    public static class ${type.name}Builder implements ${type.parentType.name}IO.${type.parentType.name}Builder {
+        <#if type.propertyFields?has_content>
+            <#list type.propertyFields as field>
+        private final <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name};
+            </#list>
+        </#if>
+
+        public ${type.name}Builder(<#list type.propertyFields as field><#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name}<#sep>, </#sep></#list>) {
+            <#list type.propertyFields as field>
+            this.${field.name} = ${field.name};
+            </#list>
+        }
+
+        public ${type.name} build(<#list type.parentType.asComplexTypeDefinition().orElseThrow().propertyFields as field><#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name}<#sep>, </#sep></#list>) {
+            return new ${type.name}(<#list type.allPropertyFields as field>${field.name}<#sep>, </#sep></#list>);
+        }
+    }
+
+</#if>
+}
+</#outputformat>
diff --git a/code-generation/language-java/src/main/resources/templates/java/pojo-template.java.ftlh b/code-generation/language-cs/src/main/resources/templates/cs/model-template.cs.ftlh
similarity index 59%
copy from code-generation/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
copy to code-generation/language-cs/src/main/resources/templates/cs/model-template.cs.ftlh
index 07dc000..0616a5b 100644
--- a/code-generation/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
+++ b/code-generation/language-cs/src/main/resources/templates/cs/model-template.cs.ftlh
@@ -22,11 +22,11 @@
 <#-- @ftlvariable name="languageName" type="java.lang.String" -->
 <#-- @ftlvariable name="protocolName" type="java.lang.String" -->
 <#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
-<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.java.JavaLanguageTemplateHelper" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.cs.CsLanguageTemplateHelper" -->
 <#-- @ftlvariable name="tracer" type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
 <#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
 <#-- Declare the name and type of variables declared locally inside the template -->
-${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", "/")}/${type.name}.java
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/${type.name}.cs
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -45,31 +45,23 @@ ${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", "/")
  * specific language governing permissions and limitations
  * under the License.
  */
-package ${helper.packageName(protocolName, languageName, outputFlavor)};
-
-import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
-import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
-import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
-
-import org.apache.plc4x.java.api.value.*;
-import org.apache.plc4x.java.spi.codegen.io.DataWriterComplexDefault;
-import org.apache.plc4x.java.spi.codegen.io.DataWriterEnumDefault;
-import org.apache.plc4x.java.spi.generation.Message;
-import org.apache.plc4x.java.spi.generation.MessageIO;
-import org.apache.plc4x.java.spi.generation.SerializationException;
-import org.apache.plc4x.java.spi.generation.WriteBuffer;
-import org.apache.plc4x.java.spi.generation.WriteBufferBoxBased;
-import org.apache.plc4x.java.spi.generation.WithReaderWriterArgs;
-
-import java.time.*;
-import java.util.*;
-import java.math.BigInteger;
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
 
 // Code generated by code-generation. DO NOT EDIT.
 
 <#-- TODO: the code below implies that parserArguments will be null if not present... not pretty  -->
 <#if type.parserArguments.isPresent()><#assign parserArguments=type.parserArguments.orElseThrow()></#if>
-public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${type.name}<#if type.parentType??> extends ${type.parentType.name}</#if> implements Message {
+namespace org.apache.plc4net.drivers.${protocolName?replace("-", "")}.${outputFlavor?replace("-", "")}.model
+{
+
+    public<#if helper.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${type.name}<#if type.parentType??> : ${type.parentType.name}</#if>
+    {
 
 <#--
     If this is a discriminated child type, we need to generate methods for accessing it's discriminator
@@ -77,22 +69,12 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
 -->
 <#if type.isDiscriminatedChildTypeDefinition()>
     <#assign discriminatedChildType = type.asDiscriminatedComplexTypeDefinition().orElseThrow()>
-    // Accessors for discriminator values.
+        // Accessors for discriminator values.
     <#list discriminatedChildType.getDiscriminatorMap() as discriminatorName, discriminatorValue>
         <#-- If the discriminator name matches that of another field, suppress the methods generation -->
         <#if !discriminatedChildType.isNonDiscriminatorField(discriminatorName)><#--&& !discriminatedChildType.isParserArgument(discriminatorName)-->
             <#assign discriminatorType = helper.getDiscriminatorTypes()[discriminatorName]>
-    public ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} get${discriminatorName?cap_first}() {
-            <#if discriminatorValue??>
-                <#if helper.isEnumTypeReference(discriminatorType)>
-        return ${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(null, discriminatorType, discriminatorValue, parserArguments)};
-                <#else>
-        return ${helper.toParseExpression(null, discriminatorType, discriminatorValue, parserArguments)};
-                </#if>
-            <#else>
-        return ${helper.getNullValueForTypeReference(discriminatorType)};
-            </#if>
-    }
+        public override ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} ${discriminatorName?cap_first} => <#if discriminatorValue??><#if helper.isEnumTypeReference(discriminatorType)>${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(null, discriminatorType, discriminatorValue, parserArguments)}<#else>${helper.toParseExpression(null, discriminatorType, discriminatorValue, parserArguments)}</#if><#else>${helper.getNullValueForTypeR [...]
         </#if>
     </#list>
 </#if>
@@ -103,42 +85,43 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
 <#if type.isDiscriminatedParentTypeDefinition()>
     <#assign discriminatedParentType = type>
     <#-- @ftlvariable name="discriminatedParentType" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
-    // Abstract accessors for discriminator values.
+        // Abstract accessors for discriminator values.
     <#list helper.discriminatorTypes as discriminatorName, discriminatorType>
         <#-- If the discriminator name matches that of another field, suppress the methods generation -->
         <#if !type.isNonDiscriminatorField(discriminatorName)><#-- && !type.isParserArgument(discriminatorName)-->
-    public abstract ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} get${discriminatorName?cap_first}();
+        public abstract ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} ${discriminatorName?cap_first} { get; }
         </#if>
     </#list>
 </#if>
 <#-- If the current type contains "const" fields, generate some java constants for holing their values -->
 <#if type.constFields?has_content>
 
-    // Constant values.
+        // Constant values.
 <#list type.constFields as field>
-    public static final ${helper.getLanguageTypeNameForField(field)} ${field.name?upper_case} = ${helper.toParseExpression(field, field.type, field.referenceValue, parserArguments)};
+        public const ${helper.getLanguageTypeNameForField(field)} ${field.name?upper_case} = ${helper.toParseExpression(field, field.type, field.referenceValue, parserArguments)};
 </#list>
 </#if>
 <#-- Property fields are fields that require a property in the pojo -->
 <#if type.propertyFields?has_content>
 
-    // Properties.
+        // Properties.
 <#list type.propertyFields as field>
-    protected final <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name};
+        public ${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> ${field.name?cap_first} { get; }
 </#list>
 </#if>
 
     <#-- getAllPropertyFields() returns not only the property fields of this type but also of it's parents -->
-    public ${type.name}(<#list type.getAllPropertyFields() as field><#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name}<#sep>, </#sep></#list>) {
+        public ${type.name}(<#list type.getAllPropertyFields() as field>${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>[]</#if> ${field.name}<#sep>, </#sep></#list>)
 <#if type.getParentPropertyFields()?has_content>
-        super(<#list type.getParentPropertyFields() as field>${field.name}<#sep>, </#sep></#list>);
+            : base(<#list type.getParentPropertyFields() as field>${field.name}<#sep>, </#sep></#list>)
 </#if>
+        {
 <#list type.propertyFields as field>
-        this.${field.name} = ${field.name};
+            ${field.name?cap_first} = ${field.name};
 </#list>
-    }
+        }
 
-<#list type.abstractFields as field>
+<#--list type.abstractFields as field>
     public abstract <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> get${field.asNamedField().orElseThrow().name?cap_first}();
 
 </#list>
@@ -233,7 +216,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
                         <#assign namedField = field.asNamedField().orElseThrow()>
 
                         // Implicit Field (${implicitField.name}) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-                        <#-- Implicit field values might be used in expressions, in order to avoid problems, we generate a temporary variable with the given name. -->
+                        <#- Implicit field values might be used in expressions, in order to avoid problems, we generate a temporary variable with the given name. ->
                         ${helper.getLanguageTypeNameForField(field)} ${implicitField.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toSerializationExpression(implicitField, implicitField.type, implicitField.serializeExpression, parserArguments)});
                         writeImplicitField("${namedField.name}", ${implicitField.name}, ${helper.getDataWriterCall(typedField.type, namedField.name)});
                         <#break>
@@ -311,219 +294,174 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
         return getLengthInBits() / 8;
     }
 
-    @Override
-    public int getLengthInBits() {
-        int lengthInBits = <#if type.parentType??>super.getLengthInBits()<#else>0</#if>;
-        ${type.name} _value  = this;
-<#list type.fields as field>
-<#switch field.typeName>
-    <#case "array">
-        <#assign arrayField = field.asArrayField().orElseThrow()>
-
-        // Array field
-        if(${arrayField.name} != null) {
-        <#if helper.isSimpleTypeReference(arrayField.type)>
-            <#assign simpleTypeReference = arrayField.type.asSimpleTypeReference().orElseThrow()>
-            lengthInBits += ${simpleTypeReference.sizeInBits} * ${arrayField.name}.<#if arrayField.type.isByteBased()>length<#else>size()</#if>;
-        <#elseif arrayField.isCountArrayField()>
-            int i=0;
-            <#assign complexTypeReference = arrayField.type.asComplexTypeReference().orElseThrow()>
-            for(${complexTypeReference.name} element : ${arrayField.name}) {
-                boolean last = ++i >= ${arrayField.name}.size();
-                lengthInBits += element.getLengthInBits();
-            }
-        <#else>
-            for(Message element : ${arrayField.name}) {
-                lengthInBits += element.getLengthInBits();
+        @Override
+        public int getLengthInBits() {
+            int lengthInBits = <#if type.parentType??>super.getLengthInBits()<#else>0</#if>;
+            ${type.name} _value  = this;
+    <#list type.fields as field>
+    <#switch field.typeName>
+        <#case "array">
+            <#assign arrayField = field.asArrayField().orElseThrow()>
+
+            // Array field
+            if(${arrayField.name} != null) {
+            <#if helper.isSimpleTypeReference(arrayField.type)>
+                <#assign simpleTypeReference = arrayField.type.asSimpleTypeReference().orElseThrow()>
+                lengthInBits += ${simpleTypeReference.sizeInBits} * ${arrayField.name}.<#if arrayField.type.isByteBased()>length<#else>size()</#if>;
+            <#elseif arrayField.isCountArrayField()>
+                int i=0;
+                <#assign complexTypeReference = arrayField.type.asComplexTypeReference().orElseThrow()>
+                for(${complexTypeReference.name} element : ${arrayField.name}) {
+                    boolean last = ++i >= ${arrayField.name}.size();
+                    lengthInBits += element.getLengthInBits();
+                }
+            <#else>
+                for(Message element : ${arrayField.name}) {
+                    lengthInBits += element.getLengthInBits();
+                }
+            </#if>
             }
-        </#if>
-        }
-        <#break>
-    <#case "checksum">
-        <#assign checksumField = field.asChecksumField().orElseThrow()>
-        <#assign typedField = field.asTypedField().orElseThrow()>
-        <#assign simpleTypeReference = typedField.type.asSimpleTypeReference().orElseThrow()>
-
-        // Checksum Field (checksum)
-        lengthInBits += ${simpleTypeReference.sizeInBits};
-        <#break>
-    <#case "const">
-        <#assign constField = field.asConstField().orElseThrow()>
-        <#assign typedField = field.asTypedField().orElseThrow()>
-
-        // Const Field (${constField.name})
-        <#if helper.isSimpleTypeReference(typedField.type)>
-        <#assign simpleTypeReference = typedField.type.asSimpleTypeReference().orElseThrow()>
-        lengthInBits += ${simpleTypeReference.sizeInBits};
-        <#else>
-        lengthInBits += ${helper.getEnumBaseTypeReference(typedField.type).sizeInBits};
-        </#if>
-        <#break>
-    <#case "discriminator">
-        <#assign discriminatorField = field.asDiscriminatorField().orElseThrow()>
-
-        // Discriminator Field (${discriminatorField.name})
-        <#if helper.isSimpleTypeReference(discriminatorField.type)>
-            <#assign simpleTypeReference = discriminatorField.type.asSimpleTypeReference().orElseThrow()>
-            <#if simpleTypeReference.isVstringTypeReference()>
-                <#assign vstringTypeReference = simpleTypeReference.asVstringTypeReference().orElseThrow()>
-        lengthInBits += ${helper.toSerializationExpression(discriminatorField, helper.intTypeReference, vstringTypeReference.getLengthExpression(), parserArguments)};
+            <#break>
+        <#case "checksum">
+            <#assign checksumField = field.asChecksumField().orElseThrow()>
+            <#assign typedField = field.asTypedField().orElseThrow()>
+            <#assign simpleTypeReference = typedField.type.asSimpleTypeReference().orElseThrow()>
+
+            // Checksum Field (checksum)
+            lengthInBits += ${simpleTypeReference.sizeInBits};
+            <#break>
+        <#case "const">
+            <#assign constField = field.asConstField().orElseThrow()>
+            <#assign typedField = field.asTypedField().orElseThrow()>
+
+            // Const Field (${constField.name})
+            <#if helper.isSimpleTypeReference(typedField.type)>
+            <#assign simpleTypeReference = typedField.type.asSimpleTypeReference().orElseThrow()>
+            lengthInBits += ${simpleTypeReference.sizeInBits};
             <#else>
-        lengthInBits += ${simpleTypeReference.sizeInBits};
+            lengthInBits += ${helper.getEnumBaseTypeReference(typedField.type).sizeInBits};
             </#if>
-        <#elseif helper.isEnumField(field)>
-            lengthInBits += ${helper.getEnumBaseTypeReference(discriminatorField.type).sizeInBits};
-        <#else>
-            lengthInBits += ${discriminatorField.name}.getLengthInBits();
-        </#if>
-        <#break>
-    <#case "enum">
-        <#assign enumField = field.asEnumField().orElseThrow()>
-
-        // Enum Field (${enumField.name})
-        lengthInBits += ${helper.getEnumBaseTypeReference(enumField.type).sizeInBits};
-        <#break>
-    <#case "implicit">
-        <#assign implicitField = field.asImplicitField().orElseThrow()>
-        <#assign simpleTypeReference = implicitField.type.asSimpleTypeReference().orElseThrow()>
-
-        // Implicit Field (${implicitField.name})
-        lengthInBits += ${simpleTypeReference.sizeInBits};
-        <#break>
-    <#case "manualArray">
-        <#assign manualArrayField = field.asManualArrayField().orElseThrow()>
-
-        // Manual Array Field (${manualArrayField.name})
-        lengthInBits += ${helper.toParseExpression(manualArrayField, helper.intTypeReference, manualArrayField.lengthExpression, parserArguments)} * 8;
-        <#break>
-    <#case "manual">
-        <#assign manualField = field.asManualField().orElseThrow()>
-
-        // Manual Field (${manualField.name})
-        lengthInBits += ${helper.toParseExpression(manualField, helper.intTypeReference, manualField.lengthExpression, parserArguments)} * 8;
-        <#break>
-    <#case "optional">
-        <#assign optionalField = field.asOptionalField().orElseThrow()>
-
-        // Optional Field (${optionalField.name})
-        if(${optionalField.name} != null) {
-        <#if helper.isSimpleTypeReference(optionalField.type)>
-            <#assign simpleTypeReference = optionalField.type.asSimpleTypeReference().orElseThrow()>
-            <#if simpleTypeReference.isVstringTypeReference()>
-                <#assign vstringTypeReference = simpleTypeReference.asVstringTypeReference().orElseThrow()>
-            lengthInBits += ${helper.toSerializationExpression(optionalField, helper.intTypeReference, vstringTypeReference.getLengthExpression(), parserArguments)};
+            <#break>
+        <#case "discriminator">
+            <#assign discriminatorField = field.asDiscriminatorField().orElseThrow()>
+
+            // Discriminator Field (${discriminatorField.name})
+            <#if helper.isSimpleTypeReference(discriminatorField.type)>
+                <#assign simpleTypeReference = discriminatorField.type.asSimpleTypeReference().orElseThrow()>
+                <#if simpleTypeReference.isVstringTypeReference()>
+                    <#assign vstringTypeReference = simpleTypeReference.asVstringTypeReference().orElseThrow()>
+            lengthInBits += ${helper.toSerializationExpression(discriminatorField, helper.intTypeReference, vstringTypeReference.getLengthExpression(), parserArguments)};
+                <#else>
+            lengthInBits += ${simpleTypeReference.sizeInBits};
+                </#if>
+            <#elseif helper.isEnumField(field)>
+                lengthInBits += ${helper.getEnumBaseTypeReference(discriminatorField.type).sizeInBits};
             <#else>
+                lengthInBits += ${discriminatorField.name}.getLengthInBits();
+            </#if>
+            <#break>
+        <#case "enum">
+            <#assign enumField = field.asEnumField().orElseThrow()>
+
+            // Enum Field (${enumField.name})
+            lengthInBits += ${helper.getEnumBaseTypeReference(enumField.type).sizeInBits};
+            <#break>
+        <#case "implicit">
+            <#assign implicitField = field.asImplicitField().orElseThrow()>
+            <#assign simpleTypeReference = implicitField.type.asSimpleTypeReference().orElseThrow()>
+
+            // Implicit Field (${implicitField.name})
             lengthInBits += ${simpleTypeReference.sizeInBits};
+            <#break>
+        <#case "manualArray">
+            <#assign manualArrayField = field.asManualArrayField().orElseThrow()>
+
+            // Manual Array Field (${manualArrayField.name})
+            lengthInBits += ${helper.toParseExpression(manualArrayField, helper.intTypeReference, manualArrayField.lengthExpression, parserArguments)} * 8;
+            <#break>
+        <#case "manual">
+            <#assign manualField = field.asManualField().orElseThrow()>
+
+            // Manual Field (${manualField.name})
+            lengthInBits += ${helper.toParseExpression(manualField, helper.intTypeReference, manualField.lengthExpression, parserArguments)} * 8;
+            <#break>
+        <#case "optional">
+            <#assign optionalField = field.asOptionalField().orElseThrow()>
+
+            // Optional Field (${optionalField.name})
+            if(${optionalField.name} != null) {
+            <#if helper.isSimpleTypeReference(optionalField.type)>
+                <#assign simpleTypeReference = optionalField.type.asSimpleTypeReference().orElseThrow()>
+                <#if simpleTypeReference.isVstringTypeReference()>
+                    <#assign vstringTypeReference = simpleTypeReference.asVstringTypeReference().orElseThrow()>
+                lengthInBits += ${helper.toSerializationExpression(optionalField, helper.intTypeReference, vstringTypeReference.getLengthExpression(), parserArguments)};
+                <#else>
+                lengthInBits += ${simpleTypeReference.sizeInBits};
+                </#if>
+            <#elseif helper.isEnumField(field)>
+                lengthInBits += ${helper.getEnumBaseTypeReference(optionalField.type).sizeInBits};
+            <#else>
+                lengthInBits += ${optionalField.name}.getLengthInBits();
             </#if>
-        <#elseif helper.isEnumField(field)>
-            lengthInBits += ${helper.getEnumBaseTypeReference(optionalField.type).sizeInBits};
-        <#else>
-            lengthInBits += ${optionalField.name}.getLengthInBits();
-        </#if>
-        }
-        <#break>
-    <#case "padding">
-        <#assign paddingField = field.asPaddingField().orElseThrow()>
-        <#assign simpleTypeReference = paddingField.type.asSimpleTypeReference().orElseThrow()>
-
-        // Padding Field (padding)
-        <#-- We're replacing the "lastItem" with 'false' here as the item itself can't know if it is the last -->
-        int _timesPadding = (int) (${helper.toParseExpression(paddingField, helper.intTypeReference, paddingField.paddingCondition, parserArguments)});
-        while (_timesPadding-- > 0) {
+            }
+            <#break>
+        <#case "padding">
+            <#assign paddingField = field.asPaddingField().orElseThrow()>
+            <#assign simpleTypeReference = paddingField.type.asSimpleTypeReference().orElseThrow()>
+
+            // Padding Field (padding)
+            <#- We're replacing the "lastItem" with 'false' here as the item itself can't know if it is the last ->
+            int _timesPadding = (int) (${helper.toParseExpression(paddingField, helper.intTypeReference, paddingField.paddingCondition, parserArguments)});
+            while (_timesPadding-- > 0) {
+                lengthInBits += ${simpleTypeReference.sizeInBits};
+            }
+            <#break>
+        <#case "reserved">
+            <#assign reservedField = field.asReservedField().orElseThrow()>
+            <#assign simpleTypeReference = reservedField.type.asSimpleTypeReference().orElseThrow()>
+
+            // Reserved Field (reserved)
             lengthInBits += ${simpleTypeReference.sizeInBits};
-        }
-        <#break>
-    <#case "reserved">
-        <#assign reservedField = field.asReservedField().orElseThrow()>
-        <#assign simpleTypeReference = reservedField.type.asSimpleTypeReference().orElseThrow()>
-
-        // Reserved Field (reserved)
-        lengthInBits += ${simpleTypeReference.sizeInBits};
-        <#break>
-    <#case "simple">
-        <#assign simpleField = field.asSimpleField().orElseThrow()>
-
-        // Simple field (${simpleField.name})
-        <#if simpleField.type.isSimpleTypeReference()>
-            <#assign simpleTypeReference = simpleField.type.asSimpleTypeReference().orElseThrow()>
-            <#if simpleTypeReference.isVstringTypeReference()>
-                <#assign vstringTypeReference = simpleTypeReference.asVstringTypeReference().orElseThrow()>
-        lengthInBits += ${helper.toSerializationExpression(simpleField, helper.intTypeReference, vstringTypeReference.getLengthExpression(), parserArguments)};
+            <#break>
+        <#case "simple">
+            <#assign simpleField = field.asSimpleField().orElseThrow()>
+
+            // Simple field (${simpleField.name})
+            <#if simpleField.type.isSimpleTypeReference()>
+                <#assign simpleTypeReference = simpleField.type.asSimpleTypeReference().orElseThrow()>
+                <#if simpleTypeReference.isVstringTypeReference()>
+                    <#assign vstringTypeReference = simpleTypeReference.asVstringTypeReference().orElseThrow()>
+            lengthInBits += ${helper.toSerializationExpression(simpleField, helper.intTypeReference, vstringTypeReference.getLengthExpression(), parserArguments)};
+                <#else>
+            lengthInBits += ${simpleTypeReference.sizeInBits};
+                </#if>
+            <#elseif helper.isEnumField(field)>
+            lengthInBits += ${helper.getEnumBaseTypeReference(simpleField.type).sizeInBits};
             <#else>
-        lengthInBits += ${simpleTypeReference.sizeInBits};
+            lengthInBits += ${simpleField.name}.getLengthInBits();
             </#if>
-        <#elseif helper.isEnumField(field)>
-        lengthInBits += ${helper.getEnumBaseTypeReference(simpleField.type).sizeInBits};
-        <#else>
-        lengthInBits += ${simpleField.name}.getLengthInBits();
-        </#if>
-        <#break>
-    <#case "switch">
-        <#assign switchField = field.asSwitchField().orElseThrow()>
-
-        // Length of sub-type elements will be added by sub-type...
-        <#break>
-    <#case "unknown">
-        <#assign unknownField = field.asUnknownField().orElseThrow()>
-        <#assign simpleTypeReference = unknownField.type.asSimpleTypeReference().orElseThrow()>
-
-        // Unknown field
-        lengthInBits += ${simpleTypeReference.sizeInBits};
-    <#case "virtual">
-        <#assign virtualField = field>
-
-        // A virtual field doesn't have any in- or output.
-        <#break>
-</#switch>
-</#list>
+            <#break>
+        <#case "switch">
+            <#assign switchField = field.asSwitchField().orElseThrow()>
 
-        return lengthInBits;
-    }
+            // Length of sub-type elements will be added by sub-type...
+            <#break>
+        <#case "unknown">
+            <#assign unknownField = field.asUnknownField().orElseThrow()>
+            <#assign simpleTypeReference = unknownField.type.asSimpleTypeReference().orElseThrow()>
 
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof ${type.name})) {
-            return false;
-        }
-        ${type.name} that = (${type.name}) o;
-        return
-            <#if type.propertyFields?has_content>
-            <#list type.propertyFields as field>
-            (get${field.name?cap_first}() == that.get${field.name?cap_first}()) &&
-            </#list>
-            </#if>
-            <#if type.parentType??>
-            super.equals(that) &&
-            </#if>
-            true;
-    }
+            // Unknown field
+            lengthInBits += ${simpleTypeReference.sizeInBits};
+        <#case "virtual">
+            <#assign virtualField = field>
 
-    @Override
-    public int hashCode() {
-        return Objects.hash(
-            <#if type.parentType??>
-            super.hashCode()<#if type.propertyFields?has_content>,</#if>
-            </#if>
-            <#if type.propertyFields?has_content>
-            <#list type.propertyFields as field>
-            get${field.name?cap_first}()<#sep>,</#sep>
-            </#list>
-            </#if>
-        );
-    }
+            // A virtual field doesn't have any in- or output.
+            <#break>
+    </#switch>
+    </#list>
 
-    @Override
-    public String toString() {
-        WriteBufferBoxBased writeBufferBoxBased = new WriteBufferBoxBased(true, true);
-        try {
-            serialize(writeBufferBoxBased);
-        } catch (SerializationException e) {
-            throw new RuntimeException(e);
-        }
-        return "\n" + writeBufferBoxBased.getBox().toString()+ "\n";
+            return lengthInBits;
+        }-->
     }
 }
 </#outputformat>
\ No newline at end of file
diff --git a/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageOutput.java b/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageOutput.java
index 4c0989a..d6114f1 100644
--- a/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageOutput.java
+++ b/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageOutput.java
@@ -63,7 +63,7 @@ public class JavaLanguageOutput extends FreemarkerLanguageOutput {
     @Override
     protected List<Template> getComplexTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
         return Arrays.asList(
-            freemarkerConfiguration.getTemplate("templates/java/pojo-template.java.ftlh"),
+            freemarkerConfiguration.getTemplate("templates/java/model-template.java.ftlh"),
             freemarkerConfiguration.getTemplate("templates/java/io-template.java.ftlh"));
     }
 
diff --git a/code-generation/language-java/src/main/resources/templates/java/pojo-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/model-template.java.ftlh
similarity index 100%
rename from code-generation/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
rename to code-generation/language-java/src/main/resources/templates/java/model-template.java.ftlh
diff --git a/code-generation/pom.xml b/code-generation/pom.xml
index b558de8..4f55a63 100644
--- a/code-generation/pom.xml
+++ b/code-generation/pom.xml
@@ -17,7 +17,8 @@
   specific language governing permissions and limitations
   under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
   <modelVersion>4.0.0</modelVersion>
 
@@ -39,26 +40,30 @@
     <module>protocol-test</module>
 
     <module>language-java</module>
-    <!--module>language-java-old</module-->
   </modules>
 
   <profiles>
-  <!-- Build PLC4X including the C modules -->
-  <profile>
-    <id>with-c</id>
-    <modules>
-      <module>language-c</module>
-    </modules>
-  </profile>
+    <profile>
+      <id>with-c</id>
+      <modules>
+        <module>language-c</module>
+      </modules>
+    </profile>
 
-  <profile>
-    <id>with-go</id>
-    <modules>
-      <module>language-go</module>
-    </modules>
-  </profile>
+    <profile>
+      <id>with-dotnet</id>
+      <modules>
+        <module>language-cs</module>
+      </modules>
+    </profile>
 
-</profiles>
+    <profile>
+      <id>with-go</id>
+      <modules>
+        <module>language-go</module>
+      </modules>
+    </profile>
+  </profiles>
 
   <dependencies>
     <!-- JUnit 5 Support -->
diff --git a/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxManufacturer.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxManufacturer.go
index afc995e..66cb884 100644
--- a/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxManufacturer.go
+++ b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxManufacturer.go
@@ -605,8 +605,9 @@ const (
 	KnxManufacturer_M_GOLDMEDAL                                          KnxManufacturer = 567
 	KnxManufacturer_M_CannX                                              KnxManufacturer = 568
 	KnxManufacturer_M_EGI___EARTH_GOODNESS                               KnxManufacturer = 569
-	KnxManufacturer_M_ABB___RESERVED                                     KnxManufacturer = 570
-	KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED                    KnxManufacturer = 571
+	KnxManufacturer_M_VIEGA_GMBH_AND_CO__KG                              KnxManufacturer = 570
+	KnxManufacturer_M_ABB___RESERVED                                     KnxManufacturer = 571
+	KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED                    KnxManufacturer = 572
 )
 
 var KnxManufacturerValues []KnxManufacturer
@@ -1184,6 +1185,7 @@ func init() {
 		KnxManufacturer_M_GOLDMEDAL,
 		KnxManufacturer_M_CannX,
 		KnxManufacturer_M_EGI___EARTH_GOODNESS,
+		KnxManufacturer_M_VIEGA_GMBH_AND_CO__KG,
 		KnxManufacturer_M_ABB___RESERVED,
 		KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED,
 	}
@@ -3289,10 +3291,14 @@ func (e KnxManufacturer) Number() uint16 {
 		}
 	case 570:
 		{ /* '570' */
-			return 43954
+			return 628
 		}
 	case 571:
 		{ /* '571' */
+			return 43954
+		}
+	case 572:
+		{ /* '572' */
 			return 43959
 		}
 	case 58:
@@ -5595,10 +5601,14 @@ func (e KnxManufacturer) Name() string {
 		}
 	case 570:
 		{ /* '570' */
-			return "ABB - reserved"
+			return "Viega GmbH & Co. KG"
 		}
 	case 571:
 		{ /* '571' */
+			return "ABB - reserved"
+		}
+	case 572:
+		{ /* '572' */
 			return "Busch-Jaeger Elektro - reserved"
 		}
 	case 58:
@@ -6851,8 +6861,10 @@ func KnxManufacturerByValue(value uint16) KnxManufacturer {
 	case 57:
 		return KnxManufacturer_M_ORAS
 	case 570:
-		return KnxManufacturer_M_ABB___RESERVED
+		return KnxManufacturer_M_VIEGA_GMBH_AND_CO__KG
 	case 571:
+		return KnxManufacturer_M_ABB___RESERVED
+	case 572:
 		return KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED
 	case 58:
 		return KnxManufacturer_M_DAETWYLER
@@ -8000,6 +8012,8 @@ func KnxManufacturerByName(value string) KnxManufacturer {
 		return KnxManufacturer_M_EGI___EARTH_GOODNESS
 	case "M_ORAS":
 		return KnxManufacturer_M_ORAS
+	case "M_VIEGA_GMBH_AND_CO__KG":
+		return KnxManufacturer_M_VIEGA_GMBH_AND_CO__KG
 	case "M_ABB___RESERVED":
 		return KnxManufacturer_M_ABB___RESERVED
 	case "M_BUSCH_JAEGER_ELEKTRO___RESERVED":
@@ -9180,6 +9194,8 @@ func (e KnxManufacturer) name() string {
 		return "M_EGI___EARTH_GOODNESS"
 	case KnxManufacturer_M_ORAS:
 		return "M_ORAS"
+	case KnxManufacturer_M_VIEGA_GMBH_AND_CO__KG:
+		return "M_VIEGA_GMBH_AND_CO__KG"
 	case KnxManufacturer_M_ABB___RESERVED:
 		return "M_ABB___RESERVED"
 	case KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED:
diff --git a/sandbox/plc4net/api/api/value/IPlcValue.cs b/sandbox/plc4net/api/api/value/IPlcValue.cs
index a6682b9..b1931bd 100644
--- a/sandbox/plc4net/api/api/value/IPlcValue.cs
+++ b/sandbox/plc4net/api/api/value/IPlcValue.cs
@@ -75,7 +75,7 @@ namespace org.apache.plc4net.api.value
         bool IsList();
         int GetLength();
         IPlcValue GetIndex(int index);
-        IPlcValue[] GetList();
+        List<IPlcValue> GetList();
 
         // Struct Methods
         bool IsStruct();
diff --git a/sandbox/plc4net/drivers/knxnetip-test/resources/protocols/knxnetip/ParserSerializerTestsuite.xml b/sandbox/plc4net/drivers/knxnetip-test/resources/protocols/knxnetip/ParserSerializerTestsuite.xml
index 2eae8b6..666ca62 100644
--- a/sandbox/plc4net/drivers/knxnetip-test/resources/protocols/knxnetip/ParserSerializerTestsuite.xml
+++ b/sandbox/plc4net/drivers/knxnetip-test/resources/protocols/knxnetip/ParserSerializerTestsuite.xml
@@ -17,10 +17,14 @@
   specific language governing permissions and limitations
   under the License.
   -->
-<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd" bigEndian="true">
+<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd"
+                byteOrder="BIG_ENDIAN">
 
   <name>KNXNet/IP</name>
 
+  <protocolName>knxnetip</protocolName>
+  <outputFlavor>read-write</outputFlavor>
+
   <!--testcase>
     <name>Causes Failure 1</name>
     <raw>0610042000180404ce002b0703010404025002bab8b838bb</raw>
@@ -49,7 +53,7 @@
         </tunnelingRequestDataBlock>
         <cemi className="org.apache.plc4x.java.knxnetip.readwrite.CEMIBusmonInd">
           <additionalInformationLength>7</additionalInformationLength>
-          <additionalInformation>
+          <additionalInformation isList="true">
             <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationBusmonitorInfo">
               <frameErrorFlag>false</frameErrorFlag>
               <bitErrorFlag>false</bitErrorFlag>
@@ -89,7 +93,7 @@
         </tunnelingRequestDataBlock>
         <cemi className="org.apache.plc4x.java.knxnetip.readwrite.CEMIBusmonInd">
           <additionalInformationLength>7</additionalInformationLength>
-          <additionalInformation>
+          <additionalInformation isList="true">
             <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationBusmonitorInfo">
               <frameErrorFlag>false</frameErrorFlag>
               <bitErrorFlag>false</bitErrorFlag>
@@ -116,73 +120,129 @@
 
   <testcase>
     <name>Search Request</name>
-    <raw>06100201000e0801c0a82a46ef8e</raw>
+    <raw>06100201000e0801c0a82ac8d6b4</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <SearchRequest className="org.apache.plc4x.java.knxnetip.readwrite.SearchRequest">
-        <hpaiIDiscoveryEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDiscoveryEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqRg==</addr>
-          </ipAddress>
-          <ipPort>61326</ipPort>
-        </hpaiIDiscoveryEndpoint>
-      </SearchRequest>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">513</msgType>
+        <totalLength dataType="uint" bitLength="16">14</totalLength>
+        <SearchRequest>
+          <hpaiIDiscoveryEndpoint>
+            <HPAIDiscoveryEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82ac8</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">54964</ipPort>
+            </HPAIDiscoveryEndpoint>
+          </hpaiIDiscoveryEndpoint>
+        </SearchRequest>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
   <testcase>
     <name>Search Response</name>
-    <raw>06100202004c0801c0a82a0b0e5736010200ffff000000082d409852e000170c000ab327553647697261204b4e582f49502d5363686e6974747374656c6c6500000000000802020103010401</raw>
+    <raw>
+      06100202004c0801c0a82a0b0e5736010200ffff000000082d409852e000170c000ab327553647697261204b4e582f49502d5363686e6974747374656c6c6500000000000802020103010401
+    </raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <SearchResponse className="org.apache.plc4x.java.knxnetip.readwrite.SearchResponse">
-        <hpaiControlEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIControlEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqCw==</addr>
-          </ipAddress>
-          <ipPort>3671</ipPort>
-        </hpaiControlEndpoint>
-        <dibDeviceInfo className="org.apache.plc4x.java.knxnetip.readwrite.DIBDeviceInfo">
-          <descriptionType>1</descriptionType>
-          <knxMedium>MEDIUM_TP1</knxMedium>
-          <deviceStatus className="org.apache.plc4x.java.knxnetip.readwrite.DeviceStatus">
-            <programMode>false</programMode>
-          </deviceStatus>
-          <knxAddress className="org.apache.plc4x.java.knxnetip.readwrite.KnxAddress">
-            <mainGroup>15</mainGroup>
-            <middleGroup>15</middleGroup>
-            <subGroup>255</subGroup>
-          </knxAddress>
-          <projectInstallationIdentifier className="org.apache.plc4x.java.knxnetip.readwrite.ProjectInstallationIdentifier">
-            <projectNumber>0</projectNumber>
-            <installationNumber>0</installationNumber>
-          </projectInstallationIdentifier>
-          <knxNetIpDeviceSerialNumber>AAgtQJhS</knxNetIpDeviceSerialNumber>
-          <knxNetIpDeviceMulticastAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>4AAXDA==</addr>
-          </knxNetIpDeviceMulticastAddress>
-          <knxNetIpDeviceMacAddress className="org.apache.plc4x.java.knxnetip.readwrite.MACAddress">
-            <addr>AAqzJ1U2</addr>
-          </knxNetIpDeviceMacAddress>
-          <deviceFriendlyName>R2lyYSBLTlgvSVAtU2Nobml0dHN0ZWxsZQAAAAAA</deviceFriendlyName>
-        </dibDeviceInfo>
-        <dibSuppSvcFamilies className="org.apache.plc4x.java.knxnetip.readwrite.DIBSuppSvcFamilies">
-          <descriptionType>2</descriptionType>
-          <serviceIds>
-            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpCore">
-              <version>1</version>
-            </serviceIds>
-            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpDeviceManagement">
-              <version>1</version>
-            </serviceIds>
-            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpTunneling">
-              <version>1</version>
-            </serviceIds>
-          </serviceIds>
-        </dibSuppSvcFamilies>
-      </SearchResponse>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">514</msgType>
+        <totalLength dataType="uint" bitLength="16">76</totalLength>
+        <SearchResponse>
+          <hpaiControlEndpoint>
+            <HPAIControlEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82a0b</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">3671</ipPort>
+            </HPAIControlEndpoint>
+          </hpaiControlEndpoint>
+          <dibDeviceInfo>
+            <DIBDeviceInfo>
+              <structureLength dataType="uint" bitLength="8">54</structureLength>
+              <descriptionType dataType="uint" bitLength="8">1</descriptionType>
+              <knxMedium>
+                <KnxMedium dataType="uint" bitLength="8" stringRepresentation="MEDIUM_TP1">2</KnxMedium>
+              </knxMedium>
+              <deviceStatus>
+                <DeviceStatus>
+                  <reserved dataType="uint" bitLength="7">0</reserved>
+                  <programMode dataType="bit" bitLength="1">false</programMode>
+                </DeviceStatus>
+              </deviceStatus>
+              <knxAddress>
+                <KnxAddress>
+                  <mainGroup dataType="uint" bitLength="4">15</mainGroup>
+                  <middleGroup dataType="uint" bitLength="4">15</middleGroup>
+                  <subGroup dataType="uint" bitLength="8">255</subGroup>
+                </KnxAddress>
+              </knxAddress>
+              <projectInstallationIdentifier>
+                <ProjectInstallationIdentifier>
+                  <projectNumber dataType="uint" bitLength="8">0</projectNumber>
+                  <installationNumber dataType="uint" bitLength="8">0</installationNumber>
+                </ProjectInstallationIdentifier>
+              </projectInstallationIdentifier>
+              <knxNetIpDeviceSerialNumber dataType="byte" bitLength="48">0x00082d409852</knxNetIpDeviceSerialNumber>
+              <knxNetIpDeviceMulticastAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xe000170c</addr>
+                </IPAddress>
+              </knxNetIpDeviceMulticastAddress>
+              <knxNetIpDeviceMacAddress>
+                <MACAddress>
+                  <addr dataType="byte" bitLength="48">0x000ab3275536</addr>
+                </MACAddress>
+              </knxNetIpDeviceMacAddress>
+              <deviceFriendlyName dataType="byte" bitLength="240">0x47697261204b4e582f49502d5363686e6974747374656c6c650000000000</deviceFriendlyName>
+            </DIBDeviceInfo>
+          </dibDeviceInfo>
+          <dibSuppSvcFamilies>
+            <DIBSuppSvcFamilies>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <descriptionType dataType="uint" bitLength="8">2</descriptionType>
+              <serviceIds isList="true">
+                <ServiceId>
+                  <serviceType dataType="uint" bitLength="8">2</serviceType>
+                  <KnxNetIpCore>
+                    <version dataType="uint" bitLength="8">1</version>
+                  </KnxNetIpCore>
+                </ServiceId>
+                <ServiceId>
+                  <serviceType dataType="uint" bitLength="8">3</serviceType>
+                  <KnxNetIpDeviceManagement>
+                    <version dataType="uint" bitLength="8">1</version>
+                  </KnxNetIpDeviceManagement>
+                </ServiceId>
+                <ServiceId>
+                  <serviceType dataType="uint" bitLength="8">4</serviceType>
+                  <KnxNetIpTunneling>
+                    <version dataType="uint" bitLength="8">1</version>
+                  </KnxNetIpTunneling>
+                </ServiceId>
+              </serviceIds>
+            </DIBSuppSvcFamilies>
+          </dibSuppSvcFamilies>
+        </SearchResponse>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
@@ -191,146 +251,270 @@
     <raw>06100203000e0801000000000000</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <DescriptionRequest className="org.apache.plc4x.java.knxnetip.readwrite.DescriptionRequest">
-        <hpaiControlEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIControlEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>AAAAAA==</addr>
-          </ipAddress>
-          <ipPort>0</ipPort>
-        </hpaiControlEndpoint>
-      </DescriptionRequest>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">515</msgType>
+        <totalLength dataType="uint" bitLength="16">14</totalLength>
+        <DescriptionRequest>
+          <hpaiControlEndpoint>
+            <HPAIControlEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0x00000000</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">0</ipPort>
+            </HPAIControlEndpoint>
+          </hpaiControlEndpoint>
+        </DescriptionRequest>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
   <testcase>
     <name>Description Response</name>
-    <raw>06100204004436010200ffff000000082d409852e000170c000ab327553647697261204b4e582f49502d5363686e6974747374656c6c6500000000000802020103010401</raw>
+    <raw>
+      06100204004436010200ffff000000082d409852e000170c000ab327553647697261204b4e582f49502d5363686e6974747374656c6c6500000000000802020103010401
+    </raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <DescriptionResponse className="org.apache.plc4x.java.knxnetip.readwrite.DescriptionResponse">
-        <dibDeviceInfo className="org.apache.plc4x.java.knxnetip.readwrite.DIBDeviceInfo">
-          <descriptionType>1</descriptionType>
-          <knxMedium>MEDIUM_TP1</knxMedium>
-          <deviceStatus className="org.apache.plc4x.java.knxnetip.readwrite.DeviceStatus">
-            <programMode>false</programMode>
-          </deviceStatus>
-          <knxAddress className="org.apache.plc4x.java.knxnetip.readwrite.KnxAddress">
-            <mainGroup>15</mainGroup>
-            <middleGroup>15</middleGroup>
-            <subGroup>255</subGroup>
-          </knxAddress>
-          <projectInstallationIdentifier className="org.apache.plc4x.java.knxnetip.readwrite.ProjectInstallationIdentifier">
-            <projectNumber>0</projectNumber>
-            <installationNumber>0</installationNumber>
-          </projectInstallationIdentifier>
-          <knxNetIpDeviceSerialNumber>AAgtQJhS</knxNetIpDeviceSerialNumber>
-          <knxNetIpDeviceMulticastAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>4AAXDA==</addr>
-          </knxNetIpDeviceMulticastAddress>
-          <knxNetIpDeviceMacAddress className="org.apache.plc4x.java.knxnetip.readwrite.MACAddress">
-            <addr>AAqzJ1U2</addr>
-          </knxNetIpDeviceMacAddress>
-          <deviceFriendlyName>R2lyYSBLTlgvSVAtU2Nobml0dHN0ZWxsZQAAAAAA</deviceFriendlyName>
-        </dibDeviceInfo>
-        <dibSuppSvcFamilies className="org.apache.plc4x.java.knxnetip.readwrite.DIBSuppSvcFamilies">
-          <descriptionType>2</descriptionType>
-          <serviceIds>
-            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpCore">
-              <version>1</version>
-            </serviceIds>
-            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpDeviceManagement">
-              <version>1</version>
-            </serviceIds>
-            <serviceIds className="org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpTunneling">
-              <version>1</version>
-            </serviceIds>
-          </serviceIds>
-        </dibSuppSvcFamilies>
-      </DescriptionResponse>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">516</msgType>
+        <totalLength dataType="uint" bitLength="16">68</totalLength>
+        <DescriptionResponse>
+          <dibDeviceInfo>
+            <DIBDeviceInfo>
+              <structureLength dataType="uint" bitLength="8">54</structureLength>
+              <descriptionType dataType="uint" bitLength="8">1</descriptionType>
+              <knxMedium>
+                <KnxMedium dataType="uint" bitLength="8" stringRepresentation="MEDIUM_TP1">2</KnxMedium>
+              </knxMedium>
+              <deviceStatus>
+                <DeviceStatus>
+                  <reserved dataType="uint" bitLength="7">0</reserved>
+                  <programMode dataType="bit" bitLength="1">false</programMode>
+                </DeviceStatus>
+              </deviceStatus>
+              <knxAddress>
+                <KnxAddress>
+                  <mainGroup dataType="uint" bitLength="4">15</mainGroup>
+                  <middleGroup dataType="uint" bitLength="4">15</middleGroup>
+                  <subGroup dataType="uint" bitLength="8">255</subGroup>
+                </KnxAddress>
+              </knxAddress>
+              <projectInstallationIdentifier>
+                <ProjectInstallationIdentifier>
+                  <projectNumber dataType="uint" bitLength="8">0</projectNumber>
+                  <installationNumber dataType="uint" bitLength="8">0</installationNumber>
+                </ProjectInstallationIdentifier>
+              </projectInstallationIdentifier>
+              <knxNetIpDeviceSerialNumber dataType="byte" bitLength="48">0x00082d409852</knxNetIpDeviceSerialNumber>
+              <knxNetIpDeviceMulticastAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xe000170c</addr>
+                </IPAddress>
+              </knxNetIpDeviceMulticastAddress>
+              <knxNetIpDeviceMacAddress>
+                <MACAddress>
+                  <addr dataType="byte" bitLength="48">0x000ab3275536</addr>
+                </MACAddress>
+              </knxNetIpDeviceMacAddress>
+              <deviceFriendlyName dataType="byte" bitLength="240">0x47697261204b4e582f49502d5363686e6974747374656c6c650000000000</deviceFriendlyName>
+            </DIBDeviceInfo>
+          </dibDeviceInfo>
+          <dibSuppSvcFamilies>
+            <DIBSuppSvcFamilies>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <descriptionType dataType="uint" bitLength="8">2</descriptionType>
+              <serviceIds isList="true">
+                <ServiceId>
+                  <serviceType dataType="uint" bitLength="8">2</serviceType>
+                  <KnxNetIpCore>
+                    <version dataType="uint" bitLength="8">1</version>
+                  </KnxNetIpCore>
+                </ServiceId>
+                <ServiceId>
+                  <serviceType dataType="uint" bitLength="8">3</serviceType>
+                  <KnxNetIpDeviceManagement>
+                    <version dataType="uint" bitLength="8">1</version>
+                  </KnxNetIpDeviceManagement>
+                </ServiceId>
+                <ServiceId>
+                  <serviceType dataType="uint" bitLength="8">4</serviceType>
+                  <KnxNetIpTunneling>
+                    <version dataType="uint" bitLength="8">1</version>
+                  </KnxNetIpTunneling>
+                </ServiceId>
+              </serviceIds>
+            </DIBSuppSvcFamilies>
+          </dibSuppSvcFamilies>
+        </DescriptionResponse>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
   <testcase>
     <name>Connect Request</name>
-    <raw>06100205001a0801c0a82a46f4310801c0a82a46f43204040200</raw>
+    <!--raw>06100205001a0801c0a82a46f4310801c0a82a46f43204040200</raw-->
+    <raw>06100205001a0801c0a82ac8d6b40801c0a82ac8d6b404040200</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <ConnectionRequest className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionRequest">
-        <hpaiDiscoveryEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDiscoveryEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqRg==</addr>
-          </ipAddress>
-          <ipPort>62513</ipPort>
-        </hpaiDiscoveryEndpoint>
-        <hpaiDataEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDataEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqRg==</addr>
-          </ipAddress>
-          <ipPort>62514</ipPort>
-        </hpaiDataEndpoint>
-        <connectionRequestInformation className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionRequestInformationTunnelConnection">
-          <knxLayer>TUNNEL_LINK_LAYER</knxLayer>
-        </connectionRequestInformation>
-      </ConnectionRequest>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">517</msgType>
+        <totalLength dataType="uint" bitLength="16">26</totalLength>
+        <ConnectionRequest>
+          <hpaiDiscoveryEndpoint>
+            <HPAIDiscoveryEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82ac8</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">54964</ipPort>
+            </HPAIDiscoveryEndpoint>
+          </hpaiDiscoveryEndpoint>
+          <hpaiDataEndpoint>
+            <HPAIDataEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82ac8</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">54964</ipPort>
+            </HPAIDataEndpoint>
+          </hpaiDataEndpoint>
+          <connectionRequestInformation>
+            <ConnectionRequestInformation>
+              <structureLength dataType="uint" bitLength="8">4</structureLength>
+              <connectionType dataType="uint" bitLength="8">4</connectionType>
+              <ConnectionRequestInformationTunnelConnection>
+                <knxLayer>
+                  <KnxLayer dataType="uint" bitLength="8" stringRepresentation="TUNNEL_LINK_LAYER">2</KnxLayer>
+                </knxLayer>
+                <reserved dataType="uint" bitLength="8">0</reserved>
+              </ConnectionRequestInformationTunnelConnection>
+            </ConnectionRequestInformation>
+          </connectionRequestInformation>
+        </ConnectionRequest>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
   <testcase>
     <name>Connect Response</name>
-    <raw>06100206001466000801c0a82a0b0e5704041101</raw>
+    <raw>06100206001402000801c0a82a0b0e570404fffe</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <ConnectionResponse className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionResponse">
-        <communicationChannelId>102</communicationChannelId>
-        <status>NO_ERROR</status>
-        <hpaiDataEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDataEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqCw==</addr>
-          </ipAddress>
-          <ipPort>3671</ipPort>
-        </hpaiDataEndpoint>
-        <connectionResponseDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionResponseDataBlockTunnelConnection">
-          <knxAddress className="org.apache.plc4x.java.knxnetip.readwrite.KnxAddress">
-            <mainGroup>1</mainGroup>
-            <middleGroup>1</middleGroup>
-            <subGroup>1</subGroup>
-          </knxAddress>
-        </connectionResponseDataBlock>
-      </ConnectionResponse>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">518</msgType>
+        <totalLength dataType="uint" bitLength="16">20</totalLength>
+        <ConnectionResponse>
+          <communicationChannelId dataType="uint" bitLength="8">2</communicationChannelId>
+          <status>
+            <Status dataType="uint" bitLength="8" stringRepresentation="NO_ERROR">0</Status>
+          </status>
+          <hpaiDataEndpoint>
+            <HPAIDataEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82a0b</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">3671</ipPort>
+            </HPAIDataEndpoint>
+          </hpaiDataEndpoint>
+          <connectionResponseDataBlock>
+            <ConnectionResponseDataBlock>
+              <structureLength dataType="uint" bitLength="8">4</structureLength>
+              <connectionType dataType="uint" bitLength="8">4</connectionType>
+              <ConnectionResponseDataBlockTunnelConnection>
+                <knxAddress>
+                  <KnxAddress>
+                    <mainGroup dataType="uint" bitLength="4">15</mainGroup>
+                    <middleGroup dataType="uint" bitLength="4">15</middleGroup>
+                    <subGroup dataType="uint" bitLength="8">254</subGroup>
+                  </KnxAddress>
+                </knxAddress>
+              </ConnectionResponseDataBlockTunnelConnection>
+            </ConnectionResponseDataBlock>
+          </connectionResponseDataBlock>
+        </ConnectionResponse>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
   <testcase>
     <name>Connection State Request</name>
-    <raw>06100207001066000801c0a82a46f431</raw>
+    <raw>06100207001002000801c0a82ac8d6b4</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <ConnectionStateRequest className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionStateRequest">
-        <communicationChannelId>102</communicationChannelId>
-        <hpaiControlEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIControlEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqRg==</addr>
-          </ipAddress>
-          <ipPort>62513</ipPort>
-        </hpaiControlEndpoint>
-      </ConnectionStateRequest>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">519</msgType>
+        <totalLength dataType="uint" bitLength="16">16</totalLength>
+        <ConnectionStateRequest>
+          <communicationChannelId dataType="uint" bitLength="8">2</communicationChannelId>
+          <reserved dataType="uint" bitLength="8">0</reserved>
+          <hpaiControlEndpoint>
+            <HPAIControlEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82ac8</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">54964</ipPort>
+            </HPAIControlEndpoint>
+          </hpaiControlEndpoint>
+        </ConnectionStateRequest>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
   <testcase>
     <name>Connection State Response</name>
-    <raw>0610020800086600</raw>
+    <raw>0610020800080200</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <ConnectionStateResponse className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionStateResponse">
-        <communicationChannelId>102</communicationChannelId>
-        <status>NO_ERROR</status>
-      </ConnectionStateResponse>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">520</msgType>
+        <totalLength dataType="uint" bitLength="16">8</totalLength>
+        <ConnectionStateResponse>
+          <communicationChannelId dataType="uint" bitLength="8">2</communicationChannelId>
+          <status>
+            <Status dataType="uint" bitLength="8" stringRepresentation="NO_ERROR">0</Status>
+          </status>
+        </ConnectionStateResponse>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
@@ -339,19 +523,34 @@
     <raw>06100310001104670000fc000001531001</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <DeviceConfigurationRequest className="org.apache.plc4x.java.knxnetip.readwrite.DeviceConfigurationRequest">
-        <deviceConfigurationRequestDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.DeviceConfigurationRequestDataBlock">
-          <communicationChannelId>103</communicationChannelId>
-          <sequenceCounter>0</sequenceCounter>
-        </deviceConfigurationRequestDataBlock>
-        <cemi className="org.apache.plc4x.java.knxnetip.readwrite.CEMIMPropReadReq">
-          <interfaceObjectType>0</interfaceObjectType>
-          <objectInstance>1</objectInstance>
-          <propertyId>83</propertyId>
-          <numberOfElements>1</numberOfElements>
-          <startIndex>1</startIndex>
-        </cemi>
-      </DeviceConfigurationRequest>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">784</msgType>
+        <totalLength dataType="uint" bitLength="16">17</totalLength>
+        <DeviceConfigurationRequest>
+          <deviceConfigurationRequestDataBlock>
+            <DeviceConfigurationRequestDataBlock>
+              <structureLength dataType="uint" bitLength="8">4</structureLength>
+              <communicationChannelId dataType="uint" bitLength="8">103</communicationChannelId>
+              <sequenceCounter dataType="uint" bitLength="8">0</sequenceCounter>
+              <reserved dataType="uint" bitLength="8">0</reserved>
+            </DeviceConfigurationRequestDataBlock>
+          </deviceConfigurationRequestDataBlock>
+          <cemi>
+            <CEMI>
+              <messageCode dataType="uint" bitLength="8">252</messageCode>
+              <MPropReadReq>
+                <interfaceObjectType dataType="uint" bitLength="16">0</interfaceObjectType>
+                <objectInstance dataType="uint" bitLength="8">1</objectInstance>
+                <propertyId dataType="uint" bitLength="8">83</propertyId>
+                <numberOfElements dataType="uint" bitLength="4">1</numberOfElements>
+                <startIndex dataType="uint" bitLength="12">1</startIndex>
+              </MPropReadReq>
+            </CEMI>
+          </cemi>
+        </DeviceConfigurationRequest>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
@@ -360,31 +559,56 @@
     <raw>06100311000a04670000</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <DeviceConfigurationAck className="org.apache.plc4x.java.knxnetip.readwrite.DeviceConfigurationAck">
-        <deviceConfigurationAckDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.DeviceConfigurationAckDataBlock">
-          <communicationChannelId>103</communicationChannelId>
-          <sequenceCounter>0</sequenceCounter>
-          <status>NO_ERROR</status>
-        </deviceConfigurationAckDataBlock>
-      </DeviceConfigurationAck>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">785</msgType>
+        <totalLength dataType="uint" bitLength="16">10</totalLength>
+        <DeviceConfigurationAck>
+          <deviceConfigurationAckDataBlock>
+            <DeviceConfigurationAckDataBlock>
+              <structureLength dataType="uint" bitLength="8">4</structureLength>
+              <communicationChannelId dataType="uint" bitLength="8">103</communicationChannelId>
+              <sequenceCounter dataType="uint" bitLength="8">0</sequenceCounter>
+              <status>
+                <Status dataType="uint" bitLength="8" stringRepresentation="NO_ERROR">0</Status>
+              </status>
+            </DeviceConfigurationAckDataBlock>
+          </deviceConfigurationAckDataBlock>
+        </DeviceConfigurationAck>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
   <testcase>
     <name>Disconnect Request</name>
-    <raw>06100209001067000801c0a82a46f431</raw>
+    <raw>06100209001001000801c0a82a0b0e57</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <DisconnectRequest className="org.apache.plc4x.java.knxnetip.readwrite.DisconnectRequest">
-        <communicationChannelId>103</communicationChannelId>
-        <hpaiControlEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIControlEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqRg==</addr>
-          </ipAddress>
-          <ipPort>62513</ipPort>
-        </hpaiControlEndpoint>
-      </DisconnectRequest>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">521</msgType>
+        <totalLength dataType="uint" bitLength="16">16</totalLength>
+        <DisconnectRequest>
+          <communicationChannelId dataType="uint" bitLength="8">1</communicationChannelId>
+          <reserved dataType="uint" bitLength="8">0</reserved>
+          <hpaiControlEndpoint>
+            <HPAIControlEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82a0b</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">3671</ipPort>
+            </HPAIControlEndpoint>
+          </hpaiControlEndpoint>
+        </DisconnectRequest>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
@@ -393,15 +617,102 @@
     <raw>0610020a00086600</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <DisconnectResponse className="org.apache.plc4x.java.knxnetip.readwrite.DisconnectResponse">
-        <communicationChannelId>102</communicationChannelId>
-        <status>NO_ERROR</status>
-      </DisconnectResponse>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">522</msgType>
+        <totalLength dataType="uint" bitLength="16">8</totalLength>
+        <DisconnectResponse>
+          <communicationChannelId dataType="uint" bitLength="8">102</communicationChannelId>
+          <status>
+            <Status dataType="uint" bitLength="8" stringRepresentation="NO_ERROR">0</Status>
+          </status>
+        </DisconnectResponse>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
   <testcase>
     <name>Tunneling Request</name>
+    <raw>061004200015040200002900bce0220a120c010081</raw>
+    <root-type>KnxNetIpMessage</root-type>
+    <xml>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">1056</msgType>
+        <totalLength dataType="uint" bitLength="16">21</totalLength>
+        <TunnelingRequest>
+          <tunnelingRequestDataBlock>
+            <TunnelingRequestDataBlock>
+              <structureLength dataType="uint" bitLength="8">4</structureLength>
+              <communicationChannelId dataType="uint" bitLength="8">2</communicationChannelId>
+              <sequenceCounter dataType="uint" bitLength="8">0</sequenceCounter>
+              <reserved dataType="uint" bitLength="8">0</reserved>
+            </TunnelingRequestDataBlock>
+          </tunnelingRequestDataBlock>
+          <cemi>
+            <CEMI>
+              <messageCode dataType="uint" bitLength="8">41</messageCode>
+              <LDataInd>
+                <additionalInformationLength dataType="uint" bitLength="8">0</additionalInformationLength>
+                <additionalInformation isList="true">
+                </additionalInformation>
+                <dataFrame>
+                  <LDataFrame>
+                    <frameType dataType="bit" bitLength="1">true</frameType>
+                    <polling dataType="bit" bitLength="1">false</polling>
+                    <notRepeated dataType="bit" bitLength="1">true</notRepeated>
+                    <notAckFrame dataType="bit" bitLength="1">true</notAckFrame>
+                    <priority>
+                      <CEMIPriority dataType="uint" bitLength="2" stringRepresentation="LOW">3</CEMIPriority>
+                    </priority>
+                    <acknowledgeRequested dataType="bit" bitLength="1">false</acknowledgeRequested>
+                    <errorFlag dataType="bit" bitLength="1">false</errorFlag>
+                    <LDataExtended>
+                      <groupAddress dataType="bit" bitLength="1">true</groupAddress>
+                      <hopCount dataType="uint" bitLength="3">6</hopCount>
+                      <extendedFrameFormat dataType="uint" bitLength="4">0</extendedFrameFormat>
+                      <sourceAddress>
+                        <KnxAddress>
+                          <mainGroup dataType="uint" bitLength="4">2</mainGroup>
+                          <middleGroup dataType="uint" bitLength="4">2</middleGroup>
+                          <subGroup dataType="uint" bitLength="8">10</subGroup>
+                        </KnxAddress>
+                      </sourceAddress>
+                      <destinationAddress dataType="byte" bitLength="16">0x120c</destinationAddress>
+                      <dataLength dataType="uint" bitLength="8">1</dataLength>
+                      <apdu>
+                        <Apdu>
+                          <control dataType="uint" bitLength="1">0</control>
+                          <numbered dataType="bit" bitLength="1">false</numbered>
+                          <counter dataType="uint" bitLength="4">0</counter>
+                          <ApduDataContainer>
+                            <dataApdu>
+                              <ApduData>
+                                <apciType dataType="uint" bitLength="4">2</apciType>
+                                <ApduDataGroupValueWrite>
+                                  <dataFirstByte dataType="int" bitLength="6">1</dataFirstByte>
+                                  <data dataType="byte" bitLength="0">0x</data>
+                                </ApduDataGroupValueWrite>
+                              </ApduData>
+                            </dataApdu>
+                          </ApduDataContainer>
+                        </Apdu>
+                      </apdu>
+                    </LDataExtended>
+                  </LDataFrame>
+                </dataFrame>
+              </LDataInd>
+            </CEMI>
+          </cemi>
+        </TunnelingRequest>
+      </KnxNetIpMessage>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Tunneling Request (Busmon)</name>
     <raw>06100420001c046b00002b0703010504024502bc360a1e0ce100810d</raw>
     <!--
     Raw CEMI Frame: bc360a1e0ce100810d
@@ -409,51 +720,99 @@
     -->
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <TunnelingRequest className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingRequest">
-        <tunnelingRequestDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingRequestDataBlock">
-          <communicationChannelId>107</communicationChannelId>
-          <sequenceCounter>0</sequenceCounter>
-        </tunnelingRequestDataBlock>
-        <cemi className="org.apache.plc4x.java.knxnetip.readwrite.CEMIBusmonInd">
-          <additionalInformationLength>7</additionalInformationLength>
-          <additionalInformation>
-            <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationBusmonitorInfo">
-              <frameErrorFlag>false</frameErrorFlag>
-              <bitErrorFlag>false</bitErrorFlag>
-              <parityErrorFlag>false</parityErrorFlag>
-              <unknownFlag>false</unknownFlag>
-              <lostFlag>false</lostFlag>
-              <sequenceNumber>5</sequenceNumber>
-            </additionalInformation>
-            <additionalInformation className="org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationRelativeTimestamp">
-              <relativeTimestamp className="org.apache.plc4x.java.knxnetip.readwrite.RelativeTimestamp">
-                <timestamp>17666</timestamp>
-              </relativeTimestamp>
-            </additionalInformation>
-          </additionalInformation>
-          <cemiFrame className="org.apache.plc4x.java.knxnetip.readwrite.CEMIFrameData">
-            <repeated>true</repeated>
-            <priority>LOW</priority>
-            <acknowledgeRequested>false</acknowledgeRequested>
-            <errorFlag>false</errorFlag>
-            <sourceAddress className="org.apache.plc4x.java.knxnetip.readwrite.KnxAddress">
-              <mainGroup>3</mainGroup>
-              <middleGroup>6</middleGroup>
-              <subGroup>10</subGroup>
-            </sourceAddress>
-            <destinationAddress>Hgw=</destinationAddress>
-            <groupAddress>true</groupAddress>
-            <hopCount>6</hopCount>
-            <dataLength>1</dataLength>
-            <tcpi>UNNUMBERED_DATA_PACKET</tcpi>
-            <counter>0</counter>
-            <apci>GROUP_VALUE_WRITE_PDU</apci>
-            <dataFirstByte>1</dataFirstByte>
-            <data></data>
-            <crc>13</crc>
-          </cemiFrame>
-        </cemi>
-      </TunnelingRequest>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">1056</msgType>
+        <totalLength dataType="uint" bitLength="16">28</totalLength>
+        <TunnelingRequest>
+          <tunnelingRequestDataBlock>
+            <TunnelingRequestDataBlock>
+              <structureLength dataType="uint" bitLength="8">4</structureLength>
+              <communicationChannelId dataType="uint" bitLength="8">107</communicationChannelId>
+              <sequenceCounter dataType="uint" bitLength="8">0</sequenceCounter>
+              <reserved dataType="uint" bitLength="8">0</reserved>
+            </TunnelingRequestDataBlock>
+          </tunnelingRequestDataBlock>
+          <cemi>
+            <CEMI>
+              <messageCode dataType="uint" bitLength="8">43</messageCode>
+              <LBusmonInd>
+                <additionalInformationLength dataType="uint" bitLength="8">7</additionalInformationLength>
+                <additionalInformation isList="true">
+                  <CEMIAdditionalInformation>
+                    <additionalInformationType dataType="uint" bitLength="8">3</additionalInformationType>
+                    <CEMIAdditionalInformationBusmonitorInfo>
+                      <len dataType="uint" bitLength="8">1</len>
+                      <frameErrorFlag dataType="bit" bitLength="1">false</frameErrorFlag>
+                      <bitErrorFlag dataType="bit" bitLength="1">false</bitErrorFlag>
+                      <parityErrorFlag dataType="bit" bitLength="1">false</parityErrorFlag>
+                      <unknownFlag dataType="bit" bitLength="1">false</unknownFlag>
+                      <lostFlag dataType="bit" bitLength="1">false</lostFlag>
+                      <sequenceNumber dataType="uint" bitLength="3">5</sequenceNumber>
+                    </CEMIAdditionalInformationBusmonitorInfo>
+                  </CEMIAdditionalInformation>
+                  <CEMIAdditionalInformation>
+                    <additionalInformationType dataType="uint" bitLength="8">4</additionalInformationType>
+                    <CEMIAdditionalInformationRelativeTimestamp>
+                      <len dataType="uint" bitLength="8">2</len>
+                      <relativeTimestamp>
+                        <RelativeTimestamp>
+                          <timestamp dataType="uint" bitLength="16">17666</timestamp>
+                        </RelativeTimestamp>
+                      </relativeTimestamp>
+                    </CEMIAdditionalInformationRelativeTimestamp>
+                  </CEMIAdditionalInformation>
+                </additionalInformation>
+                <dataFrame>
+                  <LDataFrame>
+                    <frameType dataType="bit" bitLength="1">true</frameType>
+                    <polling dataType="bit" bitLength="1">false</polling>
+                    <notRepeated dataType="bit" bitLength="1">true</notRepeated>
+                    <notAckFrame dataType="bit" bitLength="1">true</notAckFrame>
+                    <priority>
+                      <CEMIPriority dataType="uint" bitLength="2" stringRepresentation="LOW">3</CEMIPriority>
+                    </priority>
+                    <acknowledgeRequested dataType="bit" bitLength="1">false</acknowledgeRequested>
+                    <errorFlag dataType="bit" bitLength="1">false</errorFlag>
+                    <LDataExtended>
+                      <groupAddress dataType="bit" bitLength="1">false</groupAddress>
+                      <hopCount dataType="uint" bitLength="3">3</hopCount>
+                      <extendedFrameFormat dataType="uint" bitLength="4">6</extendedFrameFormat>
+                      <sourceAddress>
+                        <KnxAddress>
+                          <mainGroup dataType="uint" bitLength="4">0</mainGroup>
+                          <middleGroup dataType="uint" bitLength="4">10</middleGroup>
+                          <subGroup dataType="uint" bitLength="8">30</subGroup>
+                        </KnxAddress>
+                      </sourceAddress>
+                      <destinationAddress dataType="byte" bitLength="16">0x0ce1</destinationAddress>
+                      <dataLength dataType="uint" bitLength="8">0</dataLength>
+                      <apdu>
+                        <Apdu>
+                          <control dataType="uint" bitLength="1">1</control>
+                          <numbered dataType="bit" bitLength="1">false</numbered>
+                          <counter dataType="uint" bitLength="4">0</counter>
+                          <ApduControlContainer>
+                            <controlApdu>
+                              <ApduControl>
+                                <controlType dataType="uint" bitLength="2">1</controlType>
+                                <ApduControlDisconnect>
+                                </ApduControlDisconnect>
+                              </ApduControl>
+                            </controlApdu>
+                          </ApduControlContainer>
+                        </Apdu>
+                      </apdu>
+                    </LDataExtended>
+                  </LDataFrame>
+                </dataFrame>
+                <crc dataType="uint" bitLength="8">13</crc>
+              </LBusmonInd>
+            </CEMI>
+          </cemi>
+        </TunnelingRequest>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
@@ -462,13 +821,24 @@
     <raw>06100421000a046b0000</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <TunnelingResponse className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingResponse">
-        <tunnelingResponseDataBlock className="org.apache.plc4x.java.knxnetip.readwrite.TunnelingResponseDataBlock">
-          <communicationChannelId>107</communicationChannelId>
-          <sequenceCounter>0</sequenceCounter>
-          <status>NO_ERROR</status>
-        </tunnelingResponseDataBlock>
-      </TunnelingResponse>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">1057</msgType>
+        <totalLength dataType="uint" bitLength="16">10</totalLength>
+        <TunnelingResponse>
+          <tunnelingResponseDataBlock>
+            <TunnelingResponseDataBlock>
+              <structureLength dataType="uint" bitLength="8">4</structureLength>
+              <communicationChannelId dataType="uint" bitLength="8">107</communicationChannelId>
+              <sequenceCounter dataType="uint" bitLength="8">0</sequenceCounter>
+              <status>
+                <Status dataType="uint" bitLength="8" stringRepresentation="NO_ERROR">0</Status>
+              </status>
+            </TunnelingResponseDataBlock>
+          </tunnelingResponseDataBlock>
+        </TunnelingResponse>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
@@ -477,24 +847,51 @@
     <raw>0610020500180801c0a82a46c4090801c0a82a46c40a0203</raw>
     <root-type>KnxNetIpMessage</root-type>
     <xml>
-      <ConnectionRequest className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionRequest">
-        <hpaiDiscoveryEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDiscoveryEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqRg==</addr>
-          </ipAddress>
-          <ipPort>50185</ipPort>
-        </hpaiDiscoveryEndpoint>
-        <hpaiDataEndpoint className="org.apache.plc4x.java.knxnetip.readwrite.HPAIDataEndpoint">
-          <hostProtocolCode>IPV4_UDP</hostProtocolCode>
-          <ipAddress className="org.apache.plc4x.java.knxnetip.readwrite.IPAddress">
-            <addr>wKgqRg==</addr>
-          </ipAddress>
-          <ipPort>50186</ipPort>
-        </hpaiDataEndpoint>
-        <connectionRequestInformation className="org.apache.plc4x.java.knxnetip.readwrite.ConnectionRequestInformationDeviceManagement"/>
-      </ConnectionRequest>
+      <KnxNetIpMessage>
+        <headerLength dataType="uint" bitLength="8">6</headerLength>
+        <protocolVersion dataType="uint" bitLength="8">16</protocolVersion>
+        <msgType dataType="uint" bitLength="16">517</msgType>
+        <totalLength dataType="uint" bitLength="16">24</totalLength>
+        <ConnectionRequest>
+          <hpaiDiscoveryEndpoint>
+            <HPAIDiscoveryEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82a46</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">50185</ipPort>
+            </HPAIDiscoveryEndpoint>
+          </hpaiDiscoveryEndpoint>
+          <hpaiDataEndpoint>
+            <HPAIDataEndpoint>
+              <structureLength dataType="uint" bitLength="8">8</structureLength>
+              <hostProtocolCode>
+                <HostProtocolCode dataType="uint" bitLength="8" stringRepresentation="IPV4_UDP">1</HostProtocolCode>
+              </hostProtocolCode>
+              <ipAddress>
+                <IPAddress>
+                  <addr dataType="byte" bitLength="32">0xc0a82a46</addr>
+                </IPAddress>
+              </ipAddress>
+              <ipPort dataType="uint" bitLength="16">50186</ipPort>
+            </HPAIDataEndpoint>
+          </hpaiDataEndpoint>
+          <connectionRequestInformation>
+            <ConnectionRequestInformation>
+              <structureLength dataType="uint" bitLength="8">2</structureLength>
+              <connectionType dataType="uint" bitLength="8">3</connectionType>
+              <ConnectionRequestInformationDeviceManagement>
+              </ConnectionRequestInformationDeviceManagement>
+            </ConnectionRequestInformation>
+          </connectionRequestInformation>
+        </ConnectionRequest>
+      </KnxNetIpMessage>
     </xml>
   </testcase>
 
-</test:testsuite>
\ No newline at end of file
+</test:testsuite>
diff --git a/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs b/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs
index 57e290d..6e0e5b6 100644
--- a/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs
+++ b/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs
@@ -35,7 +35,7 @@ namespace org.apache.plc4net.test.knxnetip.readwrite.model
             var input = StrToByteArray("0041b00000");
             IPlcValue expected = new PlcREAL(22.0f);
             
-            var actual = new KnxDatapoint().Parse(new ReadBuffer(input), formatName);
+            var actual = KnxDatapoint.StaticParse(new ReadBuffer(input), KnxDatapointType.DPT_SSSBMode);
             
             Assert.Equal(expected, actual);
         }
diff --git a/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj b/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
index 27ae013..0be2cd7 100644
--- a/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
+++ b/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
@@ -36,4 +36,8 @@
     <ProjectReference Include="..\..\spi\plc4net-spi.csproj" />
   </ItemGroup>
 
+  <ItemGroup>
+    <PackageReference Include="NLog" Version="4.7.13" />
+  </ItemGroup>
+
 </Project>
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/AccessLevel.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/AccessLevel.cs
new file mode 100644
index 0000000..18a786c
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/AccessLevel.cs
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum AccessLevel
+    {
+        Level0 = 0x0,
+        Level1 = 0x1,
+        Level2 = 0x2,
+        Level3 = 0x3,
+        Level15 = 0xF,
+    }
+
+    public static class AccessLevelInfo
+    {
+
+        public static string Purpose(this AccessLevel value)
+        {
+            switch (value)
+            {
+                case AccessLevel.Level0: { /* '0x0' */
+                    return "system manufacturer";
+                }
+                case AccessLevel.Level1: { /* '0x1' */
+                    return "product manufacturer";
+                }
+                case AccessLevel.Level2: { /* '0x2' */
+                    return "configuration";
+                }
+                case AccessLevel.Level3: { /* '0x3' */
+                    return "end-user";
+                }
+                case AccessLevel.Level15: { /* '0xF' */
+                    return "read access";
+                }
+                default: {
+                    return null;
+                }
+            }
+        }
+
+        public static bool? NeedsAuthentication(this AccessLevel value)
+        {
+            switch (value)
+            {
+                case AccessLevel.Level0: { /* '0x0' */
+                    return true;
+                }
+                case AccessLevel.Level1: { /* '0x1' */
+                    return true;
+                }
+                case AccessLevel.Level2: { /* '0x2' */
+                    return true;
+                }
+                case AccessLevel.Level3: { /* '0x3' */
+                    return false;
+                }
+                case AccessLevel.Level15: { /* '0xF' */
+                    return false;
+                }
+                default: {
+                    return false;
+                }
+            }
+        }
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/Apdu.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/Apdu.cs
new file mode 100644
index 0000000..595c0f6
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/Apdu.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class Apdu
+    {
+
+        // Abstract accessors for discriminator values.
+        public abstract byte Control { get; }
+
+        // Properties.
+        public bool Numbered { get; }
+        public byte Counter { get; }
+
+        public Apdu(bool numbered, byte counter)
+        {
+            Numbered = numbered;
+            Counter = counter;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControl.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControl.cs
new file mode 100644
index 0000000..9c10240
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControl.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class ApduControl
+    {
+
+        // Abstract accessors for discriminator values.
+        public abstract byte ControlType { get; }
+
+        public ApduControl()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlAck.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlAck.cs
new file mode 100644
index 0000000..5561a37
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlAck.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduControlAck : ApduControl
+    {
+
+        // Accessors for discriminator values.
+        public override byte ControlType => 0x2;
+
+        public ApduControlAck()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlConnect.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlConnect.cs
new file mode 100644
index 0000000..858a23a
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlConnect.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduControlConnect : ApduControl
+    {
+
+        // Accessors for discriminator values.
+        public override byte ControlType => 0x0;
+
+        public ApduControlConnect()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlContainer.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlContainer.cs
new file mode 100644
index 0000000..a64c0fd
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlContainer.cs
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduControlContainer : Apdu
+    {
+
+        // Accessors for discriminator values.
+        public override byte Control => 1;
+
+        // Properties.
+        public ApduControl ControlApdu { get; }
+
+        public ApduControlContainer(bool numbered, byte counter, ApduControl controlApdu)
+            : base(numbered, counter)
+        {
+            ControlApdu = controlApdu;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlDisconnect.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlDisconnect.cs
new file mode 100644
index 0000000..3a1843e
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlDisconnect.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduControlDisconnect : ApduControl
+    {
+
+        // Accessors for discriminator values.
+        public override byte ControlType => 0x1;
+
+        public ApduControlDisconnect()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlNack.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlNack.cs
new file mode 100644
index 0000000..459c22d
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduControlNack.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduControlNack : ApduControl
+    {
+
+        // Accessors for discriminator values.
+        public override byte ControlType => 0x3;
+
+        public ApduControlNack()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduData.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduData.cs
new file mode 100644
index 0000000..b5b2aa1
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduData.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class ApduData
+    {
+
+        // Abstract accessors for discriminator values.
+        public abstract byte ApciType { get; }
+
+        public ApduData()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataAdcRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataAdcRead.cs
new file mode 100644
index 0000000..4e7cc24
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataAdcRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataAdcRead : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x6;
+
+        public ApduDataAdcRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataAdcResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataAdcResponse.cs
new file mode 100644
index 0000000..37b4348
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataAdcResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataAdcResponse : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x7;
+
+        public ApduDataAdcResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataContainer.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataContainer.cs
new file mode 100644
index 0000000..7969f31
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataContainer.cs
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataContainer : Apdu
+    {
+
+        // Accessors for discriminator values.
+        public override byte Control => 0;
+
+        // Properties.
+        public ApduData DataApdu { get; }
+
+        public ApduDataContainer(bool numbered, byte counter, ApduData dataApdu)
+            : base(numbered, counter)
+        {
+            DataApdu = dataApdu;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataDeviceDescriptorRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataDeviceDescriptorRead.cs
new file mode 100644
index 0000000..41921b5
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataDeviceDescriptorRead.cs
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataDeviceDescriptorRead : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0xC;
+
+        // Properties.
+        public byte DescriptorType { get; }
+
+        public ApduDataDeviceDescriptorRead(byte descriptorType)
+        {
+            DescriptorType = descriptorType;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataDeviceDescriptorResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataDeviceDescriptorResponse.cs
new file mode 100644
index 0000000..1259778
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataDeviceDescriptorResponse.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataDeviceDescriptorResponse : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0xD;
+
+        // Properties.
+        public byte DescriptorType { get; }
+        public byte[] Data { get; }
+
+        public ApduDataDeviceDescriptorResponse(byte descriptorType, byte[] data)
+        {
+            DescriptorType = descriptorType;
+            Data = data;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExt.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExt.cs
new file mode 100644
index 0000000..90f7e4f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExt.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class ApduDataExt
+    {
+
+        // Abstract accessors for discriminator values.
+        public abstract byte ExtApciType { get; }
+
+        public ApduDataExt()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtAuthorizeRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtAuthorizeRequest.cs
new file mode 100644
index 0000000..c31800b
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtAuthorizeRequest.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtAuthorizeRequest : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x11;
+
+        // Properties.
+        public byte Level { get; }
+        public byte[] Data { get; }
+
+        public ApduDataExtAuthorizeRequest(byte level, byte[] data)
+        {
+            Level = level;
+            Data = data;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtAuthorizeResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtAuthorizeResponse.cs
new file mode 100644
index 0000000..adab868
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtAuthorizeResponse.cs
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtAuthorizeResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x12;
+
+        // Properties.
+        public byte Level { get; }
+
+        public ApduDataExtAuthorizeResponse(byte level)
+        {
+            Level = level;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressRead.cs
new file mode 100644
index 0000000..c640fce
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtDomainAddressRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x21;
+
+        public ApduDataExtDomainAddressRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressResponse.cs
new file mode 100644
index 0000000..87acf52
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtDomainAddressResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x22;
+
+        public ApduDataExtDomainAddressResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSelectiveRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSelectiveRead.cs
new file mode 100644
index 0000000..2c6034c
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSelectiveRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtDomainAddressSelectiveRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x23;
+
+        public ApduDataExtDomainAddressSelectiveRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberRead.cs
new file mode 100644
index 0000000..8099b85
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtDomainAddressSerialNumberRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x2C;
+
+        public ApduDataExtDomainAddressSerialNumberRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberResponse.cs
new file mode 100644
index 0000000..b0bf11f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtDomainAddressSerialNumberResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x2D;
+
+        public ApduDataExtDomainAddressSerialNumberResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberWrite.cs
new file mode 100644
index 0000000..7cdd03b
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressSerialNumberWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtDomainAddressSerialNumberWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x2E;
+
+        public ApduDataExtDomainAddressSerialNumberWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressWrite.cs
new file mode 100644
index 0000000..af01011
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtDomainAddressWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtDomainAddressWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x20;
+
+        public ApduDataExtDomainAddressWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtFileStreamInfoReport.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtFileStreamInfoReport.cs
new file mode 100644
index 0000000..4e363fb
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtFileStreamInfoReport.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtFileStreamInfoReport : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x30;
+
+        public ApduDataExtFileStreamInfoReport()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueInfoReport.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueInfoReport.cs
new file mode 100644
index 0000000..943546e
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueInfoReport.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtGroupPropertyValueInfoReport : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x2B;
+
+        public ApduDataExtGroupPropertyValueInfoReport()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueRead.cs
new file mode 100644
index 0000000..4ea6cc8
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtGroupPropertyValueRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x28;
+
+        public ApduDataExtGroupPropertyValueRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueResponse.cs
new file mode 100644
index 0000000..96e6591
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtGroupPropertyValueResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x29;
+
+        public ApduDataExtGroupPropertyValueResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueWrite.cs
new file mode 100644
index 0000000..2d9df55
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtGroupPropertyValueWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtGroupPropertyValueWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x2A;
+
+        public ApduDataExtGroupPropertyValueWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberRead.cs
new file mode 100644
index 0000000..8ada652
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtIndividualAddressSerialNumberRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x1C;
+
+        public ApduDataExtIndividualAddressSerialNumberRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberResponse.cs
new file mode 100644
index 0000000..8b21dea
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtIndividualAddressSerialNumberResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x1D;
+
+        public ApduDataExtIndividualAddressSerialNumberResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberWrite.cs
new file mode 100644
index 0000000..d8e08c7
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtIndividualAddressSerialNumberWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtIndividualAddressSerialNumberWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x1E;
+
+        public ApduDataExtIndividualAddressSerialNumberWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtKeyResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtKeyResponse.cs
new file mode 100644
index 0000000..05a02a3
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtKeyResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtKeyResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x14;
+
+        public ApduDataExtKeyResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtKeyWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtKeyWrite.cs
new file mode 100644
index 0000000..d950733
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtKeyWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtKeyWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x13;
+
+        public ApduDataExtKeyWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkRead.cs
new file mode 100644
index 0000000..187ea02
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtLinkRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x25;
+
+        public ApduDataExtLinkRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkResponse.cs
new file mode 100644
index 0000000..af907e8
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtLinkResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x26;
+
+        public ApduDataExtLinkResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkWrite.cs
new file mode 100644
index 0000000..e5a1000
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtLinkWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtLinkWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x27;
+
+        public ApduDataExtLinkWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtMemoryBitWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtMemoryBitWrite.cs
new file mode 100644
index 0000000..48e9a99
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtMemoryBitWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtMemoryBitWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x10;
+
+        public ApduDataExtMemoryBitWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterRead.cs
new file mode 100644
index 0000000..c53cd41
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtNetworkParameterRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x1A;
+
+        public ApduDataExtNetworkParameterRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterResponse.cs
new file mode 100644
index 0000000..9009e2f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtNetworkParameterResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x1B;
+
+        public ApduDataExtNetworkParameterResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterWrite.cs
new file mode 100644
index 0000000..3aa348b
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtNetworkParameterWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtNetworkParameterWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x24;
+
+        public ApduDataExtNetworkParameterWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtOpenRoutingTableRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtOpenRoutingTableRequest.cs
new file mode 100644
index 0000000..c29da56
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtOpenRoutingTableRequest.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtOpenRoutingTableRequest : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x00;
+
+        public ApduDataExtOpenRoutingTableRequest()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyDescriptionRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyDescriptionRead.cs
new file mode 100644
index 0000000..ec19fc8
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyDescriptionRead.cs
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtPropertyDescriptionRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x18;
+
+        // Properties.
+        public byte ObjectIndex { get; }
+        public byte PropertyId { get; }
+        public byte Index { get; }
+
+        public ApduDataExtPropertyDescriptionRead(byte objectIndex, byte propertyId, byte index)
+        {
+            ObjectIndex = objectIndex;
+            PropertyId = propertyId;
+            Index = index;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyDescriptionResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyDescriptionResponse.cs
new file mode 100644
index 0000000..2708884
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyDescriptionResponse.cs
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtPropertyDescriptionResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x19;
+
+        // Properties.
+        public byte ObjectIndex { get; }
+        public byte PropertyId { get; }
+        public byte Index { get; }
+        public bool WriteEnabled { get; }
+        public KnxPropertyDataType PropertyDataType { get; }
+        public ushort MaxNrOfElements { get; }
+        public AccessLevel ReadLevel { get; }
+        public AccessLevel WriteLevel { get; }
+
+        public ApduDataExtPropertyDescriptionResponse(byte objectIndex, byte propertyId, byte index, bool writeEnabled, KnxPropertyDataType propertyDataType, ushort maxNrOfElements, AccessLevel readLevel, AccessLevel writeLevel)
+        {
+            ObjectIndex = objectIndex;
+            PropertyId = propertyId;
+            Index = index;
+            WriteEnabled = writeEnabled;
+            PropertyDataType = propertyDataType;
+            MaxNrOfElements = maxNrOfElements;
+            ReadLevel = readLevel;
+            WriteLevel = writeLevel;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueRead.cs
new file mode 100644
index 0000000..853c9ed
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueRead.cs
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtPropertyValueRead : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x15;
+
+        // Properties.
+        public byte ObjectIndex { get; }
+        public byte PropertyId { get; }
+        public byte Count { get; }
+        public ushort Index { get; }
+
+        public ApduDataExtPropertyValueRead(byte objectIndex, byte propertyId, byte count, ushort index)
+        {
+            ObjectIndex = objectIndex;
+            PropertyId = propertyId;
+            Count = count;
+            Index = index;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueResponse.cs
new file mode 100644
index 0000000..17ef7ad
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueResponse.cs
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtPropertyValueResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x16;
+
+        // Properties.
+        public byte ObjectIndex { get; }
+        public byte PropertyId { get; }
+        public byte Count { get; }
+        public ushort Index { get; }
+        public byte[] Data { get; }
+
+        public ApduDataExtPropertyValueResponse(byte objectIndex, byte propertyId, byte count, ushort index, byte[] data)
+        {
+            ObjectIndex = objectIndex;
+            PropertyId = propertyId;
+            Count = count;
+            Index = index;
+            Data = data;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueWrite.cs
new file mode 100644
index 0000000..defc07e
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtPropertyValueWrite.cs
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtPropertyValueWrite : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x17;
+
+        // Properties.
+        public byte ObjectIndex { get; }
+        public byte PropertyId { get; }
+        public byte Count { get; }
+        public ushort Index { get; }
+        public byte[] Data { get; }
+
+        public ApduDataExtPropertyValueWrite(byte objectIndex, byte propertyId, byte count, ushort index, byte[] data)
+        {
+            ObjectIndex = objectIndex;
+            PropertyId = propertyId;
+            Count = count;
+            Index = index;
+            Data = data;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterMemoryRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterMemoryRequest.cs
new file mode 100644
index 0000000..7e673c3
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterMemoryRequest.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtReadRouterMemoryRequest : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x08;
+
+        public ApduDataExtReadRouterMemoryRequest()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterMemoryResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterMemoryResponse.cs
new file mode 100644
index 0000000..ee2f825
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterMemoryResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtReadRouterMemoryResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x09;
+
+        public ApduDataExtReadRouterMemoryResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterStatusRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterStatusRequest.cs
new file mode 100644
index 0000000..4abf5e4
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterStatusRequest.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtReadRouterStatusRequest : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x0D;
+
+        public ApduDataExtReadRouterStatusRequest()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterStatusResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterStatusResponse.cs
new file mode 100644
index 0000000..9536b0f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRouterStatusResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtReadRouterStatusResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x0E;
+
+        public ApduDataExtReadRouterStatusResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRoutingTableRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRoutingTableRequest.cs
new file mode 100644
index 0000000..6c5e42c
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRoutingTableRequest.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtReadRoutingTableRequest : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x01;
+
+        public ApduDataExtReadRoutingTableRequest()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRoutingTableResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRoutingTableResponse.cs
new file mode 100644
index 0000000..10caf24
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtReadRoutingTableResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtReadRoutingTableResponse : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x02;
+
+        public ApduDataExtReadRoutingTableResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRouterMemoryRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRouterMemoryRequest.cs
new file mode 100644
index 0000000..70ef98f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRouterMemoryRequest.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtWriteRouterMemoryRequest : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x0A;
+
+        public ApduDataExtWriteRouterMemoryRequest()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRouterStatusRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRouterStatusRequest.cs
new file mode 100644
index 0000000..fa6b021
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRouterStatusRequest.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtWriteRouterStatusRequest : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x0F;
+
+        public ApduDataExtWriteRouterStatusRequest()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRoutingTableRequest.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRoutingTableRequest.cs
new file mode 100644
index 0000000..a9a42e1
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataExtWriteRoutingTableRequest.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataExtWriteRoutingTableRequest : ApduDataExt
+    {
+
+        // Accessors for discriminator values.
+        public override byte ExtApciType => 0x03;
+
+        public ApduDataExtWriteRoutingTableRequest()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueRead.cs
new file mode 100644
index 0000000..7bfc343
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataGroupValueRead : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x0;
+
+        public ApduDataGroupValueRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueResponse.cs
new file mode 100644
index 0000000..ad91915
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueResponse.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataGroupValueResponse : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x1;
+
+        // Properties.
+        public sbyte DataFirstByte { get; }
+        public byte[] Data { get; }
+
+        public ApduDataGroupValueResponse(sbyte dataFirstByte, byte[] data)
+        {
+            DataFirstByte = dataFirstByte;
+            Data = data;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueWrite.cs
new file mode 100644
index 0000000..5d46503
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataGroupValueWrite.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataGroupValueWrite : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x2;
+
+        // Properties.
+        public sbyte DataFirstByte { get; }
+        public byte[] Data { get; }
+
+        public ApduDataGroupValueWrite(sbyte dataFirstByte, byte[] data)
+        {
+            DataFirstByte = dataFirstByte;
+            Data = data;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressRead.cs
new file mode 100644
index 0000000..dade850
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressRead.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataIndividualAddressRead : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x4;
+
+        public ApduDataIndividualAddressRead()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressResponse.cs
new file mode 100644
index 0000000..aad45ec
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressResponse.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataIndividualAddressResponse : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x5;
+
+        public ApduDataIndividualAddressResponse()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressWrite.cs
new file mode 100644
index 0000000..25e9bf3
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataIndividualAddressWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataIndividualAddressWrite : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x3;
+
+        public ApduDataIndividualAddressWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryRead.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryRead.cs
new file mode 100644
index 0000000..80c715f
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryRead.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataMemoryRead : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x8;
+
+        // Properties.
+        public byte NumBytes { get; }
+        public ushort Address { get; }
+
+        public ApduDataMemoryRead(byte numBytes, ushort address)
+        {
+            NumBytes = numBytes;
+            Address = address;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryResponse.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryResponse.cs
new file mode 100644
index 0000000..7a961cf
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryResponse.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataMemoryResponse : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0x9;
+
+        // Properties.
+        public ushort Address { get; }
+        public byte[] Data { get; }
+
+        public ApduDataMemoryResponse(ushort address, byte[] data)
+        {
+            Address = address;
+            Data = data;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryWrite.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryWrite.cs
new file mode 100644
index 0000000..1bbdb09
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataMemoryWrite.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataMemoryWrite : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0xA;
+
+        public ApduDataMemoryWrite()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataOther.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataOther.cs
new file mode 100644
index 0000000..ef9d970
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataOther.cs
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataOther : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0xF;
+
+        // Properties.
+        public ApduDataExt ExtendedApdu { get; }
+
+        public ApduDataOther(ApduDataExt extendedApdu)
+        {
+            ExtendedApdu = extendedApdu;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataRestart.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataRestart.cs
new file mode 100644
index 0000000..2cae6d2
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataRestart.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataRestart : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0xE;
+
+        public ApduDataRestart()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataUserMessage.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataUserMessage.cs
new file mode 100644
index 0000000..4c16f63
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ApduDataUserMessage.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ApduDataUserMessage : ApduData
+    {
+
+        // Accessors for discriminator values.
+        public override byte ApciType => 0xB;
+
+        public ApduDataUserMessage()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMI.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMI.cs
new file mode 100644
index 0000000..947f5f9
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMI.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class CEMI
+    {
+
+        // Abstract accessors for discriminator values.
+        public abstract byte MessageCode { get; }
+
+        public CEMI()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformation.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformation.cs
new file mode 100644
index 0000000..36fbc33
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformation.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class CEMIAdditionalInformation
+    {
+
+        // Abstract accessors for discriminator values.
+        public abstract byte AdditionalInformationType { get; }
+
+        public CEMIAdditionalInformation()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.cs
new file mode 100644
index 0000000..67997e9
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.cs
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIAdditionalInformationBusmonitorInfo : CEMIAdditionalInformation
+    {
+
+        // Accessors for discriminator values.
+        public override byte AdditionalInformationType => 0x03;
+
+        // Constant values.
+        public const byte LEN = 1;
+
+        // Properties.
+        public bool FrameErrorFlag { get; }
+        public bool BitErrorFlag { get; }
+        public bool ParityErrorFlag { get; }
+        public bool UnknownFlag { get; }
+        public bool LostFlag { get; }
+        public byte SequenceNumber { get; }
+
+        public CEMIAdditionalInformationBusmonitorInfo(bool frameErrorFlag, bool bitErrorFlag, bool parityErrorFlag, bool unknownFlag, bool lostFlag, byte sequenceNumber)
+        {
+            FrameErrorFlag = frameErrorFlag;
+            BitErrorFlag = bitErrorFlag;
+            ParityErrorFlag = parityErrorFlag;
+            UnknownFlag = unknownFlag;
+            LostFlag = lostFlag;
+            SequenceNumber = sequenceNumber;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.cs
new file mode 100644
index 0000000..9bc7f9d
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.cs
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class CEMIAdditionalInformationRelativeTimestamp : CEMIAdditionalInformation
+    {
+
+        // Accessors for discriminator values.
+        public override byte AdditionalInformationType => 0x04;
+
+        // Constant values.
+        public const byte LEN = 2;
+
+        // Properties.
+        public RelativeTimestamp RelativeTimestamp { get; }
+
+        public CEMIAdditionalInformationRelativeTimestamp(RelativeTimestamp relativeTimestamp)
+        {
+            RelativeTimestamp = relativeTimestamp;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIPriority.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIPriority.cs
new file mode 100644
index 0000000..51681b4
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/CEMIPriority.cs
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum CEMIPriority
+    {
+        SYSTEM = 0x0,
+        NORMAL = 0x1,
+        URGENT = 0x2,
+        LOW = 0x3,
+    }
+
+}
+
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ChannelInformation.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ChannelInformation.cs
new file mode 100644
index 0000000..b486594
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ChannelInformation.cs
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public class ChannelInformation
+    {
+
+
+        // Properties.
+        public byte NumChannels { get; }
+        public ushort ChannelCode { get; }
+
+        public ChannelInformation(byte numChannels, ushort channelCode)
+        {
+            NumChannels = numChannels;
+            ChannelCode = channelCode;
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ComObjectTable.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ComObjectTable.cs
new file mode 100644
index 0000000..fd403bd
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ComObjectTable.cs
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public abstract class ComObjectTable
+    {
+
+        // Abstract accessors for discriminator values.
+        public abstract FirmwareType FirmwareType { get; }
+
+        public ComObjectTable()
+        {
+        }
+
+    }
+}
diff --git a/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ComObjectTableAddresses.cs b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ComObjectTableAddresses.cs
new file mode 100644
index 0000000..2cc7b5b
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/ComObjectTableAddresses.cs
@@ -0,0 +1,7416 @@
+/*
+ * 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.
+ */
+
+// Code generated by code-generation. DO NOT EDIT.
+
+namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
+{
+
+    public enum ComObjectTableAddresses
+    {
+        DEV0001914201 = 1,
+        DEV0001140C13 = 2,
+        DEV0001140B11 = 3,
+        DEV0001803002 = 4,
+        DEV00641BD610 = 5,
+        DEV0064760210 = 6,
+        DEV0064182410 = 7,
+        DEV0064182310 = 8,
+        DEV0064705C01 = 9,
+        DEV0064181910 = 10,
+        DEV0064181810 = 11,
+        DEV0064181710 = 12,
+        DEV0064181610 = 13,
+        DEV006420C011 = 14,
+        DEV006420BA11 = 15,
+        DEV0064182010 = 16,
+        DEV0064182510 = 17,
+        DEV0064182610 = 18,
+        DEV0064182910 = 19,
+        DEV0064130610 = 20,
+        DEV0064130710 = 21,
+        DEV0064133510 = 22,
+        DEV0064133310 = 23,
+        DEV0064133410 = 24,
+        DEV0064133610 = 25,
+        DEV0064130510 = 26,
+        DEV0064480611 = 27,
+        DEV0064482011 = 28,
+        DEV0064182210 = 29,
+        DEV0064182710 = 30,
+        DEV0064183010 = 31,
+        DEV0064B00812 = 32,
+        DEV0064B00A01 = 33,
+        DEV0064760110 = 34,
+        DEV0064242313 = 35,
+        DEV0064FF2111 = 36,
+        DEV0064FF2112 = 37,
+        DEV0064648B10 = 38,
+        DEV0064724010 = 39,
+        DEV006420BD11 = 40,
+        DEV0064570011 = 41,
+        DEV0064570310 = 42,
+        DEV0064570211 = 43,
+        DEV0064570411 = 44,
+        DEV0064570110 = 45,
+        DEV0064615022 = 46,
+        DEV0064182810 = 47,
+        DEV0064183110 = 48,
+        DEV0064133611 = 49,
+        DEV006A000122 = 50,
+        DEV006A000222 = 51,
+        DEV006A070210 = 52,
+        DEV006BFFF713 = 53,
+        DEV006BFF2111 = 54,
+        DEV006BFFF820 = 55,
+        DEV006B106D10 = 56,
+        DEV0071123130 = 57,
+        DEV0071413133 = 58,
+        DEV0071114019 = 59,
+        DEV007111306C = 60,
+        DEV0071231112 = 61,
+        DEV0071113080 = 62,
+        DEV0071321212 = 63,
+        DEV0071321113 = 64,
+        DEV0071322212 = 65,
+        DEV0071322112 = 66,
+        DEV0071322312 = 67,
+        DEV0071122124 = 68,
+        DEV0071122135 = 69,
+        DEV007112221E = 70,
+        DEV0071122229 = 71,
+        DEV0071413314 = 72,
+        DEV0072300110 = 73,
+        DEV0076002101 = 74,
+        DEV0076002001 = 75,
+        DEV0076002A15 = 76,
+        DEV0076002815 = 77,
+        DEV0076002215 = 78,
+        DEV0076002B15 = 79,
+        DEV0076002715 = 80,
+        DEV0076002315 = 81,
+        DEV0076002415 = 82,
+        DEV0076002615 = 83,
+        DEV0076002515 = 84,
+        DEV0076000201 = 85,
+        DEV0076000101 = 86,
+        DEV0076000301 = 87,
+        DEV0076000401 = 88,
+        DEV0076002903 = 89,
+        DEV0076002901 = 90,
+        DEV007600E503 = 91,
+        DEV0076004002 = 92,
+        DEV0076004003 = 93,
+        DEV0076003402 = 94,
+        DEV0076003401 = 95,
+        DEV007600E908 = 96,
+        DEV007600E907 = 97,
+        DEV000C181710 = 98,
+        DEV000C130510 = 99,
+        DEV000C130610 = 100,
+        DEV000C133610 = 101,
+        DEV000C133410 = 102,
+        DEV000C133310 = 103,
+        DEV000C133611 = 104,
+        DEV000C133510 = 105,
+        DEV000C130710 = 106,
+        DEV000C760210 = 107,
+        DEV000C1BD610 = 108,
+        DEV000C181610 = 109,
+        DEV000C648B10 = 110,
+        DEV000C480611 = 111,
+        DEV000C482011 = 112,
+        DEV000C724010 = 113,
+        DEV000C570211 = 114,
+        DEV000C570310 = 115,
+        DEV000C570411 = 116,
+        DEV000C570110 = 117,
+        DEV000C570011 = 118,
+        DEV000C20BD11 = 119,
+        DEV000C20BA11 = 120,
+        DEV000C760110 = 121,
+        DEV000C705C01 = 122,
+        DEV000CFF2112 = 123,
+        DEV000C242313 = 124,
+        DEV000CB00812 = 125,
+        DEV000CB00713 = 126,
+        DEV000C181910 = 127,
+        DEV000C181810 = 128,
+        DEV000C20C011 = 129,
+        DEV0079002527 = 130,
+        DEV0079004027 = 131,
+        DEV0079000223 = 132,
+        DEV0079000123 = 133,
+        DEV0079001427 = 134,
+        DEV0079003027 = 135,
+        DEV0079100C13 = 136,
+        DEV0079101C11 = 137,
+        DEV0080709010 = 138,
+        DEV0080707010 = 139,
+        DEV0080706010 = 140,
+        DEV0080706810 = 141,
+        DEV0080705010 = 142,
+        DEV0080703013 = 143,
+        DEV0080704021 = 144,
+        DEV0080704022 = 145,
+        DEV0080704020 = 146,
+        DEV0080701111 = 147,
+        DEV0080701811 = 148,
+        DEV008020A110 = 149,
+        DEV008020A210 = 150,
+        DEV008020A010 = 151,
+        DEV0080207212 = 152,
+        DEV0080209111 = 153,
+        DEV0080204310 = 154,
+        DEV008020B612 = 155,
+        DEV008020B412 = 156,
+        DEV008020B512 = 157,
+        DEV0080208310 = 158,
+        DEV0080702111 = 159,
+        DEV0085000520 = 160,
+        DEV0085000620 = 161,
+        DEV0085000720 = 162,
+        DEV0085012210 = 163,
+        DEV0085011210 = 164,
+        DEV0085013220 = 165,
+        DEV0085010210 = 166,
+        DEV0085000A10 = 167,
+        DEV0085000B10 = 168,
+        DEV0085071010 = 169,
+        DEV008500FB10 = 170,
+        DEV0085060210 = 171,
+        DEV0085060110 = 172,
+        DEV0085000D20 = 173,
+        DEV008500C810 = 174,
+        DEV0085040111 = 175,
+        DEV008500C910 = 176,
+        DEV0085045020 = 177,
+        DEV0085070210 = 178,
+        DEV0085070110 = 179,
+        DEV0085070310 = 180,
+        DEV0085000E20 = 181,
+        DEV008E596010 = 182,
+        DEV008E593710 = 183,
+        DEV008E597710 = 184,
+        DEV008E598310 = 185,
+        DEV008E598910 = 186,
+        DEV008E598920 = 187,
+        DEV008E598320 = 188,
+        DEV008E596021 = 189,
+        DEV008E597721 = 190,
+        DEV008E587320 = 191,
+        DEV008E587020 = 192,
+        DEV008E587220 = 193,
+        DEV008E587120 = 194,
+        DEV008E679910 = 195,
+        DEV008E618310 = 196,
+        DEV008E707910 = 197,
+        DEV008E676610 = 198,
+        DEV008E004010 = 199,
+        DEV008E570910 = 200,
+        DEV008E558810 = 201,
+        DEV008E683410 = 202,
+        DEV008E707710 = 203,
+        DEV008E707810 = 204,
+        DEV008E787310 = 205,
+        DEV008E787410 = 206,
+        DEV0091100013 = 207,
+        DEV0091100110 = 208,
+        DEV009E670101 = 209,
+        DEV009E119311 = 210,
+        DEV00A2101C11 = 211,
+        DEV00A2100C13 = 212,
+        DEV00A2300110 = 213,
+        DEV0002A05814 = 214,
+        DEV0002A07114 = 215,
+        DEV0002134A10 = 216,
+        DEV0002A03D12 = 217,
+        DEV0002A03422 = 218,
+        DEV0002A03321 = 219,
+        DEV0002648B10 = 220,
+        DEV0002A09013 = 221,
+        DEV0002A08F13 = 222,
+        DEV0002A05510 = 223,
+        DEV0002A05910 = 224,
+        DEV0002A05326 = 225,
+        DEV0002A05428 = 226,
+        DEV0002A08411 = 227,
+        DEV0002A08511 = 228,
+        DEV0002A00F11 = 229,
+        DEV0002A07310 = 230,
+        DEV0002A04110 = 231,
+        DEV0002A06414 = 232,
+        DEV0002A03813 = 233,
+        DEV0002A07F13 = 234,
+        DEV0002A01217 = 235,
+        DEV0002A07914 = 236,
+        DEV0002A06114 = 237,
+        DEV0002A06714 = 238,
+        DEV0002A06214 = 239,
+        DEV0002A06514 = 240,
+        DEV0002A07714 = 241,
+        DEV0002A06014 = 242,
+        DEV0002A06614 = 243,
+        DEV0002A07814 = 244,
+        DEV0002A09A13 = 245,
+        DEV0002A00213 = 246,
+        DEV0002A00113 = 247,
+        DEV0002A01511 = 248,
+        DEV0002A01112 = 249,
+        DEV0002FF1140 = 250,
+        DEV0002A07E10 = 251,
+        DEV0002A07213 = 252,
+        DEV0002A04A35 = 253,
+        DEV0002613812 = 254,
+        DEV0002A07420 = 255,
+        DEV0002A07520 = 256,
+        DEV0002A07B12 = 257,
+        DEV0002A07C12 = 258,
+        DEV0002A04312 = 259,
+        DEV0002A04412 = 260,
+        DEV0002A04512 = 261,
+        DEV0002A04912 = 262,
+        DEV0002A05012 = 263,
+        DEV0002A01811 = 264,
+        DEV0002A03E11 = 265,
+        DEV0002A08711 = 266,
+        DEV0002A09311 = 267,
+        DEV0002A01011 = 268,
+        DEV0002A01622 = 269,
+        DEV0002A04210 = 270,
+        DEV0002A0C310 = 271,
+        DEV0002A0C316 = 272,
+        DEV0002A04B10 = 273,
+        DEV0002A09B12 = 274,
+        DEV0002A04F13 = 275,
+        DEV0002A04D13 = 276,
+        DEV0002A04C13 = 277,
+        DEV0002A04E13 = 278,
+        DEV0002A09C12 = 279,
+        DEV0002A03C10 = 280,
+        DEV0002A0A511 = 281,
+        DEV0002A0A516 = 282,
+        DEV0002A0A514 = 283,
+        DEV0002A0A513 = 284,
+        DEV0002A0A512 = 285,
+        DEV0002A0A611 = 286,
+        DEV0002A0A616 = 287,
+        DEV0002A09111 = 288,
+        DEV0002A09211 = 289,
+        DEV0002632010 = 290,
+        DEV0002632020 = 291,
+        DEV0002632170 = 292,
+        DEV0002632040 = 293,
+        DEV00C8272040 = 294,
+        DEV00C8272260 = 295,
+        DEV00C8272060 = 296,
+        DEV00C8272160 = 297,
+        DEV00C8272050 = 298,
+        DEV00C910BA10 = 299,
+        DEV00C9106D10 = 300,
+        DEV00C9107C20 = 301,
+        DEV00C9108511 = 302,
+        DEV00C9108500 = 303,
+        DEV00C9106210 = 304,
+        DEV00C9109310 = 305,
+        DEV00C9109300 = 306,
+        DEV00C9109210 = 307,
+        DEV00C9109200 = 308,
+        DEV00C9109810 = 309,
+        DEV00C9109A10 = 310,
+        DEV00C9109A00 = 311,
+        DEV00C910A420 = 312,
+        DEV00C910A110 = 313,
+        DEV00C910A100 = 314,
+        DEV00C910A010 = 315,
+        DEV00C910A000 = 316,
+        DEV00C910A310 = 317,
+        DEV00C910A300 = 318,
+        DEV00C910A210 = 319,
+        DEV00C910A200 = 320,
+        DEV00C9109B10 = 321,
+        DEV00C9109B00 = 322,
+        DEV00C9106110 = 323,
+        DEV00C9109110 = 324,
+        DEV00C9109100 = 325,
+        DEV00C9109610 = 326,
+        DEV00C9109600 = 327,
+        DEV00C9109710 = 328,
+        DEV00C9109700 = 329,
+        DEV00C9109510 = 330,
+        DEV00C9109500 = 331,
+        DEV00C9109910 = 332,
+        DEV00C9109900 = 333,
+        DEV00C9109C10 = 334,
+        DEV00C9109C00 = 335,
+        DEV00C910AB10 = 336,
+        DEV00C910AB00 = 337,
+        DEV00C910AC10 = 338,
+        DEV00C910AC00 = 339,
+        DEV00C910AD10 = 340,
+        DEV00C910AD00 = 341,
+        DEV00C910A810 = 342,
+        DEV00C910B010 = 343,
+        DEV00C910B310 = 344,
+        DEV00C9106311 = 345,
+        DEV00C9106111 = 346,
+        DEV00C9106510 = 347,
+        DEV00C910A710 = 348,
+        DEV00C9107610 = 349,
+        DEV00C910AF10 = 350,
+        DEV00C910B510 = 351,
+        DEV00C910890A = 352,
+        DEV00C9FF1012 = 353,
+        DEV00C9FF0913 = 354,
+        DEV00C9FF1112 = 355,
+        DEV00C9100310 = 356,
+        DEV00C9101110 = 357,
+        DEV00C9101010 = 358,
+        DEV00C9103710 = 359,
+        DEV00C9101310 = 360,
+        DEV00C9FF0D12 = 361,
+        DEV00C9100E10 = 362,
+        DEV00C9100610 = 363,
+        DEV00C9100510 = 364,
+        DEV00C9100710 = 365,
+        DEV00C9FF1D20 = 366,
+        DEV00C9FF1C10 = 367,
+        DEV00C9100810 = 368,
+        DEV00C9FF1420 = 369,
+        DEV00C9100D10 = 370,
+        DEV00C9101220 = 371,
+        DEV00C9102330 = 372,
+        DEV00C9102130 = 373,
+        DEV00C9102430 = 374,
+        DEV00C9100831 = 375,
+        DEV00C9102530 = 376,
+        DEV00C9100531 = 377,
+        DEV00C9102030 = 378,
+        DEV00C9100731 = 379,
+        DEV00C9100631 = 380,
+        DEV00C9102230 = 381,
+        DEV00C9100632 = 382,
+        DEV00C9100532 = 383,
+        DEV00C9100732 = 384,
+        DEV00C9100832 = 385,
+        DEV00C9102532 = 386,
+        DEV00C9102132 = 387,
+        DEV00C9102332 = 388,
+        DEV00C9102432 = 389,
+        DEV00C9102032 = 390,
+        DEV00C9102232 = 391,
+        DEV00C9104432 = 392,
+        DEV00C9100D11 = 393,
+        DEV00C9100633 = 394,
+        DEV00C9100533 = 395,
+        DEV00C9100733 = 396,
+        DEV00C9100833 = 397,
+        DEV00C9102533 = 398,
+        DEV00C9102133 = 399,
+        DEV00C9102333 = 400,
+        DEV00C9102433 = 401,
+        DEV00C9102033 = 402,
+        DEV00C9102233 = 403,
+        DEV00C9104810 = 404,
+        DEV00C9FF1A11 = 405,
+        DEV00C9100212 = 406,
+        DEV00C9FF0A11 = 407,
+        DEV00C9FF0C12 = 408,
+        DEV00C9100112 = 409,
+        DEV00C9FF1911 = 410,
+        DEV00C9FF0B12 = 411,
+        DEV00C9FF0715 = 412,
+        DEV00C9FF1B10 = 413,
+        DEV00C9101610 = 414,
+        DEV00C9FF1B11 = 415,
+        DEV00C9101611 = 416,
+        DEV00C9101612 = 417,
+        DEV00C9FF0F11 = 418,
+        DEV00C910B710 = 419,
+        DEV00C9FF1E30 = 420,
+        DEV00C9100410 = 421,
+        DEV00C9106410 = 422,
+        DEV00C9106710 = 423,
+        DEV00C9106700 = 424,
+        DEV00C9106810 = 425,
+        DEV00C9106800 = 426,
+        DEV00C9106010 = 427,
+        DEV00C9106000 = 428,
+        DEV00C9106310 = 429,
+        DEV00C9107110 = 430,
... 45174 lines suppressed ...

[plc4x] 05/09: - Updated the NuGet information of the .Net bundles

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

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

commit 8ce88213784de0e620f2cc8b309b4e3e20b2dba2
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Dec 3 15:47:47 2020 +0100

    - Updated the NuGet information of the .Net bundles
---
 sandbox/plc4net/api/plc4net-api.csproj                         | 3 +++
 sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj | 3 +++
 sandbox/plc4net/spi/plc4net-spi.csproj                         | 3 +++
 3 files changed, 9 insertions(+)

diff --git a/sandbox/plc4net/api/plc4net-api.csproj b/sandbox/plc4net/api/plc4net-api.csproj
index 11ff5a4..7da4e99 100644
--- a/sandbox/plc4net/api/plc4net-api.csproj
+++ b/sandbox/plc4net/api/plc4net-api.csproj
@@ -26,6 +26,9 @@
         <Authors>Apache PLC4X</Authors>
         <Copyright>The Apache Software Foundation</Copyright>
         <PackageProjectUrl>https://plc4x.apache.org</PackageProjectUrl>
+        <Title>PLC4Net: API</Title>
+        <PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
+        <PackageVersion>0.8.0-SNAPSHOT</PackageVersion>
     </PropertyGroup>
 
 </Project>
diff --git a/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj b/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
index e783193..5ed4474 100644
--- a/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
+++ b/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
@@ -26,6 +26,9 @@
     <Authors>Apache PLC4X</Authors>
     <Copyright>The Apache Software Foundation</Copyright>
     <PackageProjectUrl>https://plc4x.apache.org</PackageProjectUrl>
+    <Title>PLC4Net: Driver: KNXNet/IP</Title>
+    <PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
+    <PackageVersion>0.8.0-SNAPSHOT</PackageVersion>
   </PropertyGroup>
 
   <ItemGroup>
diff --git a/sandbox/plc4net/spi/plc4net-spi.csproj b/sandbox/plc4net/spi/plc4net-spi.csproj
index 26090c5..649ee68 100644
--- a/sandbox/plc4net/spi/plc4net-spi.csproj
+++ b/sandbox/plc4net/spi/plc4net-spi.csproj
@@ -26,6 +26,9 @@
         <Authors>Apache PLC4X</Authors>
         <Copyright>The Apache Software Foundation</Copyright>
         <PackageProjectUrl>https://plc4x.apache.org</PackageProjectUrl>
+        <PackageVersion>0.8.0-SNAPSHOT</PackageVersion>
+        <Title>PLC4Net: SPI</Title>
+        <PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
     </PropertyGroup>
 
     <ItemGroup>

[plc4x] 06/09: - Added a first test for the decoder - Fixed issues in the float and double processing of the ReadBuffer - Made the PlcValues comparable for equality

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

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

commit 7a4b8cb38b879166977e6c5e27e472d8eb480e74
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Dec 3 18:25:51 2020 +0100

    - Added a first test for the decoder
    - Fixed issues in the float and double processing of the ReadBuffer
    - Made the PlcValues comparable for equality
---
 sandbox/plc4net/api/plc4net-api.csproj             |  2 +-
 .../plc4net-driver-knxproj-test.csproj}            | 15 +++++---
 .../knxnetip/ParserSerializerTestsuite.xml         |  0
 .../knxnetip/readwrite/model/KnxDatapointTests.cs  | 42 ++++++++++++++++++++++
 .../drivers/knxnetip/plc4net-driver-knxproj.csproj |  2 +-
 .../knxnetip/readwrite/model/KnxDatapoint.cs       |  0
 .../plc4net/plc4net.driver/plc4net.driver.csproj   | 29 ---------------
 sandbox/plc4net/plc4net.sln                        |  7 ++++
 sandbox/plc4net/pom.xml                            |  4 +--
 sandbox/plc4net/spi/plc4net-spi.csproj             |  2 +-
 sandbox/plc4net/spi/spi/generation/ReadBuffer.cs   | 26 +++++++-------
 sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs    | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs    | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs    | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcDATE.cs    | 19 ++++++++++
 .../spi/spi/model/values/PlcDATE_AND_TIME.cs       | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs   | 18 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs   | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs   | 18 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcNULL.cs    | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs | 18 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs  | 19 ++++++++++
 .../model/values/PlcSimpleNumericValueAdapter.cs   | 18 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcStruct.cs  | 19 +++++++++-
 .../spi/spi/model/values/PlcTIME _OF_DAY.cs        | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcTIME.cs    | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs   | 19 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcWORD.cs    | 18 ++++++++++
 sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs | 19 ++++++++++
 29 files changed, 414 insertions(+), 52 deletions(-)

diff --git a/sandbox/plc4net/api/plc4net-api.csproj b/sandbox/plc4net/api/plc4net-api.csproj
index 7da4e99..d568d3b 100644
--- a/sandbox/plc4net/api/plc4net-api.csproj
+++ b/sandbox/plc4net/api/plc4net-api.csproj
@@ -20,7 +20,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
     <PropertyGroup>
-        <TargetFramework>netstandard2.0</TargetFramework>
+        <TargetFramework>net452</TargetFramework>
         <RootNamespace>org.apache.plc4net</RootNamespace>
         <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
         <Authors>Apache PLC4X</Authors>
diff --git a/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj b/sandbox/plc4net/drivers/knxnetip-test/plc4net-driver-knxproj-test.csproj
similarity index 72%
copy from sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
copy to sandbox/plc4net/drivers/knxnetip-test/plc4net-driver-knxproj-test.csproj
index 5ed4474..5abe19a 100644
--- a/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
+++ b/sandbox/plc4net/drivers/knxnetip-test/plc4net-driver-knxproj-test.csproj
@@ -20,20 +20,27 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
+    <TargetFramework>net452</TargetFramework>
     <RootNamespace>org.apache.plc4net</RootNamespace>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
     <Authors>Apache PLC4X</Authors>
     <Copyright>The Apache Software Foundation</Copyright>
     <PackageProjectUrl>https://plc4x.apache.org</PackageProjectUrl>
-    <Title>PLC4Net: Driver: KNXNet/IP</Title>
+    <Title>PLC4Net: Driver: KNXNet/IP: Test</Title>
     <PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
     <PackageVersion>0.8.0-SNAPSHOT</PackageVersion>
   </PropertyGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\api\plc4net-api.csproj" />
-    <ProjectReference Include="..\..\spi\plc4net-spi.csproj" />
+    <PackageReference Include="xunit" Version="2.4.1" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\knxnetip\plc4net-driver-knxproj.csproj" />
   </ItemGroup>
 
 </Project>
diff --git a/sandbox/plc4net/drivers/knxnetip/generated/testing/assets/protocols/knxnetip/ParserSerializerTestsuite.xml b/sandbox/plc4net/drivers/knxnetip-test/resources/protocols/knxnetip/ParserSerializerTestsuite.xml
similarity index 100%
rename from sandbox/plc4net/drivers/knxnetip/generated/testing/assets/protocols/knxnetip/ParserSerializerTestsuite.xml
rename to sandbox/plc4net/drivers/knxnetip-test/resources/protocols/knxnetip/ParserSerializerTestsuite.xml
diff --git a/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs b/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs
new file mode 100644
index 0000000..64a0d55
--- /dev/null
+++ b/sandbox/plc4net/drivers/knxnetip-test/test/knxnetip/readwrite/model/KnxDatapointTests.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using org.apache.plc4net.api.value;
+using org.apache.plc4net.drivers.knxnetip.readwrite.model;
+using org.apache.plc4net.spi.generation;
+using org.apache.plc4net.spi.model.values;
+using Xunit;
+
+namespace org.apache.plc4net.test.knxnetip.readwrite.model
+{
+    public class KnxDatapointTests
+    {
+        [Fact]
+        public void DecodeKnxData1()
+        {
+            var formatName = "F32";
+            var input = StrToByteArray("0041b00000");
+            IPlcValue expected = new PlcREAL(22.0f);
+            
+            var actual = new KnxDatapoint().Parse(new ReadBuffer(input), formatName);
+            
+            Assert.Equal(expected, actual);
+        }
+        
+        private static byte[] StrToByteArray(string str)
+        {
+            var hexIndex = new Dictionary<string, byte>();
+            for (var i = 0; i <= 255; i++) 
+            {
+                hexIndex.Add(i.ToString("X2"), (byte) i);
+            }
+
+            var hexRes = new List<byte>();
+            for (var i = 0; i < str.Length; i += 2)
+            {
+                hexRes.Add(hexIndex[str.Substring(i, 2).ToUpper()]);
+            }
+            return hexRes.ToArray();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj b/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
index 5ed4474..27ae013 100644
--- a/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
+++ b/sandbox/plc4net/drivers/knxnetip/plc4net-driver-knxproj.csproj
@@ -20,7 +20,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
+    <TargetFramework>net452</TargetFramework>
     <RootNamespace>org.apache.plc4net</RootNamespace>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
     <Authors>Apache PLC4X</Authors>
diff --git a/sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs b/sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxDatapoint.cs
similarity index 100%
rename from sandbox/plc4net/drivers/knxnetip/generated/sources/knxnetip/readwrite/model/KnxDatapoint.cs
rename to sandbox/plc4net/drivers/knxnetip/src/knxnetip/readwrite/model/KnxDatapoint.cs
diff --git a/sandbox/plc4net/plc4net.driver/plc4net.driver.csproj b/sandbox/plc4net/plc4net.driver/plc4net.driver.csproj
deleted file mode 100644
index e54dfc4..0000000
--- a/sandbox/plc4net/plc4net.driver/plc4net.driver.csproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
-    <BaseOutputPath>target/classes</BaseOutputPath>
-    <BaseIntermediateOutputPath>target/classes-intermediate</BaseIntermediateOutputPath>
-    <RestoreOutputPath>target/restore-output-path</RestoreOutputPath>
-  </PropertyGroup>
-
-</Project>
diff --git a/sandbox/plc4net/plc4net.sln b/sandbox/plc4net/plc4net.sln
index 8e4ebe1..5659034 100644
--- a/sandbox/plc4net/plc4net.sln
+++ b/sandbox/plc4net/plc4net.sln
@@ -27,6 +27,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "drivers", "drivers", "{35D8
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "plc4net-driver-knxproj", "drivers\knxnetip\plc4net-driver-knxproj.csproj", "{640E582A-68DF-4E51-B019-AE5774F31B54}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "plc4net-driver-knxproj-test", "drivers\knxnetip-test\plc4net-driver-knxproj-test.csproj", "{E9497B75-55B6-4C14-AAFB-DB93D0C88166}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -45,8 +47,13 @@ Global
 		{640E582A-68DF-4E51-B019-AE5774F31B54}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{640E582A-68DF-4E51-B019-AE5774F31B54}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{640E582A-68DF-4E51-B019-AE5774F31B54}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E9497B75-55B6-4C14-AAFB-DB93D0C88166}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E9497B75-55B6-4C14-AAFB-DB93D0C88166}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E9497B75-55B6-4C14-AAFB-DB93D0C88166}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E9497B75-55B6-4C14-AAFB-DB93D0C88166}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 		{640E582A-68DF-4E51-B019-AE5774F31B54} = {35D8C56A-A721-46B3-A32C-71FCF212E85D}
+		{E9497B75-55B6-4C14-AAFB-DB93D0C88166} = {35D8C56A-A721-46B3-A32C-71FCF212E85D}
 	EndGlobalSection
 EndGlobal
diff --git a/sandbox/plc4net/pom.xml b/sandbox/plc4net/pom.xml
index 418a489..5d9854c 100644
--- a/sandbox/plc4net/pom.xml
+++ b/sandbox/plc4net/pom.xml
@@ -58,7 +58,7 @@
                   <artifactId>plc4x-protocols-knxnetip</artifactId>
                   <classifier>tests</classifier>
                   <type>test-jar</type>
-                  <outputDirectory>${project.basedir}/drivers/knxnetip/generated/testing/assets</outputDirectory>
+                  <outputDirectory>${project.basedir}/drivers/knxnetip-test/resources</outputDirectory>
                   <includes>**/*.xml</includes>
                   <excludes>META-INF/**,org/**</excludes>
                 </artifactItem>
@@ -85,7 +85,7 @@
               <protocolName>knxnetip</protocolName>
               <languageName>C#</languageName>
               <outputFlavor>read-write</outputFlavor>
-              <outputDir>${project.basedir}/drivers/knxnetip/generated/sources</outputDir>
+              <outputDir>${project.basedir}/drivers/knxnetip/src</outputDir>
             </configuration>
           </execution>
         </executions>
diff --git a/sandbox/plc4net/spi/plc4net-spi.csproj b/sandbox/plc4net/spi/plc4net-spi.csproj
index 649ee68..481ffa1 100644
--- a/sandbox/plc4net/spi/plc4net-spi.csproj
+++ b/sandbox/plc4net/spi/plc4net-spi.csproj
@@ -20,7 +20,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
     <PropertyGroup>
-        <TargetFramework>netstandard2.0</TargetFramework>
+        <TargetFramework>net452</TargetFramework>
         <RootNamespace>org.apache.plc4net</RootNamespace>
         <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
         <Authors>Apache PLC4X</Authors>
diff --git a/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs b/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs
index f727fba..33669a4 100644
--- a/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs
+++ b/sandbox/plc4net/spi/spi/generation/ReadBuffer.cs
@@ -76,7 +76,7 @@ namespace org.apache.plc4net.spi.generation
             {
                 throw new ArgumentOutOfRangeException();
             }
-            return (byte) _reader.ReadInt(0, bitLength);
+            return (byte) _reader.ReadInt(bitLength);
         }
         
         public ushort ReadUshort(int bitLength)
@@ -85,7 +85,7 @@ namespace org.apache.plc4net.spi.generation
             {
                 throw new ArgumentOutOfRangeException();
             }
-            return (ushort) _reader.ReadInt(0, bitLength);
+            return (ushort) _reader.ReadInt(bitLength);
         }
 
         public uint ReadUint(int bitLength)
@@ -94,7 +94,7 @@ namespace org.apache.plc4net.spi.generation
             {
                 throw new ArgumentOutOfRangeException();
             }
-            return (uint) _reader.ReadInt(0, bitLength);
+            return (uint) _reader.ReadInt(bitLength);
         }
 
         public ulong ReadUlong(int bitLength)
@@ -107,9 +107,9 @@ namespace org.apache.plc4net.spi.generation
             ulong firstInt = 0;
             if (bitLength > 32)
             {
-                firstInt = (ulong) _reader.ReadInt(0, bitLength - 32) << 32;
+                firstInt = (ulong) _reader.ReadInt(bitLength - 32) << 32;
             }
-            return firstInt | (ulong) _reader.ReadInt(0, bitLength);
+            return firstInt | (ulong) _reader.ReadInt(bitLength);
         }
 
         public sbyte ReadSbyte(int bitLength)
@@ -118,7 +118,7 @@ namespace org.apache.plc4net.spi.generation
             {
                 throw new ArgumentOutOfRangeException();
             }
-            return (sbyte) _reader.ReadInt(0, bitLength);
+            return (sbyte) _reader.ReadInt(bitLength);
         }
         
         public short ReadShort(int bitLength)
@@ -127,7 +127,7 @@ namespace org.apache.plc4net.spi.generation
             {
                 throw new ArgumentOutOfRangeException();
             }
-            return (short) _reader.ReadInt(0, bitLength);
+            return (short) _reader.ReadInt(bitLength);
         }
 
         public int ReadInt(int bitLength)
@@ -136,7 +136,7 @@ namespace org.apache.plc4net.spi.generation
             {
                 throw new ArgumentOutOfRangeException();
             }
-            return (int) _reader.ReadInt(0, bitLength);
+            return _reader.ReadInt(bitLength);
         }
 
         public long ReadLong(int bitLength)
@@ -149,16 +149,16 @@ namespace org.apache.plc4net.spi.generation
             long firstInt = 0;
             if (bitLength > 32)
             {
-                firstInt = (long) _reader.ReadInt(0, bitLength - 32) << 32;
+                firstInt = (long) _reader.ReadInt(bitLength - 32) << 32;
             }
-            return firstInt | (long) _reader.ReadInt(0, bitLength);
+            return firstInt | (long) _reader.ReadInt(bitLength);
         }
 
         public float ReadFloat(bool signed, int exponentBitLength, int mantissaBitLength)
         {
             if (signed && exponentBitLength == 8 && mantissaBitLength == 23)
             {
-                return Convert.ToSingle(ReadInt(32));
+                return BitConverter.ToSingle(BitConverter.GetBytes(ReadInt(32)), 0);
             }
             // This is the format as described in the KNX spec ... it's not a real half precision floating point.
             if (signed && exponentBitLength == 4 && mantissaBitLength == 11)
@@ -185,11 +185,11 @@ namespace org.apache.plc4net.spi.generation
         {
             if (signed && exponentBitLength == 8 && mantissaBitLength == 23)
             {
-                return Convert.ToDouble(ReadInt(32));
+                return BitConverter.ToDouble(BitConverter.GetBytes(ReadInt(32)), 0);
             }
             if (signed && exponentBitLength == 11 && mantissaBitLength == 52)
             {
-                return Convert.ToDouble(ReadLong(64));
+                return BitConverter.ToDouble(BitConverter.GetBytes(ReadLong(64)), 0);
             }
             throw new NotImplementedException("This encoding is currently not supported");
         }
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs b/sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs
index a3a11ad..57df8a3 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcBOOL.cs
@@ -29,5 +29,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcBOOL other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcBOOL) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs b/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs
index 9351847..a11fbcc 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcBYTE.cs
@@ -55,5 +55,24 @@ namespace org.apache.plc4net.spi.model.values
                 GetBoolAt(6), GetBoolAt(7)
             };
         }
+
+        protected bool Equals(PlcBYTE other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcBYTE) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs b/sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs
index 958bb0f..29f322c 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcCHAR.cs
@@ -29,5 +29,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcCHAR other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcCHAR) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcDATE.cs b/sandbox/plc4net/spi/spi/model/values/PlcDATE.cs
index d51b3c4..b857d91 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcDATE.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcDATE.cs
@@ -30,5 +30,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcDATE other)
+        {
+            return value.Equals(other.value);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcDATE) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcDATE_AND_TIME.cs b/sandbox/plc4net/spi/spi/model/values/PlcDATE_AND_TIME.cs
index 1a9b528..e744887 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcDATE_AND_TIME.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcDATE_AND_TIME.cs
@@ -29,5 +29,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcDATE_AND_TIME other)
+        {
+            return value.Equals(other.value);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcDATE_AND_TIME) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs
index 3051771..1e6065d 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcDWORD.cs
@@ -68,5 +68,23 @@ namespace org.apache.plc4net.spi.model.values
             };
         }
 
+        protected bool Equals(PlcDWORD other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcDWORD) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (int) value;
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs b/sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs
index cfd3b7c..6bf4ceb 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcLTIME.cs
@@ -30,5 +30,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcLTIME other)
+        {
+            return value.Equals(other.value);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcLTIME) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs
index 64d67f3..2bfe6f3 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcLWORD.cs
@@ -84,5 +84,23 @@ namespace org.apache.plc4net.spi.model.values
             };
         }
 
+        protected bool Equals(PlcLWORD other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcLWORD) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcNULL.cs b/sandbox/plc4net/spi/spi/model/values/PlcNULL.cs
index 1822fd1..fb8c33a 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcNULL.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcNULL.cs
@@ -26,5 +26,24 @@ namespace org.apache.plc4net.spi.model.values
         public PlcNULL()
         {
         }
+
+        protected bool Equals(PlcNULL other)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcNULL) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            throw new System.NotImplementedException();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs b/sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs
index 1930a60..6d7f9a7 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcPlcList.cs
@@ -30,5 +30,23 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.values = values;
         }
+
+        protected bool Equals(PlcList other)
+        {
+            return Equals(values, other.values);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcList) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (values != null ? values.GetHashCode() : 0);
+        }
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs b/sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs
index be41810..9ff291a 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcSTRING.cs
@@ -29,5 +29,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcSTRING other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcSTRING) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (value != null ? value.GetHashCode() : 0);
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs b/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs
index 122cc0f..8c2a1a0 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcSimpleNumericValueAdapter.cs
@@ -190,5 +190,23 @@ namespace org.apache.plc4net.spi.model.values
             return value.ToString();
         }
 
+        protected bool Equals(SimpleNumericValueAdapter<T> other)
+        {
+            return Equals(value, other.value);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((SimpleNumericValueAdapter<T>) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (value != null ? value.GetHashCode() : 0);
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcStruct.cs b/sandbox/plc4net/spi/spi/model/values/PlcStruct.cs
index 206fac3..1739f14 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcStruct.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcStruct.cs
@@ -31,7 +31,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.values = values;
         }
-        
+
+        protected bool Equals(PlcStruct other)
+        {
+            return Equals(values, other.values);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcStruct) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (values != null ? values.GetHashCode() : 0);
+        }
     }
     
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcTIME _OF_DAY.cs b/sandbox/plc4net/spi/spi/model/values/PlcTIME _OF_DAY.cs
index 2c3c67a..ff80f7c 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcTIME _OF_DAY.cs	
+++ b/sandbox/plc4net/spi/spi/model/values/PlcTIME _OF_DAY.cs	
@@ -30,5 +30,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcTIME_OF_DAY other)
+        {
+            return value.Equals(other.value);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcTIME_OF_DAY) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcTIME.cs b/sandbox/plc4net/spi/spi/model/values/PlcTIME.cs
index 0d78c57..ead78c3 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcTIME.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcTIME.cs
@@ -30,5 +30,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcTIME other)
+        {
+            return value.Equals(other.value);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcTIME) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs b/sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs
index 5b34f8a..518e964 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcWCHAR.cs
@@ -29,5 +29,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcWCHAR other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcWCHAR) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs b/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs
index 84e2b99..b0f0041 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcWORD.cs
@@ -60,5 +60,23 @@ namespace org.apache.plc4net.spi.model.values
             };
         }
 
+        protected bool Equals(PlcWORD other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcWORD) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs b/sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs
index e344e7e..7564b95 100644
--- a/sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs
+++ b/sandbox/plc4net/spi/spi/model/values/PlcWSTRING.cs
@@ -29,5 +29,24 @@ namespace org.apache.plc4net.spi.model.values
         {
             this.value = value;
         }
+
+        protected bool Equals(PlcWSTRING other)
+        {
+            return value == other.value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((PlcWSTRING) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (value != null ? value.GetHashCode() : 0);
+        }
+        
     }
 }
\ No newline at end of file