/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.plc4x.java.knxnetip.readwrite;

import static org.apache.plc4x.java.spi.codegen.fields.FieldReaderFactory.*;
import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
import static org.apache.plc4x.java.spi.codegen.io.DataReaderFactory.*;
import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
import static org.apache.plc4x.java.spi.generation.StaticHelper.*;

import java.time.*;
import java.util.*;
import org.apache.plc4x.java.api.exceptions.*;
import org.apache.plc4x.java.api.value.*;
import org.apache.plc4x.java.spi.codegen.*;
import org.apache.plc4x.java.spi.codegen.fields.*;
import org.apache.plc4x.java.spi.codegen.io.*;
import org.apache.plc4x.java.spi.generation.*;
import org.apache.plc4x.java.spi.values.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// Code generated by code-generation. DO NOT EDIT.

public class KnxProperty {

  private static final Logger LOGGER = LoggerFactory.getLogger(KnxProperty.class);

  public static PlcValue staticParse(
      ReadBuffer readBuffer, KnxPropertyDataType propertyType, Short dataLengthInBytes)
      throws ParseException {
    if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_CONTROL)) { // BOOL
      Byte reservedField0 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 7), (byte) 0x00);

      boolean value = readSimpleField("value", readBoolean(readBuffer));
      return new PlcBOOL(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_CHAR)) { // SINT
      byte value = readSimpleField("value", readSignedByte(readBuffer, 8));
      return new PlcSINT(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_CHAR)) { // USINT
      short value = readSimpleField("value", readUnsignedShort(readBuffer, 8));
      return new PlcUSINT(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_INT)) { // INT
      short value = readSimpleField("value", readSignedShort(readBuffer, 16));
      return new PlcINT(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_UNSIGNED_INT)
        && EvaluationHelper.equals(dataLengthInBytes, (short) 4)) { // UDINT
      long value = readSimpleField("value", readUnsignedLong(readBuffer, 32));
      return new PlcUDINT(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_INT)) { // UINT
      int value = readSimpleField("value", readUnsignedInt(readBuffer, 16));
      return new PlcUINT(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_KNX_FLOAT)) { // REAL
      float value =
          readSimpleField("value", readFloat(readBuffer, 16), WithOption.WithEncoding("KNXFloat"));
      return new PlcREAL(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_DATE)) { // Struct
      Byte reservedField0 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 3), (byte) 0x00);

      byte dayOfMonth = readSimpleField("dayOfMonth", readUnsignedByte(readBuffer, 5));

      Byte reservedField1 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 4), (byte) 0x00);

      byte month = readSimpleField("month", readUnsignedByte(readBuffer, 4));

      Byte reservedField2 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 1), (byte) 0x00);

      byte year = readSimpleField("year", readUnsignedByte(readBuffer, 7));

      Map<String, PlcValue> _map = new HashMap<>();
      _map.put("dayOfMonth", new PlcUSINT(dayOfMonth));
      _map.put("month", new PlcUSINT(month));
      _map.put("year", new PlcUSINT(year));
      return new PlcStruct(_map);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_TIME)) { // Struct
      byte day = readSimpleField("day", readUnsignedByte(readBuffer, 3));

      byte hour = readSimpleField("hour", readUnsignedByte(readBuffer, 5));

      Byte reservedField0 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 2), (byte) 0x00);

      byte minutes = readSimpleField("minutes", readUnsignedByte(readBuffer, 6));

      Byte reservedField1 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 2), (byte) 0x00);

      byte seconds = readSimpleField("seconds", readUnsignedByte(readBuffer, 6));

      Map<String, PlcValue> _map = new HashMap<>();
      _map.put("day", new PlcUSINT(day));
      _map.put("hour", new PlcUSINT(hour));
      _map.put("minutes", new PlcUSINT(minutes));
      _map.put("seconds", new PlcUSINT(seconds));
      return new PlcStruct(_map);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_LONG)) { // DINT
      int value = readSimpleField("value", readSignedInt(readBuffer, 32));
      return new PlcDINT(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_LONG)) { // UDINT
      long value = readSimpleField("value", readUnsignedLong(readBuffer, 32));
      return new PlcUDINT(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_FLOAT)) { // REAL
      float value = readSimpleField("value", readFloat(readBuffer, 32));
      return new PlcREAL(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_DOUBLE)) { // LREAL
      double value = readSimpleField("value", readDouble(readBuffer, 64));
      return new PlcLREAL(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_CHAR_BLOCK)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(10));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_POLL_GROUP_SETTINGS)) { // Struct
      byte[] groupAddress = readBuffer.readByteArray("groupAddress", Math.toIntExact(2));

      boolean disable = readSimpleField("disable", readBoolean(readBuffer));

      Byte reservedField0 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 3), (byte) 0x0);

      byte pollingSoftNr = readSimpleField("pollingSoftNr", readUnsignedByte(readBuffer, 4));

      Map<String, PlcValue> _map = new HashMap<>();
      _map.put("groupAddress", new PlcRawByteArray(groupAddress));
      _map.put("disable", new PlcBOOL(disable));
      _map.put("pollingSoftNr", new PlcUSINT(pollingSoftNr));
      return new PlcStruct(_map);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_SHORT_CHAR_BLOCK)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(5));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_DATE_TIME)) { // Struct
      short year = readSimpleField("year", readUnsignedShort(readBuffer, 8));

      Byte reservedField0 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 4), (byte) 0x00);

      byte month = readSimpleField("month", readUnsignedByte(readBuffer, 4));

      Byte reservedField1 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 3), (byte) 0x00);

      byte dayOfMonth = readSimpleField("dayOfMonth", readUnsignedByte(readBuffer, 5));

      byte dayOfWeek = readSimpleField("dayOfWeek", readUnsignedByte(readBuffer, 3));

      byte hour = readSimpleField("hour", readUnsignedByte(readBuffer, 5));

      Byte reservedField2 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 2), (byte) 0x00);

      byte minutes = readSimpleField("minutes", readUnsignedByte(readBuffer, 6));

      Byte reservedField3 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 2), (byte) 0x00);

      byte seconds = readSimpleField("seconds", readUnsignedByte(readBuffer, 6));

      boolean fault = readSimpleField("fault", readBoolean(readBuffer));

      boolean workingDay = readSimpleField("workingDay", readBoolean(readBuffer));

      boolean noWd = readSimpleField("noWd", readBoolean(readBuffer));

      boolean noYear = readSimpleField("noYear", readBoolean(readBuffer));

      boolean noDate = readSimpleField("noDate", readBoolean(readBuffer));

      boolean noDayOfWeek = readSimpleField("noDayOfWeek", readBoolean(readBuffer));

      boolean noTime = readSimpleField("noTime", readBoolean(readBuffer));

      boolean standardSummerTime = readSimpleField("standardSummerTime", readBoolean(readBuffer));

      boolean qualityOfClock = readSimpleField("qualityOfClock", readBoolean(readBuffer));

      Byte reservedField4 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 7), (byte) 0x00);

      Map<String, PlcValue> _map = new HashMap<>();
      _map.put("year", new PlcUSINT(year));
      _map.put("month", new PlcUSINT(month));
      _map.put("dayOfMonth", new PlcUSINT(dayOfMonth));
      _map.put("dayOfWeek", new PlcUSINT(dayOfWeek));
      _map.put("hour", new PlcUSINT(hour));
      _map.put("minutes", new PlcUSINT(minutes));
      _map.put("seconds", new PlcUSINT(seconds));
      _map.put("fault", new PlcBOOL(fault));
      _map.put("workingDay", new PlcBOOL(workingDay));
      _map.put("noWd", new PlcBOOL(noWd));
      _map.put("noYear", new PlcBOOL(noYear));
      _map.put("noDate", new PlcBOOL(noDate));
      _map.put("noDayOfWeek", new PlcBOOL(noDayOfWeek));
      _map.put("noTime", new PlcBOOL(noTime));
      _map.put("standardSummerTime", new PlcBOOL(standardSummerTime));
      _map.put("qualityOfClock", new PlcBOOL(qualityOfClock));
      return new PlcStruct(_map);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_01)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(1));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_02)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(2));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_03)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(3));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_04)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(4));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_05)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(5));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_06)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(6));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_07)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(7));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_08)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(8));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_09)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(9));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_10)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(10));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_11)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(11));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_12)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(12));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_13)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(13));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_14)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(14));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_15)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(15));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_16)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(16));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_17)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(17));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_18)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(18));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_19)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(19));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_20)) { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(20));
      return new PlcRawByteArray(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_VERSION)) { // Struct
      byte magicNumber = readSimpleField("magicNumber", readUnsignedByte(readBuffer, 5));

      byte versionNumber = readSimpleField("versionNumber", readUnsignedByte(readBuffer, 5));

      byte revisionNumber = readSimpleField("revisionNumber", readUnsignedByte(readBuffer, 6));

      Map<String, PlcValue> _map = new HashMap<>();
      _map.put("magicNumber", new PlcUSINT(magicNumber));
      _map.put("versionNumber", new PlcUSINT(versionNumber));
      _map.put("revisionNumber", new PlcUSINT(revisionNumber));
      return new PlcStruct(_map);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_ALARM_INFO)) { // Struct
      short logNumber = readSimpleField("logNumber", readUnsignedShort(readBuffer, 8));

      short alarmPriority = readSimpleField("alarmPriority", readUnsignedShort(readBuffer, 8));

      short applicationArea = readSimpleField("applicationArea", readUnsignedShort(readBuffer, 8));

      short errorClass = readSimpleField("errorClass", readUnsignedShort(readBuffer, 8));

      Byte reservedField0 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 4), (byte) 0x00);

      boolean errorcodeSup = readSimpleField("errorcodeSup", readBoolean(readBuffer));

      boolean alarmtextSup = readSimpleField("alarmtextSup", readBoolean(readBuffer));

      boolean timestampSup = readSimpleField("timestampSup", readBoolean(readBuffer));

      boolean ackSup = readSimpleField("ackSup", readBoolean(readBuffer));

      Byte reservedField1 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 5), (byte) 0x00);

      boolean locked = readSimpleField("locked", readBoolean(readBuffer));

      boolean alarmunack = readSimpleField("alarmunack", readBoolean(readBuffer));

      boolean inalarm = readSimpleField("inalarm", readBoolean(readBuffer));

      Map<String, PlcValue> _map = new HashMap<>();
      _map.put("logNumber", new PlcUSINT(logNumber));
      _map.put("alarmPriority", new PlcUSINT(alarmPriority));
      _map.put("applicationArea", new PlcUSINT(applicationArea));
      _map.put("errorClass", new PlcUSINT(errorClass));
      _map.put("errorcodeSup", new PlcBOOL(errorcodeSup));
      _map.put("alarmtextSup", new PlcBOOL(alarmtextSup));
      _map.put("timestampSup", new PlcBOOL(timestampSup));
      _map.put("ackSup", new PlcBOOL(ackSup));
      _map.put("locked", new PlcBOOL(locked));
      _map.put("alarmunack", new PlcBOOL(alarmunack));
      _map.put("inalarm", new PlcBOOL(inalarm));
      return new PlcStruct(_map);
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_BINARY_INFORMATION)) { // BOOL
      Byte reservedField0 =
          readReservedField("reserved", readUnsignedByte(readBuffer, 7), (byte) 0x00);

      boolean value = readSimpleField("value", readBoolean(readBuffer));
      return new PlcBOOL(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_BITSET8)) { // BYTE
      short value = readSimpleField("value", readUnsignedShort(readBuffer, 8));
      return new PlcBYTE(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_BITSET16)) { // WORD
      int value = readSimpleField("value", readUnsignedInt(readBuffer, 16));
      return new PlcWORD(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_ENUM8)) { // USINT
      short value = readSimpleField("value", readUnsignedShort(readBuffer, 8));
      return new PlcUSINT(value);
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_SCALING)) { // USINT
      short value = readSimpleField("value", readUnsignedShort(readBuffer, 8));
      return new PlcUSINT(value);
    } else { // RawByteArray
      byte[] value = readBuffer.readByteArray("value", Math.toIntExact(dataLengthInBytes));
      return new PlcRawByteArray(value);
    }
  }

  public static int getLengthInBytes(
      PlcValue _value, KnxPropertyDataType propertyType, Short dataLengthInBytes) {
    return (int) Math.ceil((float) getLengthInBits(_value, propertyType, dataLengthInBytes) / 8.0);
  }

  public static int getLengthInBits(
      PlcValue _value, KnxPropertyDataType propertyType, Short dataLengthInBytes) {
    int lengthInBits = 0;
    if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_CONTROL)) { // BOOL
      // Reserved Field (reserved)
      lengthInBits += 7;

      // Simple field (value)
      lengthInBits += 1;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_CHAR)) { // SINT
      // Simple field (value)
      lengthInBits += 8;
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_CHAR)) { // USINT
      // Simple field (value)
      lengthInBits += 8;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_INT)) { // INT
      // Simple field (value)
      lengthInBits += 16;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_UNSIGNED_INT)
        && EvaluationHelper.equals(dataLengthInBytes, (short) 4)) { // UDINT
      // Simple field (value)
      lengthInBits += 32;
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_INT)) { // UINT
      // Simple field (value)
      lengthInBits += 16;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_KNX_FLOAT)) { // REAL
      // Simple field (value)
      lengthInBits += 16;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_DATE)) { // Struct
      // Reserved Field (reserved)
      lengthInBits += 3;

      // Simple field (dayOfMonth)
      lengthInBits += 5;

      // Reserved Field (reserved)
      lengthInBits += 4;

      // Simple field (month)
      lengthInBits += 4;

      // Reserved Field (reserved)
      lengthInBits += 1;

      // Simple field (year)
      lengthInBits += 7;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_TIME)) { // Struct
      // Simple field (day)
      lengthInBits += 3;

      // Simple field (hour)
      lengthInBits += 5;

      // Reserved Field (reserved)
      lengthInBits += 2;

      // Simple field (minutes)
      lengthInBits += 6;

      // Reserved Field (reserved)
      lengthInBits += 2;

      // Simple field (seconds)
      lengthInBits += 6;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_LONG)) { // DINT
      // Simple field (value)
      lengthInBits += 32;
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_LONG)) { // UDINT
      // Simple field (value)
      lengthInBits += 32;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_FLOAT)) { // REAL
      // Simple field (value)
      lengthInBits += 32;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_DOUBLE)) { // LREAL
      // Simple field (value)
      lengthInBits += 64;
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_CHAR_BLOCK)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_POLL_GROUP_SETTINGS)) { // Struct
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }

      // Simple field (disable)
      lengthInBits += 1;

      // Reserved Field (reserved)
      lengthInBits += 3;

      // Simple field (pollingSoftNr)
      lengthInBits += 4;
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_SHORT_CHAR_BLOCK)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_DATE_TIME)) { // Struct
      // Simple field (year)
      lengthInBits += 8;

      // Reserved Field (reserved)
      lengthInBits += 4;

      // Simple field (month)
      lengthInBits += 4;

      // Reserved Field (reserved)
      lengthInBits += 3;

      // Simple field (dayOfMonth)
      lengthInBits += 5;

      // Simple field (dayOfWeek)
      lengthInBits += 3;

      // Simple field (hour)
      lengthInBits += 5;

      // Reserved Field (reserved)
      lengthInBits += 2;

      // Simple field (minutes)
      lengthInBits += 6;

      // Reserved Field (reserved)
      lengthInBits += 2;

      // Simple field (seconds)
      lengthInBits += 6;

      // Simple field (fault)
      lengthInBits += 1;

      // Simple field (workingDay)
      lengthInBits += 1;

      // Simple field (noWd)
      lengthInBits += 1;

      // Simple field (noYear)
      lengthInBits += 1;

      // Simple field (noDate)
      lengthInBits += 1;

      // Simple field (noDayOfWeek)
      lengthInBits += 1;

      // Simple field (noTime)
      lengthInBits += 1;

      // Simple field (standardSummerTime)
      lengthInBits += 1;

      // Simple field (qualityOfClock)
      lengthInBits += 1;

      // Reserved Field (reserved)
      lengthInBits += 7;
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_01)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_02)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_03)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_04)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_05)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_06)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_07)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_08)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_09)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_10)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_11)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_12)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_13)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_14)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_15)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_16)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_17)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_18)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_19)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_20)) { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_VERSION)) { // Struct
      // Simple field (magicNumber)
      lengthInBits += 5;

      // Simple field (versionNumber)
      lengthInBits += 5;

      // Simple field (revisionNumber)
      lengthInBits += 6;
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_ALARM_INFO)) { // Struct
      // Simple field (logNumber)
      lengthInBits += 8;

      // Simple field (alarmPriority)
      lengthInBits += 8;

      // Simple field (applicationArea)
      lengthInBits += 8;

      // Simple field (errorClass)
      lengthInBits += 8;

      // Reserved Field (reserved)
      lengthInBits += 4;

      // Simple field (errorcodeSup)
      lengthInBits += 1;

      // Simple field (alarmtextSup)
      lengthInBits += 1;

      // Simple field (timestampSup)
      lengthInBits += 1;

      // Simple field (ackSup)
      lengthInBits += 1;

      // Reserved Field (reserved)
      lengthInBits += 5;

      // Simple field (locked)
      lengthInBits += 1;

      // Simple field (alarmunack)
      lengthInBits += 1;

      // Simple field (inalarm)
      lengthInBits += 1;
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_BINARY_INFORMATION)) { // BOOL
      // Reserved Field (reserved)
      lengthInBits += 7;

      // Simple field (value)
      lengthInBits += 1;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_BITSET8)) { // BYTE
      // Simple field (value)
      lengthInBits += 8;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_BITSET16)) { // WORD
      // Simple field (value)
      lengthInBits += 16;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_ENUM8)) { // USINT
      // Simple field (value)
      lengthInBits += 8;
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_SCALING)) { // USINT
      // Simple field (value)
      lengthInBits += 8;
    } else { // RawByteArray
      // Array field
      if (_value != null) {
        lengthInBits += 8 * _value.getRaw().length;
      }
    }

    return lengthInBits;
  }

  public static void staticSerialize(
      WriteBuffer writeBuffer,
      PlcValue _value,
      KnxPropertyDataType propertyType,
      Short dataLengthInBytes)
      throws SerializationException {
    staticSerialize(writeBuffer, _value, propertyType, dataLengthInBytes, ByteOrder.BIG_ENDIAN);
  }

  public static void staticSerialize(
      WriteBuffer writeBuffer,
      PlcValue _value,
      KnxPropertyDataType propertyType,
      Short dataLengthInBytes,
      ByteOrder byteOrder)
      throws SerializationException {
    if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_CONTROL)) { // BOOL
      // Reserved Field (reserved)
      writeReservedField("reserved", (byte) 0x00, writeUnsignedByte(writeBuffer, 7));

      // Simple Field (value)
      writeSimpleField("value", (boolean) _value.getBoolean(), writeBoolean(writeBuffer));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_CHAR)) { // SINT
      // Simple Field (value)
      writeSimpleField("value", (byte) _value.getByte(), writeSignedByte(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_CHAR)) { // USINT
      // Simple Field (value)
      writeSimpleField("value", (short) _value.getShort(), writeUnsignedShort(writeBuffer, 8));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_INT)) { // INT
      // Simple Field (value)
      writeSimpleField("value", (short) _value.getShort(), writeSignedShort(writeBuffer, 16));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_UNSIGNED_INT)
        && EvaluationHelper.equals(dataLengthInBytes, (short) 4)) { // UDINT
      // Simple Field (value)
      writeSimpleField("value", (long) _value.getLong(), writeUnsignedLong(writeBuffer, 32));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_INT)) { // UINT
      // Simple Field (value)
      writeSimpleField("value", (int) _value.getInteger(), writeUnsignedInt(writeBuffer, 16));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_KNX_FLOAT)) { // REAL
      // Simple Field (value)
      writeSimpleField(
          "value",
          (float) _value.getFloat(),
          writeFloat(writeBuffer, 16),
          WithOption.WithEncoding("KNXFloat"));
    } else if (EvaluationHelper.equals(
        propertyType,
        KnxPropertyDataType.PDT_DATE)) { // Struct                // Output something here ...
    } else if (EvaluationHelper.equals(
        propertyType,
        KnxPropertyDataType.PDT_TIME)) { // Struct                // Output something here ...
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_LONG)) { // DINT
      // Simple Field (value)
      writeSimpleField("value", (int) _value.getInteger(), writeSignedInt(writeBuffer, 32));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_UNSIGNED_LONG)) { // UDINT
      // Simple Field (value)
      writeSimpleField("value", (long) _value.getLong(), writeUnsignedLong(writeBuffer, 32));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_FLOAT)) { // REAL
      // Simple Field (value)
      writeSimpleField("value", (float) _value.getFloat(), writeFloat(writeBuffer, 32));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_DOUBLE)) { // LREAL
      // Simple Field (value)
      writeSimpleField("value", (double) _value.getDouble(), writeDouble(writeBuffer, 64));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_CHAR_BLOCK)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType,
        KnxPropertyDataType
            .PDT_POLL_GROUP_SETTINGS)) { // Struct                // Output something here ...
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_SHORT_CHAR_BLOCK)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType,
        KnxPropertyDataType.PDT_DATE_TIME)) { // Struct                // Output something here ...
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_01)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_02)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_03)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_04)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_05)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_06)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_07)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_08)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_09)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_10)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_11)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_12)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_13)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_14)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_15)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_16)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_17)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_18)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_19)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_GENERIC_20)) { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    } else if (EvaluationHelper.equals(
        propertyType,
        KnxPropertyDataType.PDT_VERSION)) { // Struct                // Output something here ...
    } else if (EvaluationHelper.equals(
        propertyType,
        KnxPropertyDataType.PDT_ALARM_INFO)) { // Struct                // Output something here ...
    } else if (EvaluationHelper.equals(
        propertyType, KnxPropertyDataType.PDT_BINARY_INFORMATION)) { // BOOL
      // Reserved Field (reserved)
      writeReservedField("reserved", (byte) 0x00, writeUnsignedByte(writeBuffer, 7));

      // Simple Field (value)
      writeSimpleField("value", (boolean) _value.getBoolean(), writeBoolean(writeBuffer));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_BITSET8)) { // BYTE
      // Simple Field (value)
      writeSimpleField("value", (short) _value.getShort(), writeUnsignedShort(writeBuffer, 8));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_BITSET16)) { // WORD
      // Simple Field (value)
      writeSimpleField("value", (int) _value.getInteger(), writeUnsignedInt(writeBuffer, 16));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_ENUM8)) { // USINT
      // Simple Field (value)
      writeSimpleField("value", (short) _value.getShort(), writeUnsignedShort(writeBuffer, 8));
    } else if (EvaluationHelper.equals(propertyType, KnxPropertyDataType.PDT_SCALING)) { // USINT
      // Simple Field (value)
      writeSimpleField("value", (short) _value.getShort(), writeUnsignedShort(writeBuffer, 8));
    } else { // RawByteArray
      // Array Field (value)
      writeByteArrayField("value", _value.getRaw(), writeByteArray(writeBuffer, 8));
    }
  }
}
