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:35 UTC
[plc4x] 01/09: - Work on PLC4net - Work on C# code generation
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