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

[plc4x] branch feature/plc4go updated: - Fixed some test-timeout-issues in the modbus driver testsuite (Actually by increasing the modbus default timeout) - Moved plc4go out of the sandbox

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

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


The following commit(s) were added to refs/heads/feature/plc4go by this push:
     new 8ff0363  - Fixed some test-timeout-issues in the modbus driver testsuite (Actually by increasing the modbus default timeout) - Moved plc4go out of the sandbox
8ff0363 is described below

commit 8ff03632edc6bfa2aa22216c3c9c96b48f100c9d
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Tue Nov 3 13:07:02 2020 +0100

    - Fixed some test-timeout-issues in the modbus driver testsuite (Actually by increasing the modbus default timeout)
    - Moved plc4go out of the sandbox
---
 .../knxnetip/ParserSerializerTestsuite.xml         |    0
 .../testing/protocols/modbus/DriverTestsuite.xml   |    6 +-
 .../protocols/modbus/ParserSerializerTestsuite.xml |    0
 .../testing/protocols/s7/DriverTestsuite.xml       |    0
 .../protocols/s7/ParserSerializerTestsuite.xml     |    0
 .../cmd/main/drivers/bacnetip_test.go              |    0
 .../cmd/main/drivers/knxnetip_test.go              |    0
 .../cmd/main/drivers/modbus_test.go                |    0
 .../plc4go => plc4go}/cmd/main/drivers/s7_test.go  |    0
 .../cmd/main/drivers/tests/modbus_driver_test.go   |    0
 .../drivers/tests/modbus_parser_serializer_test.go |    0
 {sandbox/plc4go => plc4go}/cmd/main/main.go        |    0
 .../examples/read/hello_world_plc4go_read.go       |    0
 .../examples/write/hello_world_plc4go_write.go     |    0
 {sandbox/plc4go => plc4go}/go.mod                  |    0
 {sandbox/plc4go => plc4go}/go.sum                  |    0
 .../internal/plc4go/bacnetip/BacnetIpDriver.go     |    0
 .../plc4go/bacnetip/readwrite/model/APDU.go        |    0
 .../plc4go/bacnetip/readwrite/model/APDUAbort.go   |  112 +-
 .../bacnetip/readwrite/model/APDUComplexAck.go     |  418 ++++++++
 .../readwrite/model/APDUConfirmedRequest.go        |  598 +++++++++++
 .../plc4go/bacnetip/readwrite/model/APDUError.go   |    0
 .../plc4go/bacnetip/readwrite/model/APDUReject.go  |    0
 .../bacnetip/readwrite/model/APDUSegmentAck.go     |  285 +++++
 .../bacnetip/readwrite/model/APDUSimpleAck.go      |    0
 .../readwrite/model/APDUUnconfirmedRequest.go      |    0
 .../bacnetip/readwrite/model/ApplicationTag.go     |    0
 .../bacnetip/readwrite/model/BACnetAddress.go      |    0
 .../readwrite/model/BACnetConfirmedServiceACK.go   |    0
 .../BACnetConfirmedServiceACKAtomicReadFile.go     |    0
 .../BACnetConfirmedServiceACKAtomicWriteFile.go    |    0
 ...tConfirmedServiceACKConfirmedPrivateTransfer.go |    0
 .../model/BACnetConfirmedServiceACKCreateObject.go |    0
 .../BACnetConfirmedServiceACKGetAlarmSummary.go    |    0
 ...ACnetConfirmedServiceACKGetEnrollmentSummary.go |    0
 ...BACnetConfirmedServiceACKGetEventInformation.go |    0
 .../model/BACnetConfirmedServiceACKReadProperty.go |    0
 ...ACnetConfirmedServiceACKReadPropertyMultiple.go |    0
 .../model/BACnetConfirmedServiceACKReadRange.go    |    0
 ...BACnetConfirmedServiceACKRemovedAuthenticate.go |    0
 ...rmedServiceACKRemovedReadPropertyConditional.go |    0
 .../model/BACnetConfirmedServiceACKVTData.go       |    0
 .../model/BACnetConfirmedServiceACKVTOpen.go       |    0
 .../model/BACnetConfirmedServiceRequest.go         |    0
 ...ACnetConfirmedServiceRequestAcknowledgeAlarm.go |    0
 .../BACnetConfirmedServiceRequestAddListElement.go |    0
 .../BACnetConfirmedServiceRequestAtomicReadFile.go |    0
 ...BACnetConfirmedServiceRequestAtomicWriteFile.go |    0
 ...firmedServiceRequestConfirmedCOVNotification.go |    0
 ...rviceRequestConfirmedCOVNotificationMultiple.go |    0
 ...rmedServiceRequestConfirmedEventNotification.go |    0
 ...firmedServiceRequestConfirmedPrivateTransfer.go |    0
 ...tConfirmedServiceRequestConfirmedTextMessage.go |    0
 .../BACnetConfirmedServiceRequestCreateObject.go   |    0
 .../BACnetConfirmedServiceRequestDeleteObject.go   |    0
 ...rmedServiceRequestDeviceCommunicationControl.go |    0
 ...tConfirmedServiceRequestGetEnrollmentSummary.go |    0
 ...etConfirmedServiceRequestGetEventInformation.go |    0
 ...etConfirmedServiceRequestLifeSafetyOperation.go |    0
 .../BACnetConfirmedServiceRequestReadProperty.go   |    0
 ...tConfirmedServiceRequestReadPropertyMultiple.go |    0
 .../BACnetConfirmedServiceRequestReadRange.go      |    0
 ...netConfirmedServiceRequestReinitializeDevice.go |    0
 ...CnetConfirmedServiceRequestRemoveListElement.go |    0
 ...etConfirmedServiceRequestRemovedAuthenticate.go |    0
 ...ServiceRequestRemovedReadPropertyConditional.go |    0
 ...CnetConfirmedServiceRequestRemovedRequestKey.go |    0
 .../BACnetConfirmedServiceRequestSubscribeCOV.go   |  235 ++---
 ...tConfirmedServiceRequestSubscribeCOVProperty.go |    0
 ...edServiceRequestSubscribeCOVPropertyMultiple.go |    0
 .../model/BACnetConfirmedServiceRequestVTClose.go  |    0
 .../model/BACnetConfirmedServiceRequestVTData.go   |    0
 .../model/BACnetConfirmedServiceRequestVTOpen.go   |    0
 .../BACnetConfirmedServiceRequestWriteProperty.go  |    0
 ...ConfirmedServiceRequestWritePropertyMultiple.go |    0
 .../plc4go/bacnetip/readwrite/model/BACnetError.go |    0
 .../readwrite/model/BACnetErrorAtomicReadFile.go   |    0
 .../readwrite/model/BACnetErrorAtomicWriteFile.go  |    0
 .../model/BACnetErrorConfirmedPrivateTransfer.go   |    0
 .../readwrite/model/BACnetErrorCreateObject.go     |    0
 .../readwrite/model/BACnetErrorGetAlarmSummary.go  |    0
 .../model/BACnetErrorGetEnrollmentSummary.go       |    0
 .../model/BACnetErrorGetEventInformation.go        |    0
 .../readwrite/model/BACnetErrorReadProperty.go     |    0
 .../model/BACnetErrorReadPropertyMultiple.go       |    0
 .../readwrite/model/BACnetErrorReadRange.go        |    0
 .../model/BACnetErrorRemovedAuthenticate.go        |    0
 .../BACnetErrorRemovedReadPropertyConditional.go   |    0
 .../bacnetip/readwrite/model/BACnetErrorVTData.go  |    0
 .../bacnetip/readwrite/model/BACnetErrorVTOpen.go  |    0
 .../bacnetip/readwrite/model/BACnetNetworkType.go  |    0
 .../bacnetip/readwrite/model/BACnetNodeType.go     |    0
 .../bacnetip/readwrite/model/BACnetNotifyType.go   |    0
 .../bacnetip/readwrite/model/BACnetObjectType.go   |    0
 .../bacnetip/readwrite/model/BACnetServiceAck.go   |    0
 .../model/BACnetServiceAckAtomicReadFile.go        |    0
 .../model/BACnetServiceAckAtomicWriteFile.go       |    0
 .../BACnetServiceAckConfirmedPrivateTransfer.go    |    0
 .../model/BACnetServiceAckCreateObject.go          |    0
 .../model/BACnetServiceAckGetAlarmSummary.go       |    0
 .../model/BACnetServiceAckGetEnrollmentSummary.go  |    0
 .../model/BACnetServiceAckGetEventInformation.go   |    0
 .../model/BACnetServiceAckReadProperty.go          |    0
 .../model/BACnetServiceAckReadPropertyMultiple.go  |    0
 .../readwrite/model/BACnetServiceAckReadRange.go   |    0
 .../model/BACnetServiceAckRemovedAuthenticate.go   |    0
 ...CnetServiceAckRemovedReadPropertyConditional.go |    0
 .../readwrite/model/BACnetServiceAckVTData.go      |    0
 .../readwrite/model/BACnetServiceAckVTOpen.go      |    0
 .../plc4go/bacnetip/readwrite/model/BACnetTag.go   |    0
 .../model/BACnetTagApplicationBitString.go         |    0
 .../readwrite/model/BACnetTagApplicationBoolean.go |    0
 .../model/BACnetTagApplicationCharacterString.go   |    0
 .../readwrite/model/BACnetTagApplicationDate.go    |    0
 .../readwrite/model/BACnetTagApplicationDouble.go  |    0
 .../model/BACnetTagApplicationEnumerated.go        |    0
 .../readwrite/model/BACnetTagApplicationNull.go    |    0
 .../model/BACnetTagApplicationObjectIdentifier.go  |    0
 .../model/BACnetTagApplicationOctetString.go       |    0
 .../readwrite/model/BACnetTagApplicationReal.go    |    0
 .../model/BACnetTagApplicationSignedInteger.go     |    0
 .../readwrite/model/BACnetTagApplicationTime.go    |    0
 .../model/BACnetTagApplicationUnsignedInteger.go   |    0
 .../bacnetip/readwrite/model/BACnetTagContext.go   |    0
 .../readwrite/model/BACnetTagWithContent.go        |    0
 .../model/BACnetUnconfirmedServiceRequest.go       |    0
 .../model/BACnetUnconfirmedServiceRequestIAm.go    |    0
 .../model/BACnetUnconfirmedServiceRequestIHave.go  |    0
 ...UnconfirmedServiceRequestTimeSynchronization.go |    0
 ...onfirmedServiceRequestUTCTimeSynchronization.go |    0
 ...rmedServiceRequestUnconfirmedCOVNotification.go |    0
 ...iceRequestUnconfirmedCOVNotificationMultiple.go |    0
 ...edServiceRequestUnconfirmedEventNotification.go |    0
 ...rmedServiceRequestUnconfirmedPrivateTransfer.go |    0
 ...onfirmedServiceRequestUnconfirmedTextMessage.go |    0
 .../model/BACnetUnconfirmedServiceRequestWhoHas.go |    0
 .../model/BACnetUnconfirmedServiceRequestWhoIs.go  |    0
 .../BACnetUnconfirmedServiceRequestWriteGroup.go   |    0
 .../plc4go/bacnetip/readwrite/model/BVLC.go        |    0
 .../model/BVLCDeleteForeignDeviceTableEntry.go     |    0
 .../model/BVLCDistributeBroadcastToNetwork.go      |    0
 .../bacnetip/readwrite/model/BVLCForwardedNPDU.go  |    0
 .../readwrite/model/BVLCOriginalBroadcastNPDU.go   |    0
 .../readwrite/model/BVLCOriginalUnicastNPDU.go     |    0
 .../model/BVLCReadBroadcastDistributionTable.go    |    0
 .../model/BVLCReadBroadcastDistributionTableAck.go |    0
 .../readwrite/model/BVLCReadForeignDeviceTable.go  |    0
 .../model/BVLCReadForeignDeviceTableAck.go         |    0
 .../readwrite/model/BVLCRegisterForeignDevice.go   |    0
 .../plc4go/bacnetip/readwrite/model/BVLCResult.go  |    0
 .../bacnetip/readwrite/model/BVLCSecureBVLL.go     |    0
 .../model/BVLCWideBroadcastDistributionTable.go    |    0
 .../plc4go/bacnetip/readwrite/model/NLM.go         |    0
 .../readwrite/model/NLMIAmRouterToNetwork.go       |    0
 .../readwrite/model/NLMWhoIsRouterToNetwork.go     |    0
 .../plc4go/bacnetip/readwrite/model/NPDU.go        |  726 +++++++++++++
 .../bacnetip/readwrite/model/ParserHelper.go       |    0
 .../bacnetip/readwrite/model/XmlParserHelper.go    |    0
 .../internal/plc4go/knxnetip/KnxNetIpDriver.go     |    0
 .../plc4go/knxnetip/readwrite/model/APCI.go        |    0
 .../plc4go/knxnetip/readwrite/model/CEMI.go        |    0
 .../readwrite/model/CEMIAdditionalInformation.go   |    0
 .../CEMIAdditionalInformationBusmonitorInfo.go     |  307 ++++++
 .../CEMIAdditionalInformationRelativeTimestamp.go  |    0
 .../knxnetip/readwrite/model/CEMIBusmonInd.go      |    0
 .../plc4go/knxnetip/readwrite/model/CEMIDataCon.go |    0
 .../knxnetip/readwrite/model/CEMIDataFrame.go      |  629 +++++++++++
 .../plc4go/knxnetip/readwrite/model/CEMIDataInd.go |    0
 .../plc4go/knxnetip/readwrite/model/CEMIDataReq.go |    0
 .../plc4go/knxnetip/readwrite/model/CEMIFrame.go   |  312 ++++++
 .../knxnetip/readwrite/model/CEMIFrameAck.go       |    0
 .../knxnetip/readwrite/model/CEMIFrameData.go      |  470 +++++++++
 .../knxnetip/readwrite/model/CEMIFrameDataExt.go   |  496 +++++++++
 .../readwrite/model/CEMIFramePollingData.go        |    0
 .../readwrite/model/CEMIFramePollingDataExt.go     |    0
 .../knxnetip/readwrite/model/CEMIMPropReadCon.go   |    0
 .../knxnetip/readwrite/model/CEMIMPropReadReq.go   |    0
 .../knxnetip/readwrite/model/CEMIPollDataCon.go    |    0
 .../knxnetip/readwrite/model/CEMIPollDataReq.go    |    0
 .../knxnetip/readwrite/model/CEMIPriority.go       |    0
 .../plc4go/knxnetip/readwrite/model/CEMIRawCon.go  |    0
 .../plc4go/knxnetip/readwrite/model/CEMIRawInd.go  |    0
 .../plc4go/knxnetip/readwrite/model/CEMIRawReq.go  |    0
 .../knxnetip/readwrite/model/ConnectionRequest.go  |    0
 .../model/ConnectionRequestInformation.go          |    0
 ...ConnectionRequestInformationDeviceManagement.go |    0
 ...ConnectionRequestInformationTunnelConnection.go |    0
 .../knxnetip/readwrite/model/ConnectionResponse.go |    0
 .../readwrite/model/ConnectionResponseDataBlock.go |    0
 .../ConnectionResponseDataBlockDeviceManagement.go |    0
 .../ConnectionResponseDataBlockTunnelConnection.go |    0
 .../readwrite/model/ConnectionStateRequest.go      |    0
 .../readwrite/model/ConnectionStateResponse.go     |    0
 .../knxnetip/readwrite/model/DIBDeviceInfo.go      |    0
 .../knxnetip/readwrite/model/DIBSuppSvcFamilies.go |    0
 .../knxnetip/readwrite/model/DescriptionRequest.go |    0
 .../readwrite/model/DescriptionResponse.go         |    0
 .../readwrite/model/DeviceConfigurationAck.go      |    0
 .../model/DeviceConfigurationAckDataBlock.go       |    0
 .../readwrite/model/DeviceConfigurationRequest.go  |    0
 .../model/DeviceConfigurationRequestDataBlock.go   |    0
 .../knxnetip/readwrite/model/DeviceStatus.go       |  170 +++
 .../knxnetip/readwrite/model/DisconnectRequest.go  |    0
 .../knxnetip/readwrite/model/DisconnectResponse.go |    0
 .../readwrite/model/HPAIControlEndpoint.go         |    0
 .../knxnetip/readwrite/model/HPAIDataEndpoint.go   |    0
 .../readwrite/model/HPAIDiscoveryEndpoint.go       |    0
 .../knxnetip/readwrite/model/HostProtocolCode.go   |    0
 .../plc4go/knxnetip/readwrite/model/IPAddress.go   |    0
 .../plc4go/knxnetip/readwrite/model/KNXAddress.go  |    0
 .../knxnetip/readwrite/model/KNXGroupAddress.go    |    0
 .../readwrite/model/KNXGroupAddress2Level.go       |    0
 .../readwrite/model/KNXGroupAddress3Level.go       |    0
 .../readwrite/model/KNXGroupAddressFreeLevel.go    |    0
 .../knxnetip/readwrite/model/KNXNetIPMessage.go    |    0
 .../knxnetip/readwrite/model/KnxDatapoint.go       | 1090 ++++++++++++++++++++
 .../plc4go/knxnetip/readwrite/model/KnxLayer.go    |    0
 .../knxnetip/readwrite/model/KnxNetIpCore.go       |    0
 .../readwrite/model/KnxNetIpDeviceManagement.go    |    0
 .../knxnetip/readwrite/model/KnxNetIpTunneling.go  |    0
 .../knxnetip/readwrite/model/KnxNetObjectServer.go |    0
 .../model/KnxNetRemoteConfigurationAndDiagnosis.go |    0
 .../readwrite/model/KnxNetRemoteLogging.go         |    0
 .../knxnetip/readwrite/model/KnxStaticHelper.go    |    0
 .../plc4go/knxnetip/readwrite/model/MACAddress.go  |    0
 .../knxnetip/readwrite/model/ParserHelper.go       |    0
 .../model/ProjectInstallationIdentifier.go         |    0
 .../knxnetip/readwrite/model/RelativeTimestamp.go  |    0
 .../knxnetip/readwrite/model/RoutingIndication.go  |    0
 .../knxnetip/readwrite/model/SearchRequest.go      |    0
 .../knxnetip/readwrite/model/SearchResponse.go     |    0
 .../plc4go/knxnetip/readwrite/model/ServiceId.go   |    0
 .../plc4go/knxnetip/readwrite/model/Status.go      |    0
 .../plc4go/knxnetip/readwrite/model/TPCI.go        |    0
 .../knxnetip/readwrite/model/TunnelingRequest.go   |    0
 .../readwrite/model/TunnelingRequestDataBlock.go   |    0
 .../knxnetip/readwrite/model/TunnelingResponse.go  |    0
 .../readwrite/model/TunnelingResponseDataBlock.go  |    0
 .../knxnetip/readwrite/model/UnknownMessage.go     |    0
 .../knxnetip/readwrite/model/XmlParserHelper.go    |    0
 .../internal/plc4go/modbus/ModbusConnection.go     |    0
 .../internal/plc4go/modbus/ModbusDriver.go         |    0
 .../internal/plc4go/modbus/ModbusField.go          |    0
 .../internal/plc4go/modbus/ModbusFieldHandler.go   |    0
 .../internal/plc4go/modbus/ModbusMessageCodec.go   |    0
 .../internal/plc4go/modbus/ModbusReader.go         |    0
 .../internal/plc4go/modbus/ModbusValueHandler.go   |    0
 .../internal/plc4go/modbus/ModbusWriter.go         |    0
 .../plc4go/modbus/readwrite/model/DataItem.go      |  647 ++++++++++++
 .../modbus/readwrite/model/ModbusConstants.go      |    0
 .../modbus/readwrite/model/ModbusDataTypeSizes.go  |    0
 .../modbus/readwrite/model/ModbusErrorCode.go      |    0
 .../plc4go/modbus/readwrite/model/ModbusPDU.go     |  260 +++++
 .../readwrite/model/ModbusPDUDiagnosticRequest.go  |    0
 .../readwrite/model/ModbusPDUDiagnosticResponse.go |    0
 .../modbus/readwrite/model/ModbusPDUError.go       |  163 +++
 .../model/ModbusPDUGetComEventCounterRequest.go    |    0
 .../model/ModbusPDUGetComEventCounterResponse.go   |    0
 .../model/ModbusPDUGetComEventLogRequest.go        |    0
 .../model/ModbusPDUGetComEventLogResponse.go       |    0
 .../ModbusPDUMaskWriteHoldingRegisterRequest.go    |    0
 .../ModbusPDUMaskWriteHoldingRegisterResponse.go   |    0
 .../readwrite/model/ModbusPDUReadCoilsRequest.go   |    0
 .../readwrite/model/ModbusPDUReadCoilsResponse.go  |    0
 .../ModbusPDUReadDeviceIdentificationRequest.go    |    0
 .../ModbusPDUReadDeviceIdentificationResponse.go   |    0
 .../model/ModbusPDUReadDiscreteInputsRequest.go    |    0
 .../model/ModbusPDUReadDiscreteInputsResponse.go   |    0
 .../model/ModbusPDUReadExceptionStatusRequest.go   |    0
 .../model/ModbusPDUReadExceptionStatusResponse.go  |    0
 .../model/ModbusPDUReadFifoQueueRequest.go         |    0
 .../model/ModbusPDUReadFifoQueueResponse.go        |    0
 .../model/ModbusPDUReadFileRecordRequest.go        |    0
 .../model/ModbusPDUReadFileRecordRequestItem.go    |    0
 .../model/ModbusPDUReadFileRecordResponse.go       |    0
 .../model/ModbusPDUReadFileRecordResponseItem.go   |    0
 .../model/ModbusPDUReadHoldingRegistersRequest.go  |    0
 .../model/ModbusPDUReadHoldingRegistersResponse.go |    0
 .../model/ModbusPDUReadInputRegistersRequest.go    |    0
 .../model/ModbusPDUReadInputRegistersResponse.go   |    0
 ...sPDUReadWriteMultipleHoldingRegistersRequest.go |    0
 ...PDUReadWriteMultipleHoldingRegistersResponse.go |    0
 .../model/ModbusPDUReportServerIdRequest.go        |    0
 .../model/ModbusPDUReportServerIdResponse.go       |    0
 .../model/ModbusPDUWriteFileRecordRequest.go       |    0
 .../model/ModbusPDUWriteFileRecordRequestItem.go   |    0
 .../model/ModbusPDUWriteFileRecordResponse.go      |    0
 .../model/ModbusPDUWriteFileRecordResponseItem.go  |    0
 .../model/ModbusPDUWriteMultipleCoilsRequest.go    |    0
 .../model/ModbusPDUWriteMultipleCoilsResponse.go   |    0
 ...odbusPDUWriteMultipleHoldingRegistersRequest.go |    0
 ...dbusPDUWriteMultipleHoldingRegistersResponse.go |    0
 .../model/ModbusPDUWriteSingleCoilRequest.go       |    0
 .../model/ModbusPDUWriteSingleCoilResponse.go      |    0
 .../model/ModbusPDUWriteSingleRegisterRequest.go   |    0
 .../model/ModbusPDUWriteSingleRegisterResponse.go  |    0
 .../modbus/readwrite/model/ModbusSerialADU.go      |    0
 .../plc4go/modbus/readwrite/model/ModbusTcpADU.go  |    0
 .../plc4go/modbus/readwrite/model/ParserHelper.go  |    0
 .../modbus/readwrite/model/XmlParserHelper.go      |    0
 .../internal/plc4go/model/DefaultPlcReadRequest.go |    0
 .../plc4go/model/DefaultPlcReadResponse.go         |    0
 .../plc4go/model/DefaultPlcWriteRequest.go         |    0
 .../plc4go/model/DefaultPlcWriteResponse.go        |    0
 .../internal/plc4go/model/RequestInterceptor.go    |    0
 .../internal/plc4go/model/values/BOOL.go           |    0
 .../internal/plc4go/model/values/BYTE.go           |    0
 .../internal/plc4go/model/values/CHAR.go           |    0
 .../internal/plc4go/model/values/DATE.go           |    0
 .../internal/plc4go/model/values/DATE_AND_TIME.go  |    0
 .../internal/plc4go/model/values/DINT.go           |    0
 .../internal/plc4go/model/values/DWORD.go          |    0
 .../plc4go/model/values/IEC61131ValueHandler.go    |    0
 .../internal/plc4go/model/values/INT.go            |    0
 .../internal/plc4go/model/values/LINT.go           |    0
 .../internal/plc4go/model/values/LREAL.go          |    2 +-
 .../internal/plc4go/model/values/LTIME.go          |    0
 .../internal/plc4go/model/values/LWORD.go          |    0
 .../internal/plc4go/model/values/NULL.go           |    0
 .../internal/plc4go/model/values/PlcList.go        |    0
 .../plc4go/model/values/PlcSimpleValueAdapter.go   |    0
 .../internal/plc4go/model/values/PlcStruct.go      |    0
 .../plc4go/model/values/PlcValueAdapter.go         |    0
 .../internal/plc4go/model/values/REAL.go           |    2 +-
 .../internal/plc4go/model/values/SINT.go           |    0
 .../internal/plc4go/model/values/STRING.go         |    0
 .../internal/plc4go/model/values/TIME.go           |    0
 .../internal/plc4go/model/values/TIME_OF_DAY.go    |    0
 .../internal/plc4go/model/values/UDINT.go          |    0
 .../internal/plc4go/model/values/UINT.go           |    0
 .../internal/plc4go/model/values/ULINT.go          |    0
 .../internal/plc4go/model/values/USINT.go          |    0
 .../internal/plc4go/model/values/WCHAR.go          |    0
 .../internal/plc4go/model/values/WORD.go           |    0
 .../internal/plc4go/model/values/WSTRING.go        |    0
 .../internal/plc4go/s7/S7Driver.go                 |    0
 .../plc4go/s7/readwrite/model/COTPPacket.go        |    0
 .../readwrite/model/COTPPacketConnectionRequest.go |    0
 .../model/COTPPacketConnectionResponse.go          |    0
 .../plc4go/s7/readwrite/model/COTPPacketData.go    |  183 ++++
 .../readwrite/model/COTPPacketDisconnectRequest.go |    0
 .../model/COTPPacketDisconnectResponse.go          |    0
 .../s7/readwrite/model/COTPPacketTpduError.go      |    0
 .../plc4go/s7/readwrite/model/COTPParameter.go     |    0
 .../s7/readwrite/model/COTPParameterCalledTsap.go  |    0
 .../s7/readwrite/model/COTPParameterCallingTsap.go |    0
 .../s7/readwrite/model/COTPParameterChecksum.go    |    0
 ...COTPParameterDisconnectAdditionalInformation.go |    0
 .../s7/readwrite/model/COTPParameterTpduSize.go    |    0
 .../plc4go/s7/readwrite/model/COTPProtocolClass.go |    0
 .../plc4go/s7/readwrite/model/COTPTpduSize.go      |    0
 .../internal/plc4go/s7/readwrite/model/DataItem.go |  440 ++++++++
 .../s7/readwrite/model/DataTransportErrorCode.go   |    0
 .../plc4go/s7/readwrite/model/DataTransportSize.go |    0
 .../plc4go/s7/readwrite/model/DeviceGroup.go       |    0
 .../plc4go/s7/readwrite/model/MemoryArea.go        |    0
 .../plc4go/s7/readwrite/model/ParserHelper.go      |    0
 .../plc4go/s7/readwrite/model/S7Address.go         |    0
 .../plc4go/s7/readwrite/model/S7AddressAny.go      |    0
 .../plc4go/s7/readwrite/model/S7Message.go         |    0
 .../plc4go/s7/readwrite/model/S7MessageRequest.go  |    0
 .../plc4go/s7/readwrite/model/S7MessageResponse.go |    0
 .../s7/readwrite/model/S7MessageResponseData.go    |    0
 .../plc4go/s7/readwrite/model/S7MessageUserData.go |    0
 .../plc4go/s7/readwrite/model/S7Parameter.go       |    0
 .../readwrite/model/S7ParameterReadVarRequest.go   |    0
 .../readwrite/model/S7ParameterReadVarResponse.go  |    0
 .../model/S7ParameterSetupCommunication.go         |    0
 .../s7/readwrite/model/S7ParameterUserData.go      |    0
 .../s7/readwrite/model/S7ParameterUserDataItem.go  |    0
 .../model/S7ParameterUserDataItemCPUFunctions.go   |    0
 .../readwrite/model/S7ParameterWriteVarRequest.go  |    0
 .../readwrite/model/S7ParameterWriteVarResponse.go |    0
 .../plc4go/s7/readwrite/model/S7Payload.go         |    0
 .../s7/readwrite/model/S7PayloadReadVarResponse.go |    0
 .../plc4go/s7/readwrite/model/S7PayloadUserData.go |    0
 .../s7/readwrite/model/S7PayloadUserDataItem.go    |    0
 ...PayloadUserDataItemCpuFunctionReadSzlRequest.go |    0
 ...ayloadUserDataItemCpuFunctionReadSzlResponse.go |    0
 .../s7/readwrite/model/S7PayloadWriteVarRequest.go |    0
 .../readwrite/model/S7PayloadWriteVarResponse.go   |    0
 .../plc4go/s7/readwrite/model/S7StaticHelper.go    |    0
 .../s7/readwrite/model/S7VarPayloadDataItem.go     |    0
 .../s7/readwrite/model/S7VarPayloadStatusItem.go   |    0
 .../readwrite/model/S7VarRequestParameterItem.go   |    0
 .../model/S7VarRequestParameterItemAddress.go      |    0
 .../plc4go/s7/readwrite/model/SzlDataTreeItem.go   |    0
 .../internal/plc4go/s7/readwrite/model/SzlId.go    |    0
 .../s7/readwrite/model/SzlModuleTypeClass.go       |    0
 .../plc4go/s7/readwrite/model/SzlSublist.go        |    0
 .../plc4go/s7/readwrite/model/TPKTPacket.go        |    0
 .../plc4go/s7/readwrite/model/TransportSize.go     |  695 +++++++++++++
 .../plc4go/s7/readwrite/model/XmlParserHelper.go   |    0
 .../internal/plc4go/spi/HandlerExposer.go          |    0
 .../internal/plc4go/spi/Message.go                 |    0
 .../internal/plc4go/spi/MessageCodec.go            |    0
 .../internal/plc4go/spi/PlcFieldHandler.go         |    0
 .../internal/plc4go/spi/PlcReader.go               |    0
 .../internal/plc4go/spi/PlcValueHandler.go         |    0
 .../internal/plc4go/spi/PlcWriter.go               |    0
 .../plc4go/spi/TransportInstanceExposer.go         |    0
 .../interceptors/SingleItemRequestInterceptor.go   |    0
 .../internal/plc4go/testutils/DriverTestRunner.go  |    0
 .../plc4go/testutils/ParserSerializerTestRunner.go |    0
 .../internal/plc4go/testutils/TestUtils.go         |    0
 .../internal/plc4go/transports/Transport.go        |    0
 .../plc4go/transports/TransportInstance.go         |    0
 .../internal/plc4go/transports/tcp/TcpTransport.go |    0
 .../plc4go/transports/test/TestTransport.go        |    0
 .../internal/plc4go/utils/CastUtils.go             |    0
 .../internal/plc4go/utils/ParserHelper.go          |    0
 .../internal/plc4go/utils/ReadBuffer.go            |    0
 .../internal/plc4go/utils/Regexp.go                |    0
 .../internal/plc4go/utils/Serializable.go          |    0
 .../internal/plc4go/utils/Utils.go                 |    0
 .../internal/plc4go/utils/WriteBuffer.go           |    0
 .../plc4go => plc4go}/pkg/plc4go/connection.go     |    0
 {sandbox/plc4go => plc4go}/pkg/plc4go/driver.go    |    0
 .../plc4go => plc4go}/pkg/plc4go/driverManager.go  |    0
 .../pkg/plc4go/model/plc_connection_metadata.go    |    0
 .../pkg/plc4go/model/plc_field.go                  |    0
 .../pkg/plc4go/model/plc_message.go                |    0
 .../pkg/plc4go/model/plc_read_request.go           |    0
 .../pkg/plc4go/model/plc_read_response.go          |    0
 .../pkg/plc4go/model/plc_request.go                |    0
 .../pkg/plc4go/model/plc_response.go               |    0
 .../pkg/plc4go/model/plc_response_code.go          |    0
 .../pkg/plc4go/model/plc_subscription_event.go     |    0
 .../pkg/plc4go/model/plc_subscription_request.go   |    0
 .../pkg/plc4go/model/plc_subscription_response.go  |    0
 .../pkg/plc4go/model/plc_unsubscription_request.go |    0
 .../plc4go/model/plc_unsubscription_response.go    |    0
 .../pkg/plc4go/model/plc_write_request.go          |    0
 .../pkg/plc4go/model/plc_write_response.go         |    0
 .../pkg/plc4go/values/plc_value.go                 |    0
 {sandbox/plc4go => plc4go}/pom.xml                 |   13 +-
 .../java/modbus/config/ModbusConfiguration.java    |    2 +-
 .../java/modbus/protocol/ModbusProtocolLogic.java  |    8 +-
 .../apache/plc4x/java/spi/Plc4xNettyWrapper.java   |    6 +-
 .../spi/internal/DefaultExpectRequestContext.java  |    2 +-
 .../spi/internal/DefaultSendRequestContext.java    |    5 +-
 .../java/spi/internal/HandlerRegistration.java     |   13 +-
 .../plc4x/test/driver/DriverTestsuiteRunner.java   |    7 +-
 pom.xml                                            |    8 +
 .../plc4go/bacnetip/readwrite/model/APDUAbort.go   |  232 -----
 .../bacnetip/readwrite/model/APDUComplexAck.go     |  417 --------
 .../readwrite/model/APDUConfirmedRequest.go        |  597 -----------
 .../bacnetip/readwrite/model/APDUSegmentAck.go     |  284 -----
 .../BACnetConfirmedServiceRequestSubscribeCOV.go   |  401 -------
 .../plc4go/bacnetip/readwrite/model/NPDU.go        |  723 -------------
 .../CEMIAdditionalInformationBusmonitorInfo.go     |  306 ------
 .../knxnetip/readwrite/model/CEMIDataFrame.go      |  626 -----------
 .../plc4go/knxnetip/readwrite/model/CEMIFrame.go   |  309 ------
 .../knxnetip/readwrite/model/CEMIFrameData.go      |  469 ---------
 .../knxnetip/readwrite/model/CEMIFrameDataExt.go   |  495 ---------
 .../knxnetip/readwrite/model/DeviceStatus.go       |  167 ---
 .../knxnetip/readwrite/model/KnxDatapoint.go       | 1089 -------------------
 .../plc4go/modbus/readwrite/model/DataItem.go      |  646 ------------
 .../plc4go/modbus/readwrite/model/ModbusPDU.go     |  257 -----
 .../modbus/readwrite/model/ModbusPDUError.go       |  162 ---
 .../plc4go/s7/readwrite/model/COTPPacketData.go    |  182 ----
 .../internal/plc4go/s7/readwrite/model/DataItem.go |  439 --------
 .../plc4go/s7/readwrite/model/TransportSize.go     |  864 ----------------
 sandbox/pom.xml                                    |    8 -
 464 files changed, 8074 insertions(+), 8909 deletions(-)

diff --git a/sandbox/plc4go/assets/testing/protocols/knxnetip/ParserSerializerTestsuite.xml b/plc4go/assets/testing/protocols/knxnetip/ParserSerializerTestsuite.xml
similarity index 100%
rename from sandbox/plc4go/assets/testing/protocols/knxnetip/ParserSerializerTestsuite.xml
rename to plc4go/assets/testing/protocols/knxnetip/ParserSerializerTestsuite.xml
diff --git a/sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml b/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
similarity index 99%
rename from sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
rename to plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
index ec63d64..ed35a3f 100644
--- a/sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
+++ b/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
@@ -302,7 +302,7 @@
                   <numberOfElements>1</numberOfElements>
                   <dataType>IEC61131_REAL</dataType>
                 </ModbusFieldHoldingRegister>
-                <value>3.141593</value>
+                <value>3.1415927</value>
               </hurz>
             </fields>
           </PlcWriteRequest>
@@ -366,8 +366,8 @@
                   <numberOfElements>2</numberOfElements>
                   <dataType>IEC61131_REAL</dataType>
                 </ModbusFieldHoldingRegister>
-                <value>3.141593</value>
-                <value>3.141593</value>
+                <value>3.1415927</value>
+                <value>3.1415927</value>
               </hurz>
             </fields>
           </PlcWriteRequest>
diff --git a/sandbox/plc4go/assets/testing/protocols/modbus/ParserSerializerTestsuite.xml b/plc4go/assets/testing/protocols/modbus/ParserSerializerTestsuite.xml
similarity index 100%
rename from sandbox/plc4go/assets/testing/protocols/modbus/ParserSerializerTestsuite.xml
rename to plc4go/assets/testing/protocols/modbus/ParserSerializerTestsuite.xml
diff --git a/sandbox/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml b/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml
similarity index 100%
rename from sandbox/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml
rename to plc4go/assets/testing/protocols/s7/DriverTestsuite.xml
diff --git a/sandbox/plc4go/assets/testing/protocols/s7/ParserSerializerTestsuite.xml b/plc4go/assets/testing/protocols/s7/ParserSerializerTestsuite.xml
similarity index 100%
rename from sandbox/plc4go/assets/testing/protocols/s7/ParserSerializerTestsuite.xml
rename to plc4go/assets/testing/protocols/s7/ParserSerializerTestsuite.xml
diff --git a/sandbox/plc4go/cmd/main/drivers/bacnetip_test.go b/plc4go/cmd/main/drivers/bacnetip_test.go
similarity index 100%
rename from sandbox/plc4go/cmd/main/drivers/bacnetip_test.go
rename to plc4go/cmd/main/drivers/bacnetip_test.go
diff --git a/sandbox/plc4go/cmd/main/drivers/knxnetip_test.go b/plc4go/cmd/main/drivers/knxnetip_test.go
similarity index 100%
rename from sandbox/plc4go/cmd/main/drivers/knxnetip_test.go
rename to plc4go/cmd/main/drivers/knxnetip_test.go
diff --git a/sandbox/plc4go/cmd/main/drivers/modbus_test.go b/plc4go/cmd/main/drivers/modbus_test.go
similarity index 100%
rename from sandbox/plc4go/cmd/main/drivers/modbus_test.go
rename to plc4go/cmd/main/drivers/modbus_test.go
diff --git a/sandbox/plc4go/cmd/main/drivers/s7_test.go b/plc4go/cmd/main/drivers/s7_test.go
similarity index 100%
rename from sandbox/plc4go/cmd/main/drivers/s7_test.go
rename to plc4go/cmd/main/drivers/s7_test.go
diff --git a/sandbox/plc4go/cmd/main/drivers/tests/modbus_driver_test.go b/plc4go/cmd/main/drivers/tests/modbus_driver_test.go
similarity index 100%
rename from sandbox/plc4go/cmd/main/drivers/tests/modbus_driver_test.go
rename to plc4go/cmd/main/drivers/tests/modbus_driver_test.go
diff --git a/sandbox/plc4go/cmd/main/drivers/tests/modbus_parser_serializer_test.go b/plc4go/cmd/main/drivers/tests/modbus_parser_serializer_test.go
similarity index 100%
rename from sandbox/plc4go/cmd/main/drivers/tests/modbus_parser_serializer_test.go
rename to plc4go/cmd/main/drivers/tests/modbus_parser_serializer_test.go
diff --git a/sandbox/plc4go/cmd/main/main.go b/plc4go/cmd/main/main.go
similarity index 100%
rename from sandbox/plc4go/cmd/main/main.go
rename to plc4go/cmd/main/main.go
diff --git a/sandbox/plc4go/examples/read/hello_world_plc4go_read.go b/plc4go/examples/read/hello_world_plc4go_read.go
similarity index 100%
rename from sandbox/plc4go/examples/read/hello_world_plc4go_read.go
rename to plc4go/examples/read/hello_world_plc4go_read.go
diff --git a/sandbox/plc4go/examples/write/hello_world_plc4go_write.go b/plc4go/examples/write/hello_world_plc4go_write.go
similarity index 100%
rename from sandbox/plc4go/examples/write/hello_world_plc4go_write.go
rename to plc4go/examples/write/hello_world_plc4go_write.go
diff --git a/sandbox/plc4go/go.mod b/plc4go/go.mod
similarity index 100%
rename from sandbox/plc4go/go.mod
rename to plc4go/go.mod
diff --git a/sandbox/plc4go/go.sum b/plc4go/go.sum
similarity index 100%
rename from sandbox/plc4go/go.sum
rename to plc4go/go.sum
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/BacnetIpDriver.go b/plc4go/internal/plc4go/bacnetip/BacnetIpDriver.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/BacnetIpDriver.go
rename to plc4go/internal/plc4go/bacnetip/BacnetIpDriver.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDU.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDU.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDU.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/APDU.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUReject.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUAbort.go
similarity index 58%
copy from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUReject.go
copy to plc4go/internal/plc4go/bacnetip/readwrite/model/APDUAbort.go
index f2f099c..d884070 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUReject.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUAbort.go
@@ -28,78 +28,82 @@ import (
 )
 
 // The data-structure of this message
-type APDUReject struct {
+type APDUAbort struct {
+    Server bool
     OriginalInvokeId uint8
-    RejectReason uint8
+    AbortReason uint8
     APDU
 }
 
 // The corresponding interface
-type IAPDUReject interface {
+type IAPDUAbort interface {
     IAPDU
     Serialize(io utils.WriteBuffer) error
 }
 
 // Accessors for discriminator values.
-func (m APDUReject) ApduType() uint8 {
-    return 0x6
+func (m APDUAbort) ApduType() uint8 {
+    return 0x7
 }
 
-func (m APDUReject) initialize() spi.Message {
+func (m APDUAbort) initialize() spi.Message {
     return m
 }
 
-func NewAPDUReject(originalInvokeId uint8, rejectReason uint8) APDUInitializer {
-    return &APDUReject{OriginalInvokeId: originalInvokeId, RejectReason: rejectReason}
+func NewAPDUAbort(server bool, originalInvokeId uint8, abortReason uint8) APDUInitializer {
+    return &APDUAbort{Server: server, OriginalInvokeId: originalInvokeId, AbortReason: abortReason}
 }
 
-func CastIAPDUReject(structType interface{}) IAPDUReject {
-    castFunc := func(typ interface{}) IAPDUReject {
-        if iAPDUReject, ok := typ.(IAPDUReject); ok {
-            return iAPDUReject
+func CastIAPDUAbort(structType interface{}) IAPDUAbort {
+    castFunc := func(typ interface{}) IAPDUAbort {
+        if iAPDUAbort, ok := typ.(IAPDUAbort); ok {
+            return iAPDUAbort
         }
         return nil
     }
     return castFunc(structType)
 }
 
-func CastAPDUReject(structType interface{}) APDUReject {
-    castFunc := func(typ interface{}) APDUReject {
-        if sAPDUReject, ok := typ.(APDUReject); ok {
-            return sAPDUReject
+func CastAPDUAbort(structType interface{}) APDUAbort {
+    castFunc := func(typ interface{}) APDUAbort {
+        if sAPDUAbort, ok := typ.(APDUAbort); ok {
+            return sAPDUAbort
         }
-        if sAPDUReject, ok := typ.(*APDUReject); ok {
-            return *sAPDUReject
+        if sAPDUAbort, ok := typ.(*APDUAbort); ok {
+            return *sAPDUAbort
         }
-        return APDUReject{}
+        return APDUAbort{}
     }
     return castFunc(structType)
 }
 
-func (m APDUReject) LengthInBits() uint16 {
+func (m APDUAbort) LengthInBits() uint16 {
     var lengthInBits uint16 = m.APDU.LengthInBits()
 
     // Reserved Field (reserved)
-    lengthInBits += 4
+    lengthInBits += 3
+
+    // Simple field (server)
+    lengthInBits += 1
 
     // Simple field (originalInvokeId)
     lengthInBits += 8
 
-    // Simple field (rejectReason)
+    // Simple field (abortReason)
     lengthInBits += 8
 
     return lengthInBits
 }
 
-func (m APDUReject) LengthInBytes() uint16 {
+func (m APDUAbort) LengthInBytes() uint16 {
     return m.LengthInBits() / 8
 }
 
-func APDURejectParse(io *utils.ReadBuffer) (APDUInitializer, error) {
+func APDUAbortParse(io *utils.ReadBuffer) (APDUInitializer, error) {
 
     // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
     {
-        reserved, _err := io.ReadUint8(4)
+        reserved, _err := io.ReadUint8(3)
         if _err != nil {
             return nil, errors.New("Error parsing 'reserved' field " + _err.Error())
         }
@@ -111,33 +115,46 @@ func APDURejectParse(io *utils.ReadBuffer) (APDUInitializer, error) {
         }
     }
 
+    // Simple Field (server)
+    server, _serverErr := io.ReadBit()
+    if _serverErr != nil {
+        return nil, errors.New("Error parsing 'server' field " + _serverErr.Error())
+    }
+
     // Simple Field (originalInvokeId)
     originalInvokeId, _originalInvokeIdErr := io.ReadUint8(8)
     if _originalInvokeIdErr != nil {
         return nil, errors.New("Error parsing 'originalInvokeId' field " + _originalInvokeIdErr.Error())
     }
 
-    // Simple Field (rejectReason)
-    rejectReason, _rejectReasonErr := io.ReadUint8(8)
-    if _rejectReasonErr != nil {
-        return nil, errors.New("Error parsing 'rejectReason' field " + _rejectReasonErr.Error())
+    // Simple Field (abortReason)
+    abortReason, _abortReasonErr := io.ReadUint8(8)
+    if _abortReasonErr != nil {
+        return nil, errors.New("Error parsing 'abortReason' field " + _abortReasonErr.Error())
     }
 
     // Create the instance
-    return NewAPDUReject(originalInvokeId, rejectReason), nil
+    return NewAPDUAbort(server, originalInvokeId, abortReason), nil
 }
 
-func (m APDUReject) Serialize(io utils.WriteBuffer) error {
+func (m APDUAbort) Serialize(io utils.WriteBuffer) error {
     ser := func() error {
 
     // Reserved Field (reserved)
     {
-        _err := io.WriteUint8(4, uint8(0x00))
+        _err := io.WriteUint8(3, uint8(0x00))
         if _err != nil {
             return errors.New("Error serializing 'reserved' field " + _err.Error())
         }
     }
 
+    // Simple Field (server)
+    server := bool(m.Server)
+    _serverErr := io.WriteBit((server))
+    if _serverErr != nil {
+        return errors.New("Error serializing 'server' field " + _serverErr.Error())
+    }
+
     // Simple Field (originalInvokeId)
     originalInvokeId := uint8(m.OriginalInvokeId)
     _originalInvokeIdErr := io.WriteUint8(8, (originalInvokeId))
@@ -145,11 +162,11 @@ func (m APDUReject) Serialize(io utils.WriteBuffer) error {
         return errors.New("Error serializing 'originalInvokeId' field " + _originalInvokeIdErr.Error())
     }
 
-    // Simple Field (rejectReason)
-    rejectReason := uint8(m.RejectReason)
-    _rejectReasonErr := io.WriteUint8(8, (rejectReason))
-    if _rejectReasonErr != nil {
-        return errors.New("Error serializing 'rejectReason' field " + _rejectReasonErr.Error())
+    // Simple Field (abortReason)
+    abortReason := uint8(m.AbortReason)
+    _abortReasonErr := io.WriteUint8(8, (abortReason))
+    if _abortReasonErr != nil {
+        return errors.New("Error serializing 'abortReason' field " + _abortReasonErr.Error())
     }
 
         return nil
@@ -157,7 +174,7 @@ func (m APDUReject) Serialize(io utils.WriteBuffer) error {
     return APDUSerialize(io, m.APDU, CastIAPDU(m), ser)
 }
 
-func (m *APDUReject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+func (m *APDUAbort) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
     for {
         token, err := d.Token()
         if err != nil {
@@ -170,33 +187,42 @@ func (m *APDUReject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
         case xml.StartElement:
             tok := token.(xml.StartElement)
             switch tok.Name.Local {
+            case "server":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Server = data
             case "originalInvokeId":
                 var data uint8
                 if err := d.DecodeElement(&data, &tok); err != nil {
                     return err
                 }
                 m.OriginalInvokeId = data
-            case "rejectReason":
+            case "abortReason":
                 var data uint8
                 if err := d.DecodeElement(&data, &tok); err != nil {
                     return err
                 }
-                m.RejectReason = data
+                m.AbortReason = data
             }
         }
     }
 }
 
-func (m APDUReject) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+func (m APDUAbort) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
     if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
-            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.bacnetip.readwrite.APDUReject"},
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.bacnetip.readwrite.APDUAbort"},
         }}); err != nil {
         return err
     }
+    if err := e.EncodeElement(m.Server, xml.StartElement{Name: xml.Name{Local: "server"}}); err != nil {
+        return err
+    }
     if err := e.EncodeElement(m.OriginalInvokeId, xml.StartElement{Name: xml.Name{Local: "originalInvokeId"}}); err != nil {
         return err
     }
-    if err := e.EncodeElement(m.RejectReason, xml.StartElement{Name: xml.Name{Local: "rejectReason"}}); err != nil {
+    if err := e.EncodeElement(m.AbortReason, xml.StartElement{Name: xml.Name{Local: "abortReason"}}); err != nil {
         return err
     }
     if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUComplexAck.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUComplexAck.go
new file mode 100644
index 0000000..c4bc080
--- /dev/null
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUComplexAck.go
@@ -0,0 +1,418 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    log "github.com/sirupsen/logrus"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    "reflect"
+)
+
+// The data-structure of this message
+type APDUComplexAck struct {
+    SegmentedMessage bool
+    MoreFollows bool
+    OriginalInvokeId uint8
+    SequenceNumber *uint8
+    ProposedWindowSize *uint8
+    ServiceAck IBACnetServiceAck
+    APDU
+}
+
+// The corresponding interface
+type IAPDUComplexAck interface {
+    IAPDU
+    Serialize(io utils.WriteBuffer) error
+}
+
+// Accessors for discriminator values.
+func (m APDUComplexAck) ApduType() uint8 {
+    return 0x3
+}
+
+func (m APDUComplexAck) initialize() spi.Message {
+    return m
+}
+
+func NewAPDUComplexAck(segmentedMessage bool, moreFollows bool, originalInvokeId uint8, sequenceNumber *uint8, proposedWindowSize *uint8, serviceAck IBACnetServiceAck) APDUInitializer {
+    return &APDUComplexAck{SegmentedMessage: segmentedMessage, MoreFollows: moreFollows, OriginalInvokeId: originalInvokeId, SequenceNumber: sequenceNumber, ProposedWindowSize: proposedWindowSize, ServiceAck: serviceAck}
+}
+
+func CastIAPDUComplexAck(structType interface{}) IAPDUComplexAck {
+    castFunc := func(typ interface{}) IAPDUComplexAck {
+        if iAPDUComplexAck, ok := typ.(IAPDUComplexAck); ok {
+            return iAPDUComplexAck
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastAPDUComplexAck(structType interface{}) APDUComplexAck {
+    castFunc := func(typ interface{}) APDUComplexAck {
+        if sAPDUComplexAck, ok := typ.(APDUComplexAck); ok {
+            return sAPDUComplexAck
+        }
+        if sAPDUComplexAck, ok := typ.(*APDUComplexAck); ok {
+            return *sAPDUComplexAck
+        }
+        return APDUComplexAck{}
+    }
+    return castFunc(structType)
+}
+
+func (m APDUComplexAck) LengthInBits() uint16 {
+    var lengthInBits uint16 = m.APDU.LengthInBits()
+
+    // Simple field (segmentedMessage)
+    lengthInBits += 1
+
+    // Simple field (moreFollows)
+    lengthInBits += 1
+
+    // Reserved Field (reserved)
+    lengthInBits += 2
+
+    // Simple field (originalInvokeId)
+    lengthInBits += 8
+
+    // Optional Field (sequenceNumber)
+    if m.SequenceNumber != nil {
+        lengthInBits += 8
+    }
+
+    // Optional Field (proposedWindowSize)
+    if m.ProposedWindowSize != nil {
+        lengthInBits += 8
+    }
+
+    // Simple field (serviceAck)
+    lengthInBits += m.ServiceAck.LengthInBits()
+
+    return lengthInBits
+}
+
+func (m APDUComplexAck) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func APDUComplexAckParse(io *utils.ReadBuffer) (APDUInitializer, error) {
+
+    // Simple Field (segmentedMessage)
+    segmentedMessage, _segmentedMessageErr := io.ReadBit()
+    if _segmentedMessageErr != nil {
+        return nil, errors.New("Error parsing 'segmentedMessage' field " + _segmentedMessageErr.Error())
+    }
+
+    // Simple Field (moreFollows)
+    moreFollows, _moreFollowsErr := io.ReadBit()
+    if _moreFollowsErr != nil {
+        return nil, errors.New("Error parsing 'moreFollows' field " + _moreFollowsErr.Error())
+    }
+
+    // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+    {
+        reserved, _err := io.ReadUint8(2)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'reserved' field " + _err.Error())
+        }
+        if reserved != uint8(0) {
+            log.WithFields(log.Fields{
+                "expected value": uint8(0),
+                "got value": reserved,
+            }).Info("Got unexpected response.")
+        }
+    }
+
+    // Simple Field (originalInvokeId)
+    originalInvokeId, _originalInvokeIdErr := io.ReadUint8(8)
+    if _originalInvokeIdErr != nil {
+        return nil, errors.New("Error parsing 'originalInvokeId' field " + _originalInvokeIdErr.Error())
+    }
+
+    // Optional Field (sequenceNumber) (Can be skipped, if a given expression evaluates to false)
+    var sequenceNumber *uint8 = nil
+    if segmentedMessage {
+        _val, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'sequenceNumber' field " + _err.Error())
+        }
+
+        sequenceNumber = &_val
+    }
+
+    // Optional Field (proposedWindowSize) (Can be skipped, if a given expression evaluates to false)
+    var proposedWindowSize *uint8 = nil
+    if segmentedMessage {
+        _val, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'proposedWindowSize' field " + _err.Error())
+        }
+
+        proposedWindowSize = &_val
+    }
+
+    // Simple Field (serviceAck)
+    _serviceAckMessage, _err := BACnetServiceAckParse(io)
+    if _err != nil {
+        return nil, errors.New("Error parsing simple field 'serviceAck'. " + _err.Error())
+    }
+    var serviceAck IBACnetServiceAck
+    serviceAck, _serviceAckOk := _serviceAckMessage.(IBACnetServiceAck)
+    if !_serviceAckOk {
+        return nil, errors.New("Couldn't cast message of type " + reflect.TypeOf(_serviceAckMessage).Name() + " to IBACnetServiceAck")
+    }
+
+    // Create the instance
+    return NewAPDUComplexAck(segmentedMessage, moreFollows, originalInvokeId, sequenceNumber, proposedWindowSize, serviceAck), nil
+}
+
+func (m APDUComplexAck) Serialize(io utils.WriteBuffer) error {
+    ser := func() error {
+
+    // Simple Field (segmentedMessage)
+    segmentedMessage := bool(m.SegmentedMessage)
+    _segmentedMessageErr := io.WriteBit((segmentedMessage))
+    if _segmentedMessageErr != nil {
+        return errors.New("Error serializing 'segmentedMessage' field " + _segmentedMessageErr.Error())
+    }
+
+    // Simple Field (moreFollows)
+    moreFollows := bool(m.MoreFollows)
+    _moreFollowsErr := io.WriteBit((moreFollows))
+    if _moreFollowsErr != nil {
+        return errors.New("Error serializing 'moreFollows' field " + _moreFollowsErr.Error())
+    }
+
+    // Reserved Field (reserved)
+    {
+        _err := io.WriteUint8(2, uint8(0))
+        if _err != nil {
+            return errors.New("Error serializing 'reserved' field " + _err.Error())
+        }
+    }
+
+    // Simple Field (originalInvokeId)
+    originalInvokeId := uint8(m.OriginalInvokeId)
+    _originalInvokeIdErr := io.WriteUint8(8, (originalInvokeId))
+    if _originalInvokeIdErr != nil {
+        return errors.New("Error serializing 'originalInvokeId' field " + _originalInvokeIdErr.Error())
+    }
+
+    // Optional Field (sequenceNumber) (Can be skipped, if the value is null)
+    var sequenceNumber *uint8 = nil
+    if m.SequenceNumber != nil {
+        sequenceNumber = m.SequenceNumber
+        _sequenceNumberErr := io.WriteUint8(8, *(sequenceNumber))
+        if _sequenceNumberErr != nil {
+            return errors.New("Error serializing 'sequenceNumber' field " + _sequenceNumberErr.Error())
+        }
+    }
+
+    // Optional Field (proposedWindowSize) (Can be skipped, if the value is null)
+    var proposedWindowSize *uint8 = nil
+    if m.ProposedWindowSize != nil {
+        proposedWindowSize = m.ProposedWindowSize
+        _proposedWindowSizeErr := io.WriteUint8(8, *(proposedWindowSize))
+        if _proposedWindowSizeErr != nil {
+            return errors.New("Error serializing 'proposedWindowSize' field " + _proposedWindowSizeErr.Error())
+        }
+    }
+
+    // Simple Field (serviceAck)
+    serviceAck := CastIBACnetServiceAck(m.ServiceAck)
+    _serviceAckErr := serviceAck.Serialize(io)
+    if _serviceAckErr != nil {
+        return errors.New("Error serializing 'serviceAck' field " + _serviceAckErr.Error())
+    }
+
+        return nil
+    }
+    return APDUSerialize(io, m.APDU, CastIAPDU(m), ser)
+}
+
+func (m *APDUComplexAck) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "segmentedMessage":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SegmentedMessage = data
+            case "moreFollows":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.MoreFollows = data
+            case "originalInvokeId":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.OriginalInvokeId = data
+            case "sequenceNumber":
+                var data *uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SequenceNumber = data
+            case "proposedWindowSize":
+                var data *uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ProposedWindowSize = data
+            case "serviceAck":
+                switch tok.Attr[0].Value {
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckGetAlarmSummary":
+                        var dt *BACnetServiceAckGetAlarmSummary
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckGetEnrollmentSummary":
+                        var dt *BACnetServiceAckGetEnrollmentSummary
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckGetEventInformation":
+                        var dt *BACnetServiceAckGetEventInformation
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckAtomicReadFile":
+                        var dt *BACnetServiceAckAtomicReadFile
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckAtomicWriteFile":
+                        var dt *BACnetServiceAckAtomicWriteFile
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckCreateObject":
+                        var dt *BACnetServiceAckCreateObject
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckReadProperty":
+                        var dt *BACnetServiceAckReadProperty
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckReadPropertyMultiple":
+                        var dt *BACnetServiceAckReadPropertyMultiple
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckReadRange":
+                        var dt *BACnetServiceAckReadRange
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckConfirmedPrivateTransfer":
+                        var dt *BACnetServiceAckConfirmedPrivateTransfer
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckVTOpen":
+                        var dt *BACnetServiceAckVTOpen
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckVTData":
+                        var dt *BACnetServiceAckVTData
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckRemovedAuthenticate":
+                        var dt *BACnetServiceAckRemovedAuthenticate
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetServiceAckRemovedReadPropertyConditional":
+                        var dt *BACnetServiceAckRemovedReadPropertyConditional
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceAck = dt
+                    }
+            }
+        }
+    }
+}
+
+func (m APDUComplexAck) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.bacnetip.readwrite.APDUComplexAck"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SegmentedMessage, xml.StartElement{Name: xml.Name{Local: "segmentedMessage"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.MoreFollows, xml.StartElement{Name: xml.Name{Local: "moreFollows"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.OriginalInvokeId, xml.StartElement{Name: xml.Name{Local: "originalInvokeId"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SequenceNumber, xml.StartElement{Name: xml.Name{Local: "sequenceNumber"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ProposedWindowSize, xml.StartElement{Name: xml.Name{Local: "proposedWindowSize"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ServiceAck, xml.StartElement{Name: xml.Name{Local: "serviceAck"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUConfirmedRequest.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUConfirmedRequest.go
new file mode 100644
index 0000000..33c4055
--- /dev/null
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUConfirmedRequest.go
@@ -0,0 +1,598 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    log "github.com/sirupsen/logrus"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    "reflect"
+)
+
+// The data-structure of this message
+type APDUConfirmedRequest struct {
+    SegmentedMessage bool
+    MoreFollows bool
+    SegmentedResponseAccepted bool
+    MaxSegmentsAccepted uint8
+    MaxApduLengthAccepted uint8
+    InvokeId uint8
+    SequenceNumber *uint8
+    ProposedWindowSize *uint8
+    ServiceRequest IBACnetConfirmedServiceRequest
+    APDU
+}
+
+// The corresponding interface
+type IAPDUConfirmedRequest interface {
+    IAPDU
+    Serialize(io utils.WriteBuffer) error
+}
+
+// Accessors for discriminator values.
+func (m APDUConfirmedRequest) ApduType() uint8 {
+    return 0x0
+}
+
+func (m APDUConfirmedRequest) initialize() spi.Message {
+    return m
+}
+
+func NewAPDUConfirmedRequest(segmentedMessage bool, moreFollows bool, segmentedResponseAccepted bool, maxSegmentsAccepted uint8, maxApduLengthAccepted uint8, invokeId uint8, sequenceNumber *uint8, proposedWindowSize *uint8, serviceRequest IBACnetConfirmedServiceRequest) APDUInitializer {
+    return &APDUConfirmedRequest{SegmentedMessage: segmentedMessage, MoreFollows: moreFollows, SegmentedResponseAccepted: segmentedResponseAccepted, MaxSegmentsAccepted: maxSegmentsAccepted, MaxApduLengthAccepted: maxApduLengthAccepted, InvokeId: invokeId, SequenceNumber: sequenceNumber, ProposedWindowSize: proposedWindowSize, ServiceRequest: serviceRequest}
+}
+
+func CastIAPDUConfirmedRequest(structType interface{}) IAPDUConfirmedRequest {
+    castFunc := func(typ interface{}) IAPDUConfirmedRequest {
+        if iAPDUConfirmedRequest, ok := typ.(IAPDUConfirmedRequest); ok {
+            return iAPDUConfirmedRequest
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastAPDUConfirmedRequest(structType interface{}) APDUConfirmedRequest {
+    castFunc := func(typ interface{}) APDUConfirmedRequest {
+        if sAPDUConfirmedRequest, ok := typ.(APDUConfirmedRequest); ok {
+            return sAPDUConfirmedRequest
+        }
+        if sAPDUConfirmedRequest, ok := typ.(*APDUConfirmedRequest); ok {
+            return *sAPDUConfirmedRequest
+        }
+        return APDUConfirmedRequest{}
+    }
+    return castFunc(structType)
+}
+
+func (m APDUConfirmedRequest) LengthInBits() uint16 {
+    var lengthInBits uint16 = m.APDU.LengthInBits()
+
+    // Simple field (segmentedMessage)
+    lengthInBits += 1
+
+    // Simple field (moreFollows)
+    lengthInBits += 1
+
+    // Simple field (segmentedResponseAccepted)
+    lengthInBits += 1
+
+    // Reserved Field (reserved)
+    lengthInBits += 2
+
+    // Simple field (maxSegmentsAccepted)
+    lengthInBits += 3
+
+    // Simple field (maxApduLengthAccepted)
+    lengthInBits += 4
+
+    // Simple field (invokeId)
+    lengthInBits += 8
+
+    // Optional Field (sequenceNumber)
+    if m.SequenceNumber != nil {
+        lengthInBits += 8
+    }
+
+    // Optional Field (proposedWindowSize)
+    if m.ProposedWindowSize != nil {
+        lengthInBits += 8
+    }
+
+    // Simple field (serviceRequest)
+    lengthInBits += m.ServiceRequest.LengthInBits()
+
+    return lengthInBits
+}
+
+func (m APDUConfirmedRequest) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func APDUConfirmedRequestParse(io *utils.ReadBuffer, apduLength uint16) (APDUInitializer, error) {
+
+    // Simple Field (segmentedMessage)
+    segmentedMessage, _segmentedMessageErr := io.ReadBit()
+    if _segmentedMessageErr != nil {
+        return nil, errors.New("Error parsing 'segmentedMessage' field " + _segmentedMessageErr.Error())
+    }
+
+    // Simple Field (moreFollows)
+    moreFollows, _moreFollowsErr := io.ReadBit()
+    if _moreFollowsErr != nil {
+        return nil, errors.New("Error parsing 'moreFollows' field " + _moreFollowsErr.Error())
+    }
+
+    // Simple Field (segmentedResponseAccepted)
+    segmentedResponseAccepted, _segmentedResponseAcceptedErr := io.ReadBit()
+    if _segmentedResponseAcceptedErr != nil {
+        return nil, errors.New("Error parsing 'segmentedResponseAccepted' field " + _segmentedResponseAcceptedErr.Error())
+    }
+
+    // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+    {
+        reserved, _err := io.ReadUint8(2)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'reserved' field " + _err.Error())
+        }
+        if reserved != uint8(0) {
+            log.WithFields(log.Fields{
+                "expected value": uint8(0),
+                "got value": reserved,
+            }).Info("Got unexpected response.")
+        }
+    }
+
+    // Simple Field (maxSegmentsAccepted)
+    maxSegmentsAccepted, _maxSegmentsAcceptedErr := io.ReadUint8(3)
+    if _maxSegmentsAcceptedErr != nil {
+        return nil, errors.New("Error parsing 'maxSegmentsAccepted' field " + _maxSegmentsAcceptedErr.Error())
+    }
+
+    // Simple Field (maxApduLengthAccepted)
+    maxApduLengthAccepted, _maxApduLengthAcceptedErr := io.ReadUint8(4)
+    if _maxApduLengthAcceptedErr != nil {
+        return nil, errors.New("Error parsing 'maxApduLengthAccepted' field " + _maxApduLengthAcceptedErr.Error())
+    }
+
+    // Simple Field (invokeId)
+    invokeId, _invokeIdErr := io.ReadUint8(8)
+    if _invokeIdErr != nil {
+        return nil, errors.New("Error parsing 'invokeId' field " + _invokeIdErr.Error())
+    }
+
+    // Optional Field (sequenceNumber) (Can be skipped, if a given expression evaluates to false)
+    var sequenceNumber *uint8 = nil
+    if segmentedMessage {
+        _val, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'sequenceNumber' field " + _err.Error())
+        }
+
+        sequenceNumber = &_val
+    }
+
+    // Optional Field (proposedWindowSize) (Can be skipped, if a given expression evaluates to false)
+    var proposedWindowSize *uint8 = nil
+    if segmentedMessage {
+        _val, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'proposedWindowSize' field " + _err.Error())
+        }
+
+        proposedWindowSize = &_val
+    }
+
+    // Simple Field (serviceRequest)
+    _serviceRequestMessage, _err := BACnetConfirmedServiceRequestParse(io, uint16(apduLength) - uint16(uint16(uint16(uint16(3)) + uint16(uint16(utils.InlineIf(segmentedMessage, uint16(uint16(2)), uint16(uint16(0))))))))
+    if _err != nil {
+        return nil, errors.New("Error parsing simple field 'serviceRequest'. " + _err.Error())
+    }
+    var serviceRequest IBACnetConfirmedServiceRequest
+    serviceRequest, _serviceRequestOk := _serviceRequestMessage.(IBACnetConfirmedServiceRequest)
+    if !_serviceRequestOk {
+        return nil, errors.New("Couldn't cast message of type " + reflect.TypeOf(_serviceRequestMessage).Name() + " to IBACnetConfirmedServiceRequest")
+    }
+
+    // Create the instance
+    return NewAPDUConfirmedRequest(segmentedMessage, moreFollows, segmentedResponseAccepted, maxSegmentsAccepted, maxApduLengthAccepted, invokeId, sequenceNumber, proposedWindowSize, serviceRequest), nil
+}
+
+func (m APDUConfirmedRequest) Serialize(io utils.WriteBuffer) error {
+    ser := func() error {
+
+    // Simple Field (segmentedMessage)
+    segmentedMessage := bool(m.SegmentedMessage)
+    _segmentedMessageErr := io.WriteBit((segmentedMessage))
+    if _segmentedMessageErr != nil {
+        return errors.New("Error serializing 'segmentedMessage' field " + _segmentedMessageErr.Error())
+    }
+
+    // Simple Field (moreFollows)
+    moreFollows := bool(m.MoreFollows)
+    _moreFollowsErr := io.WriteBit((moreFollows))
+    if _moreFollowsErr != nil {
+        return errors.New("Error serializing 'moreFollows' field " + _moreFollowsErr.Error())
+    }
+
+    // Simple Field (segmentedResponseAccepted)
+    segmentedResponseAccepted := bool(m.SegmentedResponseAccepted)
+    _segmentedResponseAcceptedErr := io.WriteBit((segmentedResponseAccepted))
+    if _segmentedResponseAcceptedErr != nil {
+        return errors.New("Error serializing 'segmentedResponseAccepted' field " + _segmentedResponseAcceptedErr.Error())
+    }
+
+    // Reserved Field (reserved)
+    {
+        _err := io.WriteUint8(2, uint8(0))
+        if _err != nil {
+            return errors.New("Error serializing 'reserved' field " + _err.Error())
+        }
+    }
+
+    // Simple Field (maxSegmentsAccepted)
+    maxSegmentsAccepted := uint8(m.MaxSegmentsAccepted)
+    _maxSegmentsAcceptedErr := io.WriteUint8(3, (maxSegmentsAccepted))
+    if _maxSegmentsAcceptedErr != nil {
+        return errors.New("Error serializing 'maxSegmentsAccepted' field " + _maxSegmentsAcceptedErr.Error())
+    }
+
+    // Simple Field (maxApduLengthAccepted)
+    maxApduLengthAccepted := uint8(m.MaxApduLengthAccepted)
+    _maxApduLengthAcceptedErr := io.WriteUint8(4, (maxApduLengthAccepted))
+    if _maxApduLengthAcceptedErr != nil {
+        return errors.New("Error serializing 'maxApduLengthAccepted' field " + _maxApduLengthAcceptedErr.Error())
+    }
+
+    // Simple Field (invokeId)
+    invokeId := uint8(m.InvokeId)
+    _invokeIdErr := io.WriteUint8(8, (invokeId))
+    if _invokeIdErr != nil {
+        return errors.New("Error serializing 'invokeId' field " + _invokeIdErr.Error())
+    }
+
+    // Optional Field (sequenceNumber) (Can be skipped, if the value is null)
+    var sequenceNumber *uint8 = nil
+    if m.SequenceNumber != nil {
+        sequenceNumber = m.SequenceNumber
+        _sequenceNumberErr := io.WriteUint8(8, *(sequenceNumber))
+        if _sequenceNumberErr != nil {
+            return errors.New("Error serializing 'sequenceNumber' field " + _sequenceNumberErr.Error())
+        }
+    }
+
+    // Optional Field (proposedWindowSize) (Can be skipped, if the value is null)
+    var proposedWindowSize *uint8 = nil
+    if m.ProposedWindowSize != nil {
+        proposedWindowSize = m.ProposedWindowSize
+        _proposedWindowSizeErr := io.WriteUint8(8, *(proposedWindowSize))
+        if _proposedWindowSizeErr != nil {
+            return errors.New("Error serializing 'proposedWindowSize' field " + _proposedWindowSizeErr.Error())
+        }
+    }
+
+    // Simple Field (serviceRequest)
+    serviceRequest := CastIBACnetConfirmedServiceRequest(m.ServiceRequest)
+    _serviceRequestErr := serviceRequest.Serialize(io)
+    if _serviceRequestErr != nil {
+        return errors.New("Error serializing 'serviceRequest' field " + _serviceRequestErr.Error())
+    }
+
+        return nil
+    }
+    return APDUSerialize(io, m.APDU, CastIAPDU(m), ser)
+}
+
+func (m *APDUConfirmedRequest) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "segmentedMessage":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SegmentedMessage = data
+            case "moreFollows":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.MoreFollows = data
+            case "segmentedResponseAccepted":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SegmentedResponseAccepted = data
+            case "maxSegmentsAccepted":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.MaxSegmentsAccepted = data
+            case "maxApduLengthAccepted":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.MaxApduLengthAccepted = data
+            case "invokeId":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.InvokeId = data
+            case "sequenceNumber":
+                var data *uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SequenceNumber = data
+            case "proposedWindowSize":
+                var data *uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ProposedWindowSize = data
+            case "serviceRequest":
+                switch tok.Attr[0].Value {
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestAcknowledgeAlarm":
+                        var dt *BACnetConfirmedServiceRequestAcknowledgeAlarm
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestConfirmedCOVNotification":
+                        var dt *BACnetConfirmedServiceRequestConfirmedCOVNotification
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestConfirmedEventNotification":
+                        var dt *BACnetConfirmedServiceRequestConfirmedEventNotification
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestGetEnrollmentSummary":
+                        var dt *BACnetConfirmedServiceRequestGetEnrollmentSummary
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestSubscribeCOV":
+                        var dt *BACnetConfirmedServiceRequestSubscribeCOV
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestAtomicReadFile":
+                        var dt *BACnetConfirmedServiceRequestAtomicReadFile
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestAtomicWriteFile":
+                        var dt *BACnetConfirmedServiceRequestAtomicWriteFile
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestAddListElement":
+                        var dt *BACnetConfirmedServiceRequestAddListElement
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestRemoveListElement":
+                        var dt *BACnetConfirmedServiceRequestRemoveListElement
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestCreateObject":
+                        var dt *BACnetConfirmedServiceRequestCreateObject
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestDeleteObject":
+                        var dt *BACnetConfirmedServiceRequestDeleteObject
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestReadProperty":
+                        var dt *BACnetConfirmedServiceRequestReadProperty
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestReadPropertyMultiple":
+                        var dt *BACnetConfirmedServiceRequestReadPropertyMultiple
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestWriteProperty":
+                        var dt *BACnetConfirmedServiceRequestWriteProperty
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestWritePropertyMultiple":
+                        var dt *BACnetConfirmedServiceRequestWritePropertyMultiple
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestDeviceCommunicationControl":
+                        var dt *BACnetConfirmedServiceRequestDeviceCommunicationControl
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestConfirmedPrivateTransfer":
+                        var dt *BACnetConfirmedServiceRequestConfirmedPrivateTransfer
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestConfirmedTextMessage":
+                        var dt *BACnetConfirmedServiceRequestConfirmedTextMessage
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestReinitializeDevice":
+                        var dt *BACnetConfirmedServiceRequestReinitializeDevice
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestVTOpen":
+                        var dt *BACnetConfirmedServiceRequestVTOpen
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestVTClose":
+                        var dt *BACnetConfirmedServiceRequestVTClose
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestVTData":
+                        var dt *BACnetConfirmedServiceRequestVTData
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestRemovedAuthenticate":
+                        var dt *BACnetConfirmedServiceRequestRemovedAuthenticate
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestRemovedRequestKey":
+                        var dt *BACnetConfirmedServiceRequestRemovedRequestKey
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestRemovedReadPropertyConditional":
+                        var dt *BACnetConfirmedServiceRequestRemovedReadPropertyConditional
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestReadRange":
+                        var dt *BACnetConfirmedServiceRequestReadRange
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestLifeSafetyOperation":
+                        var dt *BACnetConfirmedServiceRequestLifeSafetyOperation
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestSubscribeCOVProperty":
+                        var dt *BACnetConfirmedServiceRequestSubscribeCOVProperty
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestGetEventInformation":
+                        var dt *BACnetConfirmedServiceRequestGetEventInformation
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestSubscribeCOVPropertyMultiple":
+                        var dt *BACnetConfirmedServiceRequestSubscribeCOVPropertyMultiple
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestConfirmedCOVNotificationMultiple":
+                        var dt *BACnetConfirmedServiceRequestConfirmedCOVNotificationMultiple
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        m.ServiceRequest = dt
+                    }
+            }
+        }
+    }
+}
+
+func (m APDUConfirmedRequest) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.bacnetip.readwrite.APDUConfirmedRequest"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SegmentedMessage, xml.StartElement{Name: xml.Name{Local: "segmentedMessage"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.MoreFollows, xml.StartElement{Name: xml.Name{Local: "moreFollows"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SegmentedResponseAccepted, xml.StartElement{Name: xml.Name{Local: "segmentedResponseAccepted"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.MaxSegmentsAccepted, xml.StartElement{Name: xml.Name{Local: "maxSegmentsAccepted"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.MaxApduLengthAccepted, xml.StartElement{Name: xml.Name{Local: "maxApduLengthAccepted"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.InvokeId, xml.StartElement{Name: xml.Name{Local: "invokeId"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SequenceNumber, xml.StartElement{Name: xml.Name{Local: "sequenceNumber"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ProposedWindowSize, xml.StartElement{Name: xml.Name{Local: "proposedWindowSize"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ServiceRequest, xml.StartElement{Name: xml.Name{Local: "serviceRequest"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUError.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUError.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUError.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/APDUError.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUReject.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUReject.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUReject.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/APDUReject.go
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUSegmentAck.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUSegmentAck.go
new file mode 100644
index 0000000..7fd0c91
--- /dev/null
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUSegmentAck.go
@@ -0,0 +1,285 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    log "github.com/sirupsen/logrus"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+// The data-structure of this message
+type APDUSegmentAck struct {
+    NegativeAck bool
+    Server bool
+    OriginalInvokeId uint8
+    SequenceNumber uint8
+    ProposedWindowSize uint8
+    APDU
+}
+
+// The corresponding interface
+type IAPDUSegmentAck interface {
+    IAPDU
+    Serialize(io utils.WriteBuffer) error
+}
+
+// Accessors for discriminator values.
+func (m APDUSegmentAck) ApduType() uint8 {
+    return 0x4
+}
+
+func (m APDUSegmentAck) initialize() spi.Message {
+    return m
+}
+
+func NewAPDUSegmentAck(negativeAck bool, server bool, originalInvokeId uint8, sequenceNumber uint8, proposedWindowSize uint8) APDUInitializer {
+    return &APDUSegmentAck{NegativeAck: negativeAck, Server: server, OriginalInvokeId: originalInvokeId, SequenceNumber: sequenceNumber, ProposedWindowSize: proposedWindowSize}
+}
+
+func CastIAPDUSegmentAck(structType interface{}) IAPDUSegmentAck {
+    castFunc := func(typ interface{}) IAPDUSegmentAck {
+        if iAPDUSegmentAck, ok := typ.(IAPDUSegmentAck); ok {
+            return iAPDUSegmentAck
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastAPDUSegmentAck(structType interface{}) APDUSegmentAck {
+    castFunc := func(typ interface{}) APDUSegmentAck {
+        if sAPDUSegmentAck, ok := typ.(APDUSegmentAck); ok {
+            return sAPDUSegmentAck
+        }
+        if sAPDUSegmentAck, ok := typ.(*APDUSegmentAck); ok {
+            return *sAPDUSegmentAck
+        }
+        return APDUSegmentAck{}
+    }
+    return castFunc(structType)
+}
+
+func (m APDUSegmentAck) LengthInBits() uint16 {
+    var lengthInBits uint16 = m.APDU.LengthInBits()
+
+    // Reserved Field (reserved)
+    lengthInBits += 2
+
+    // Simple field (negativeAck)
+    lengthInBits += 1
+
+    // Simple field (server)
+    lengthInBits += 1
+
+    // Simple field (originalInvokeId)
+    lengthInBits += 8
+
+    // Simple field (sequenceNumber)
+    lengthInBits += 8
+
+    // Simple field (proposedWindowSize)
+    lengthInBits += 8
+
+    return lengthInBits
+}
+
+func (m APDUSegmentAck) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func APDUSegmentAckParse(io *utils.ReadBuffer) (APDUInitializer, error) {
+
+    // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+    {
+        reserved, _err := io.ReadUint8(2)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'reserved' field " + _err.Error())
+        }
+        if reserved != uint8(0x00) {
+            log.WithFields(log.Fields{
+                "expected value": uint8(0x00),
+                "got value": reserved,
+            }).Info("Got unexpected response.")
+        }
+    }
+
+    // Simple Field (negativeAck)
+    negativeAck, _negativeAckErr := io.ReadBit()
+    if _negativeAckErr != nil {
+        return nil, errors.New("Error parsing 'negativeAck' field " + _negativeAckErr.Error())
+    }
+
+    // Simple Field (server)
+    server, _serverErr := io.ReadBit()
+    if _serverErr != nil {
+        return nil, errors.New("Error parsing 'server' field " + _serverErr.Error())
+    }
+
+    // Simple Field (originalInvokeId)
+    originalInvokeId, _originalInvokeIdErr := io.ReadUint8(8)
+    if _originalInvokeIdErr != nil {
+        return nil, errors.New("Error parsing 'originalInvokeId' field " + _originalInvokeIdErr.Error())
+    }
+
+    // Simple Field (sequenceNumber)
+    sequenceNumber, _sequenceNumberErr := io.ReadUint8(8)
+    if _sequenceNumberErr != nil {
+        return nil, errors.New("Error parsing 'sequenceNumber' field " + _sequenceNumberErr.Error())
+    }
+
+    // Simple Field (proposedWindowSize)
+    proposedWindowSize, _proposedWindowSizeErr := io.ReadUint8(8)
+    if _proposedWindowSizeErr != nil {
+        return nil, errors.New("Error parsing 'proposedWindowSize' field " + _proposedWindowSizeErr.Error())
+    }
+
+    // Create the instance
+    return NewAPDUSegmentAck(negativeAck, server, originalInvokeId, sequenceNumber, proposedWindowSize), nil
+}
+
+func (m APDUSegmentAck) Serialize(io utils.WriteBuffer) error {
+    ser := func() error {
+
+    // Reserved Field (reserved)
+    {
+        _err := io.WriteUint8(2, uint8(0x00))
+        if _err != nil {
+            return errors.New("Error serializing 'reserved' field " + _err.Error())
+        }
+    }
+
+    // Simple Field (negativeAck)
+    negativeAck := bool(m.NegativeAck)
+    _negativeAckErr := io.WriteBit((negativeAck))
+    if _negativeAckErr != nil {
+        return errors.New("Error serializing 'negativeAck' field " + _negativeAckErr.Error())
+    }
+
+    // Simple Field (server)
+    server := bool(m.Server)
+    _serverErr := io.WriteBit((server))
+    if _serverErr != nil {
+        return errors.New("Error serializing 'server' field " + _serverErr.Error())
+    }
+
+    // Simple Field (originalInvokeId)
+    originalInvokeId := uint8(m.OriginalInvokeId)
+    _originalInvokeIdErr := io.WriteUint8(8, (originalInvokeId))
+    if _originalInvokeIdErr != nil {
+        return errors.New("Error serializing 'originalInvokeId' field " + _originalInvokeIdErr.Error())
+    }
+
+    // Simple Field (sequenceNumber)
+    sequenceNumber := uint8(m.SequenceNumber)
+    _sequenceNumberErr := io.WriteUint8(8, (sequenceNumber))
+    if _sequenceNumberErr != nil {
+        return errors.New("Error serializing 'sequenceNumber' field " + _sequenceNumberErr.Error())
+    }
+
+    // Simple Field (proposedWindowSize)
+    proposedWindowSize := uint8(m.ProposedWindowSize)
+    _proposedWindowSizeErr := io.WriteUint8(8, (proposedWindowSize))
+    if _proposedWindowSizeErr != nil {
+        return errors.New("Error serializing 'proposedWindowSize' field " + _proposedWindowSizeErr.Error())
+    }
+
+        return nil
+    }
+    return APDUSerialize(io, m.APDU, CastIAPDU(m), ser)
+}
+
+func (m *APDUSegmentAck) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "negativeAck":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.NegativeAck = data
+            case "server":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Server = data
+            case "originalInvokeId":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.OriginalInvokeId = data
+            case "sequenceNumber":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SequenceNumber = data
+            case "proposedWindowSize":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ProposedWindowSize = data
+            }
+        }
+    }
+}
+
+func (m APDUSegmentAck) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.bacnetip.readwrite.APDUSegmentAck"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.NegativeAck, xml.StartElement{Name: xml.Name{Local: "negativeAck"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Server, xml.StartElement{Name: xml.Name{Local: "server"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.OriginalInvokeId, xml.StartElement{Name: xml.Name{Local: "originalInvokeId"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SequenceNumber, xml.StartElement{Name: xml.Name{Local: "sequenceNumber"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ProposedWindowSize, xml.StartElement{Name: xml.Name{Local: "proposedWindowSize"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUSimpleAck.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUSimpleAck.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUSimpleAck.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/APDUSimpleAck.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUUnconfirmedRequest.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUUnconfirmedRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/APDUUnconfirmedRequest.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/APDUUnconfirmedRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/ApplicationTag.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/ApplicationTag.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/ApplicationTag.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/ApplicationTag.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetAddress.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetAddress.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetAddress.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetAddress.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACK.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACK.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACK.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACK.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKAtomicReadFile.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKAtomicReadFile.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKAtomicReadFile.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKAtomicReadFile.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKAtomicWriteFile.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKAtomicWriteFile.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKAtomicWriteFile.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKAtomicWriteFile.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKConfirmedPrivateTransfer.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKConfirmedPrivateTransfer.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKConfirmedPrivateTransfer.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKConfirmedPrivateTransfer.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKCreateObject.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKCreateObject.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKCreateObject.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKCreateObject.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetAlarmSummary.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetAlarmSummary.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetAlarmSummary.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetAlarmSummary.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetEnrollmentSummary.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetEnrollmentSummary.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetEnrollmentSummary.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetEnrollmentSummary.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetEventInformation.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetEventInformation.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetEventInformation.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKGetEventInformation.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadProperty.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadProperty.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadProperty.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadProperty.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadPropertyMultiple.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadPropertyMultiple.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadPropertyMultiple.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadPropertyMultiple.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadRange.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadRange.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadRange.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKReadRange.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKRemovedAuthenticate.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKRemovedAuthenticate.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKRemovedAuthenticate.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKRemovedAuthenticate.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKRemovedReadPropertyConditional.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKRemovedReadPropertyConditional.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKRemovedReadPropertyConditional.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKRemovedReadPropertyConditional.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKVTData.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKVTData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKVTData.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKVTData.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKVTOpen.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKVTOpen.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKVTOpen.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceACKVTOpen.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequest.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequest.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAcknowledgeAlarm.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAcknowledgeAlarm.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAcknowledgeAlarm.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAcknowledgeAlarm.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAddListElement.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAddListElement.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAddListElement.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAddListElement.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAtomicReadFile.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAtomicReadFile.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAtomicReadFile.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAtomicReadFile.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAtomicWriteFile.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAtomicWriteFile.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAtomicWriteFile.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestAtomicWriteFile.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go
similarity index 100%
copy from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go
copy to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotificationMultiple.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotificationMultiple.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotificationMultiple.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotificationMultiple.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedEventNotification.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedEventNotification.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedEventNotification.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedEventNotification.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedPrivateTransfer.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedPrivateTransfer.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedPrivateTransfer.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedPrivateTransfer.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedTextMessage.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedTextMessage.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedTextMessage.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedTextMessage.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestCreateObject.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestCreateObject.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestCreateObject.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestCreateObject.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestDeleteObject.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestDeleteObject.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestDeleteObject.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestDeleteObject.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestDeviceCommunicationControl.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestDeviceCommunicationControl.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestDeviceCommunicationControl.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestDeviceCommunicationControl.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestGetEnrollmentSummary.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestGetEnrollmentSummary.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestGetEnrollmentSummary.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestGetEnrollmentSummary.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestGetEventInformation.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestGetEventInformation.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestGetEventInformation.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestGetEventInformation.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestLifeSafetyOperation.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestLifeSafetyOperation.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestLifeSafetyOperation.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestLifeSafetyOperation.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadProperty.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadProperty.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadProperty.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadProperty.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadPropertyMultiple.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadPropertyMultiple.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadPropertyMultiple.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadPropertyMultiple.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadRange.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadRange.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadRange.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadRange.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReinitializeDevice.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReinitializeDevice.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReinitializeDevice.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReinitializeDevice.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemoveListElement.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemoveListElement.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemoveListElement.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemoveListElement.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedAuthenticate.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedAuthenticate.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedAuthenticate.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedAuthenticate.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedReadPropertyConditional.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedReadPropertyConditional.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedReadPropertyConditional.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedReadPropertyConditional.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedRequestKey.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedRequestKey.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedRequestKey.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestRemovedRequestKey.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOV.go
similarity index 53%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOV.go
index ae854c4..c216254 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOV.go
@@ -25,74 +25,70 @@ import (
     "io"
     "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
     "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
-    "reflect"
     "strconv"
 )
 
 // Constant values.
-const BACnetConfirmedServiceRequestConfirmedCOVNotification_SUBSCRIBERPROCESSIDENTIFIERHEADER uint8 = 0x09
-const BACnetConfirmedServiceRequestConfirmedCOVNotification_MONITOREDOBJECTIDENTIFIERHEADER uint8 = 0x1C
-const BACnetConfirmedServiceRequestConfirmedCOVNotification_ISSUECONFIRMEDNOTIFICATIONSHEADER uint8 = 0x2C
-const BACnetConfirmedServiceRequestConfirmedCOVNotification_LIFETIMEHEADER uint8 = 0x07
-const BACnetConfirmedServiceRequestConfirmedCOVNotification_LISTOFVALUESOPENINGTAG uint8 = 0x4E
-const BACnetConfirmedServiceRequestConfirmedCOVNotification_LISTOFVALUESCLOSINGTAG uint8 = 0x4F
+const BACnetConfirmedServiceRequestSubscribeCOV_SUBSCRIBERPROCESSIDENTIFIERHEADER uint8 = 0x09
+const BACnetConfirmedServiceRequestSubscribeCOV_MONITOREDOBJECTIDENTIFIERHEADER uint8 = 0x1C
+const BACnetConfirmedServiceRequestSubscribeCOV_ISSUECONFIRMEDNOTIFICATIONSHEADER uint8 = 0x29
+const BACnetConfirmedServiceRequestSubscribeCOV_ISSUECONFIRMEDNOTIFICATIONSSKIPBITS uint8 = 0x00
+const BACnetConfirmedServiceRequestSubscribeCOV_LIFETIMEHEADER uint8 = 0x07
 
 // The data-structure of this message
-type BACnetConfirmedServiceRequestConfirmedCOVNotification struct {
+type BACnetConfirmedServiceRequestSubscribeCOV struct {
     SubscriberProcessIdentifier uint8
     MonitoredObjectType uint16
     MonitoredObjectInstanceNumber uint32
-    IssueConfirmedNotificationsType uint16
-    IssueConfirmedNotificationsInstanceNumber uint32
+    IssueConfirmedNotifications bool
     LifetimeLength uint8
     LifetimeSeconds []int8
-    Notifications []IBACnetTagWithContent
     BACnetConfirmedServiceRequest
 }
 
 // The corresponding interface
-type IBACnetConfirmedServiceRequestConfirmedCOVNotification interface {
+type IBACnetConfirmedServiceRequestSubscribeCOV interface {
     IBACnetConfirmedServiceRequest
     Serialize(io utils.WriteBuffer) error
 }
 
 // Accessors for discriminator values.
-func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) ServiceChoice() uint8 {
-    return 0x01
+func (m BACnetConfirmedServiceRequestSubscribeCOV) ServiceChoice() uint8 {
+    return 0x05
 }
 
-func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) initialize() spi.Message {
+func (m BACnetConfirmedServiceRequestSubscribeCOV) initialize() spi.Message {
     return m
 }
 
-func NewBACnetConfirmedServiceRequestConfirmedCOVNotification(subscriberProcessIdentifier uint8, monitoredObjectType uint16, monitoredObjectInstanceNumber uint32, issueConfirmedNotificationsType uint16, issueConfirmedNotificationsInstanceNumber uint32, lifetimeLength uint8, lifetimeSeconds []int8, notifications []IBACnetTagWithContent) BACnetConfirmedServiceRequestInitializer {
-    return &BACnetConfirmedServiceRequestConfirmedCOVNotification{SubscriberProcessIdentifier: subscriberProcessIdentifier, MonitoredObjectType: monitoredObjectType, MonitoredObjectInstanceNumber: monitoredObjectInstanceNumber, IssueConfirmedNotificationsType: issueConfirmedNotificationsType, IssueConfirmedNotificationsInstanceNumber: issueConfirmedNotificationsInstanceNumber, LifetimeLength: lifetimeLength, LifetimeSeconds: lifetimeSeconds, Notifications: notifications}
+func NewBACnetConfirmedServiceRequestSubscribeCOV(subscriberProcessIdentifier uint8, monitoredObjectType uint16, monitoredObjectInstanceNumber uint32, issueConfirmedNotifications bool, lifetimeLength uint8, lifetimeSeconds []int8) BACnetConfirmedServiceRequestInitializer {
+    return &BACnetConfirmedServiceRequestSubscribeCOV{SubscriberProcessIdentifier: subscriberProcessIdentifier, MonitoredObjectType: monitoredObjectType, MonitoredObjectInstanceNumber: monitoredObjectInstanceNumber, IssueConfirmedNotifications: issueConfirmedNotifications, LifetimeLength: lifetimeLength, LifetimeSeconds: lifetimeSeconds}
 }
 
-func CastIBACnetConfirmedServiceRequestConfirmedCOVNotification(structType interface{}) IBACnetConfirmedServiceRequestConfirmedCOVNotification {
-    castFunc := func(typ interface{}) IBACnetConfirmedServiceRequestConfirmedCOVNotification {
-        if iBACnetConfirmedServiceRequestConfirmedCOVNotification, ok := typ.(IBACnetConfirmedServiceRequestConfirmedCOVNotification); ok {
-            return iBACnetConfirmedServiceRequestConfirmedCOVNotification
+func CastIBACnetConfirmedServiceRequestSubscribeCOV(structType interface{}) IBACnetConfirmedServiceRequestSubscribeCOV {
+    castFunc := func(typ interface{}) IBACnetConfirmedServiceRequestSubscribeCOV {
+        if iBACnetConfirmedServiceRequestSubscribeCOV, ok := typ.(IBACnetConfirmedServiceRequestSubscribeCOV); ok {
+            return iBACnetConfirmedServiceRequestSubscribeCOV
         }
         return nil
     }
     return castFunc(structType)
 }
 
-func CastBACnetConfirmedServiceRequestConfirmedCOVNotification(structType interface{}) BACnetConfirmedServiceRequestConfirmedCOVNotification {
-    castFunc := func(typ interface{}) BACnetConfirmedServiceRequestConfirmedCOVNotification {
-        if sBACnetConfirmedServiceRequestConfirmedCOVNotification, ok := typ.(BACnetConfirmedServiceRequestConfirmedCOVNotification); ok {
-            return sBACnetConfirmedServiceRequestConfirmedCOVNotification
+func CastBACnetConfirmedServiceRequestSubscribeCOV(structType interface{}) BACnetConfirmedServiceRequestSubscribeCOV {
+    castFunc := func(typ interface{}) BACnetConfirmedServiceRequestSubscribeCOV {
+        if sBACnetConfirmedServiceRequestSubscribeCOV, ok := typ.(BACnetConfirmedServiceRequestSubscribeCOV); ok {
+            return sBACnetConfirmedServiceRequestSubscribeCOV
         }
-        if sBACnetConfirmedServiceRequestConfirmedCOVNotification, ok := typ.(*BACnetConfirmedServiceRequestConfirmedCOVNotification); ok {
-            return *sBACnetConfirmedServiceRequestConfirmedCOVNotification
+        if sBACnetConfirmedServiceRequestSubscribeCOV, ok := typ.(*BACnetConfirmedServiceRequestSubscribeCOV); ok {
+            return *sBACnetConfirmedServiceRequestSubscribeCOV
         }
-        return BACnetConfirmedServiceRequestConfirmedCOVNotification{}
+        return BACnetConfirmedServiceRequestSubscribeCOV{}
     }
     return castFunc(structType)
 }
 
-func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) LengthInBits() uint16 {
+func (m BACnetConfirmedServiceRequestSubscribeCOV) LengthInBits() uint16 {
     var lengthInBits uint16 = m.BACnetConfirmedServiceRequest.LengthInBits()
 
     // Const Field (subscriberProcessIdentifierHeader)
@@ -113,11 +109,11 @@ func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) LengthInBits() ui
     // Const Field (issueConfirmedNotificationsHeader)
     lengthInBits += 8
 
-    // Simple field (issueConfirmedNotificationsType)
-    lengthInBits += 10
+    // Const Field (issueConfirmedNotificationsSkipBits)
+    lengthInBits += 7
 
-    // Simple field (issueConfirmedNotificationsInstanceNumber)
-    lengthInBits += 22
+    // Simple field (issueConfirmedNotifications)
+    lengthInBits += 1
 
     // Const Field (lifetimeHeader)
     lengthInBits += 5
@@ -130,35 +126,22 @@ func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) LengthInBits() ui
         lengthInBits += 8 * uint16(len(m.LifetimeSeconds))
     }
 
-    // Const Field (listOfValuesOpeningTag)
-    lengthInBits += 8
-
-    // Array field
-    if len(m.Notifications) > 0 {
-        for _, element := range m.Notifications {
-            lengthInBits += element.LengthInBits()
-        }
-    }
-
-    // Const Field (listOfValuesClosingTag)
-    lengthInBits += 8
-
     return lengthInBits
 }
 
-func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) LengthInBytes() uint16 {
+func (m BACnetConfirmedServiceRequestSubscribeCOV) LengthInBytes() uint16 {
     return m.LengthInBits() / 8
 }
 
-func BACnetConfirmedServiceRequestConfirmedCOVNotificationParse(io *utils.ReadBuffer, len uint16) (BACnetConfirmedServiceRequestInitializer, error) {
+func BACnetConfirmedServiceRequestSubscribeCOVParse(io *utils.ReadBuffer) (BACnetConfirmedServiceRequestInitializer, error) {
 
     // Const Field (subscriberProcessIdentifierHeader)
     subscriberProcessIdentifierHeader, _subscriberProcessIdentifierHeaderErr := io.ReadUint8(8)
     if _subscriberProcessIdentifierHeaderErr != nil {
         return nil, errors.New("Error parsing 'subscriberProcessIdentifierHeader' field " + _subscriberProcessIdentifierHeaderErr.Error())
     }
-    if subscriberProcessIdentifierHeader != BACnetConfirmedServiceRequestConfirmedCOVNotification_SUBSCRIBERPROCESSIDENTIFIERHEADER {
-        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestConfirmedCOVNotification_SUBSCRIBERPROCESSIDENTIFIERHEADER)) + " but got " + strconv.Itoa(int(subscriberProcessIdentifierHeader)))
+    if subscriberProcessIdentifierHeader != BACnetConfirmedServiceRequestSubscribeCOV_SUBSCRIBERPROCESSIDENTIFIERHEADER {
+        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestSubscribeCOV_SUBSCRIBERPROCESSIDENTIFIERHEADER)) + " but got " + strconv.Itoa(int(subscriberProcessIdentifierHeader)))
     }
 
     // Simple Field (subscriberProcessIdentifier)
@@ -172,8 +155,8 @@ func BACnetConfirmedServiceRequestConfirmedCOVNotificationParse(io *utils.ReadBu
     if _monitoredObjectIdentifierHeaderErr != nil {
         return nil, errors.New("Error parsing 'monitoredObjectIdentifierHeader' field " + _monitoredObjectIdentifierHeaderErr.Error())
     }
-    if monitoredObjectIdentifierHeader != BACnetConfirmedServiceRequestConfirmedCOVNotification_MONITOREDOBJECTIDENTIFIERHEADER {
-        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestConfirmedCOVNotification_MONITOREDOBJECTIDENTIFIERHEADER)) + " but got " + strconv.Itoa(int(monitoredObjectIdentifierHeader)))
+    if monitoredObjectIdentifierHeader != BACnetConfirmedServiceRequestSubscribeCOV_MONITOREDOBJECTIDENTIFIERHEADER {
+        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestSubscribeCOV_MONITOREDOBJECTIDENTIFIERHEADER)) + " but got " + strconv.Itoa(int(monitoredObjectIdentifierHeader)))
     }
 
     // Simple Field (monitoredObjectType)
@@ -193,20 +176,23 @@ func BACnetConfirmedServiceRequestConfirmedCOVNotificationParse(io *utils.ReadBu
     if _issueConfirmedNotificationsHeaderErr != nil {
         return nil, errors.New("Error parsing 'issueConfirmedNotificationsHeader' field " + _issueConfirmedNotificationsHeaderErr.Error())
     }
-    if issueConfirmedNotificationsHeader != BACnetConfirmedServiceRequestConfirmedCOVNotification_ISSUECONFIRMEDNOTIFICATIONSHEADER {
-        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestConfirmedCOVNotification_ISSUECONFIRMEDNOTIFICATIONSHEADER)) + " but got " + strconv.Itoa(int(issueConfirmedNotificationsHeader)))
+    if issueConfirmedNotificationsHeader != BACnetConfirmedServiceRequestSubscribeCOV_ISSUECONFIRMEDNOTIFICATIONSHEADER {
+        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestSubscribeCOV_ISSUECONFIRMEDNOTIFICATIONSHEADER)) + " but got " + strconv.Itoa(int(issueConfirmedNotificationsHeader)))
     }
 
-    // Simple Field (issueConfirmedNotificationsType)
-    issueConfirmedNotificationsType, _issueConfirmedNotificationsTypeErr := io.ReadUint16(10)
-    if _issueConfirmedNotificationsTypeErr != nil {
-        return nil, errors.New("Error parsing 'issueConfirmedNotificationsType' field " + _issueConfirmedNotificationsTypeErr.Error())
+    // Const Field (issueConfirmedNotificationsSkipBits)
+    issueConfirmedNotificationsSkipBits, _issueConfirmedNotificationsSkipBitsErr := io.ReadUint8(7)
+    if _issueConfirmedNotificationsSkipBitsErr != nil {
+        return nil, errors.New("Error parsing 'issueConfirmedNotificationsSkipBits' field " + _issueConfirmedNotificationsSkipBitsErr.Error())
+    }
+    if issueConfirmedNotificationsSkipBits != BACnetConfirmedServiceRequestSubscribeCOV_ISSUECONFIRMEDNOTIFICATIONSSKIPBITS {
+        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestSubscribeCOV_ISSUECONFIRMEDNOTIFICATIONSSKIPBITS)) + " but got " + strconv.Itoa(int(issueConfirmedNotificationsSkipBits)))
     }
 
-    // Simple Field (issueConfirmedNotificationsInstanceNumber)
-    issueConfirmedNotificationsInstanceNumber, _issueConfirmedNotificationsInstanceNumberErr := io.ReadUint32(22)
-    if _issueConfirmedNotificationsInstanceNumberErr != nil {
-        return nil, errors.New("Error parsing 'issueConfirmedNotificationsInstanceNumber' field " + _issueConfirmedNotificationsInstanceNumberErr.Error())
+    // Simple Field (issueConfirmedNotifications)
+    issueConfirmedNotifications, _issueConfirmedNotificationsErr := io.ReadBit()
+    if _issueConfirmedNotificationsErr != nil {
+        return nil, errors.New("Error parsing 'issueConfirmedNotifications' field " + _issueConfirmedNotificationsErr.Error())
     }
 
     // Const Field (lifetimeHeader)
@@ -214,8 +200,8 @@ func BACnetConfirmedServiceRequestConfirmedCOVNotificationParse(io *utils.ReadBu
     if _lifetimeHeaderErr != nil {
         return nil, errors.New("Error parsing 'lifetimeHeader' field " + _lifetimeHeaderErr.Error())
     }
-    if lifetimeHeader != BACnetConfirmedServiceRequestConfirmedCOVNotification_LIFETIMEHEADER {
-        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestConfirmedCOVNotification_LIFETIMEHEADER)) + " but got " + strconv.Itoa(int(lifetimeHeader)))
+    if lifetimeHeader != BACnetConfirmedServiceRequestSubscribeCOV_LIFETIMEHEADER {
+        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestSubscribeCOV_LIFETIMEHEADER)) + " but got " + strconv.Itoa(int(lifetimeHeader)))
     }
 
     // Simple Field (lifetimeLength)
@@ -236,47 +222,11 @@ func BACnetConfirmedServiceRequestConfirmedCOVNotificationParse(io *utils.ReadBu
         lifetimeSeconds[curItem] = _item
     }
 
-    // Const Field (listOfValuesOpeningTag)
-    listOfValuesOpeningTag, _listOfValuesOpeningTagErr := io.ReadUint8(8)
-    if _listOfValuesOpeningTagErr != nil {
-        return nil, errors.New("Error parsing 'listOfValuesOpeningTag' field " + _listOfValuesOpeningTagErr.Error())
-    }
-    if listOfValuesOpeningTag != BACnetConfirmedServiceRequestConfirmedCOVNotification_LISTOFVALUESOPENINGTAG {
-        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestConfirmedCOVNotification_LISTOFVALUESOPENINGTAG)) + " but got " + strconv.Itoa(int(listOfValuesOpeningTag)))
-    }
-
-    // Array field (notifications)
-    // Length array
-    notifications := make([]IBACnetTagWithContent, 0)
-    _notificationsLength := uint16(len) - uint16(uint16(18))
-    _notificationsEndPos := io.GetPos() + uint16(_notificationsLength)
-    for ;io.GetPos() < _notificationsEndPos; {
-        _message, _err := BACnetTagWithContentParse(io)
-        if _err != nil {
-            return nil, errors.New("Error parsing 'notifications' field " + _err.Error())
-        }
-        var _item IBACnetTagWithContent
-        _item, _ok := _message.(IBACnetTagWithContent)
-        if !_ok {
-            return nil, errors.New("Couldn't cast message of type " + reflect.TypeOf(_item).Name() + " to BACnetTagWithContent")
-        }
-        notifications = append(notifications, _item)
-    }
-
-    // Const Field (listOfValuesClosingTag)
-    listOfValuesClosingTag, _listOfValuesClosingTagErr := io.ReadUint8(8)
-    if _listOfValuesClosingTagErr != nil {
-        return nil, errors.New("Error parsing 'listOfValuesClosingTag' field " + _listOfValuesClosingTagErr.Error())
-    }
-    if listOfValuesClosingTag != BACnetConfirmedServiceRequestConfirmedCOVNotification_LISTOFVALUESCLOSINGTAG {
-        return nil, errors.New("Expected constant value " + strconv.Itoa(int(BACnetConfirmedServiceRequestConfirmedCOVNotification_LISTOFVALUESCLOSINGTAG)) + " but got " + strconv.Itoa(int(listOfValuesClosingTag)))
-    }
-
     // Create the instance
-    return NewBACnetConfirmedServiceRequestConfirmedCOVNotification(subscriberProcessIdentifier, monitoredObjectType, monitoredObjectInstanceNumber, issueConfirmedNotificationsType, issueConfirmedNotificationsInstanceNumber, lifetimeLength, lifetimeSeconds, notifications), nil
+    return NewBACnetConfirmedServiceRequestSubscribeCOV(subscriberProcessIdentifier, monitoredObjectType, monitoredObjectInstanceNumber, issueConfirmedNotifications, lifetimeLength, lifetimeSeconds), nil
 }
 
-func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) Serialize(io utils.WriteBuffer) error {
+func (m BACnetConfirmedServiceRequestSubscribeCOV) Serialize(io utils.WriteBuffer) error {
     ser := func() error {
 
     // Const Field (subscriberProcessIdentifierHeader)
@@ -313,23 +263,22 @@ func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) Serialize(io util
     }
 
     // Const Field (issueConfirmedNotificationsHeader)
-    _issueConfirmedNotificationsHeaderErr := io.WriteUint8(8, 0x2C)
+    _issueConfirmedNotificationsHeaderErr := io.WriteUint8(8, 0x29)
     if _issueConfirmedNotificationsHeaderErr != nil {
         return errors.New("Error serializing 'issueConfirmedNotificationsHeader' field " + _issueConfirmedNotificationsHeaderErr.Error())
     }
 
-    // Simple Field (issueConfirmedNotificationsType)
-    issueConfirmedNotificationsType := uint16(m.IssueConfirmedNotificationsType)
-    _issueConfirmedNotificationsTypeErr := io.WriteUint16(10, (issueConfirmedNotificationsType))
-    if _issueConfirmedNotificationsTypeErr != nil {
-        return errors.New("Error serializing 'issueConfirmedNotificationsType' field " + _issueConfirmedNotificationsTypeErr.Error())
+    // Const Field (issueConfirmedNotificationsSkipBits)
+    _issueConfirmedNotificationsSkipBitsErr := io.WriteUint8(7, 0x00)
+    if _issueConfirmedNotificationsSkipBitsErr != nil {
+        return errors.New("Error serializing 'issueConfirmedNotificationsSkipBits' field " + _issueConfirmedNotificationsSkipBitsErr.Error())
     }
 
-    // Simple Field (issueConfirmedNotificationsInstanceNumber)
-    issueConfirmedNotificationsInstanceNumber := uint32(m.IssueConfirmedNotificationsInstanceNumber)
-    _issueConfirmedNotificationsInstanceNumberErr := io.WriteUint32(22, (issueConfirmedNotificationsInstanceNumber))
-    if _issueConfirmedNotificationsInstanceNumberErr != nil {
-        return errors.New("Error serializing 'issueConfirmedNotificationsInstanceNumber' field " + _issueConfirmedNotificationsInstanceNumberErr.Error())
+    // Simple Field (issueConfirmedNotifications)
+    issueConfirmedNotifications := bool(m.IssueConfirmedNotifications)
+    _issueConfirmedNotificationsErr := io.WriteBit((issueConfirmedNotifications))
+    if _issueConfirmedNotificationsErr != nil {
+        return errors.New("Error serializing 'issueConfirmedNotifications' field " + _issueConfirmedNotificationsErr.Error())
     }
 
     // Const Field (lifetimeHeader)
@@ -355,34 +304,12 @@ func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) Serialize(io util
         }
     }
 
-    // Const Field (listOfValuesOpeningTag)
-    _listOfValuesOpeningTagErr := io.WriteUint8(8, 0x4E)
-    if _listOfValuesOpeningTagErr != nil {
-        return errors.New("Error serializing 'listOfValuesOpeningTag' field " + _listOfValuesOpeningTagErr.Error())
-    }
-
-    // Array Field (notifications)
-    if m.Notifications != nil {
-        for _, _element := range m.Notifications {
-            _elementErr := _element.Serialize(io)
-            if _elementErr != nil {
-                return errors.New("Error serializing 'notifications' field " + _elementErr.Error())
-            }
-        }
-    }
-
-    // Const Field (listOfValuesClosingTag)
-    _listOfValuesClosingTagErr := io.WriteUint8(8, 0x4F)
-    if _listOfValuesClosingTagErr != nil {
-        return errors.New("Error serializing 'listOfValuesClosingTag' field " + _listOfValuesClosingTagErr.Error())
-    }
-
         return nil
     }
     return BACnetConfirmedServiceRequestSerialize(io, m.BACnetConfirmedServiceRequest, CastIBACnetConfirmedServiceRequest(m), ser)
 }
 
-func (m *BACnetConfirmedServiceRequestConfirmedCOVNotification) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+func (m *BACnetConfirmedServiceRequestSubscribeCOV) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
     for {
         token, err := d.Token()
         if err != nil {
@@ -413,18 +340,12 @@ func (m *BACnetConfirmedServiceRequestConfirmedCOVNotification) UnmarshalXML(d *
                     return err
                 }
                 m.MonitoredObjectInstanceNumber = data
-            case "issueConfirmedNotificationsType":
-                var data uint16
-                if err := d.DecodeElement(&data, &tok); err != nil {
-                    return err
-                }
-                m.IssueConfirmedNotificationsType = data
-            case "issueConfirmedNotificationsInstanceNumber":
-                var data uint32
+            case "issueConfirmedNotifications":
+                var data bool
                 if err := d.DecodeElement(&data, &tok); err != nil {
                     return err
                 }
-                m.IssueConfirmedNotificationsInstanceNumber = data
+                m.IssueConfirmedNotifications = data
             case "lifetimeLength":
                 var data uint8
                 if err := d.DecodeElement(&data, &tok); err != nil {
@@ -442,20 +363,14 @@ func (m *BACnetConfirmedServiceRequestConfirmedCOVNotification) UnmarshalXML(d *
                     return err
                 }
                 m.LifetimeSeconds = utils.ByteToInt8(_decoded[0:_len])
-            case "notifications":
-                var data []IBACnetTagWithContent
-                if err := d.DecodeElement(&data, &tok); err != nil {
-                    return err
-                }
-                m.Notifications = data
             }
         }
     }
 }
 
-func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+func (m BACnetConfirmedServiceRequestSubscribeCOV) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
     if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
-            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestConfirmedCOVNotification"},
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.bacnetip.readwrite.BACnetConfirmedServiceRequestSubscribeCOV"},
         }}); err != nil {
         return err
     }
@@ -468,10 +383,7 @@ func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) MarshalXML(e *xml
     if err := e.EncodeElement(m.MonitoredObjectInstanceNumber, xml.StartElement{Name: xml.Name{Local: "monitoredObjectInstanceNumber"}}); err != nil {
         return err
     }
-    if err := e.EncodeElement(m.IssueConfirmedNotificationsType, xml.StartElement{Name: xml.Name{Local: "issueConfirmedNotificationsType"}}); err != nil {
-        return err
-    }
-    if err := e.EncodeElement(m.IssueConfirmedNotificationsInstanceNumber, xml.StartElement{Name: xml.Name{Local: "issueConfirmedNotificationsInstanceNumber"}}); err != nil {
+    if err := e.EncodeElement(m.IssueConfirmedNotifications, xml.StartElement{Name: xml.Name{Local: "issueConfirmedNotifications"}}); err != nil {
         return err
     }
     if err := e.EncodeElement(m.LifetimeLength, xml.StartElement{Name: xml.Name{Local: "lifetimeLength"}}); err != nil {
@@ -482,15 +394,6 @@ func (m BACnetConfirmedServiceRequestConfirmedCOVNotification) MarshalXML(e *xml
     if err := e.EncodeElement(_encodedLifetimeSeconds, xml.StartElement{Name: xml.Name{Local: "lifetimeSeconds"}}); err != nil {
         return err
     }
-    if err := e.EncodeToken(xml.StartElement{Name: xml.Name{Local: "notifications"}}); err != nil {
-        return err
-    }
-    if err := e.EncodeElement(m.Notifications, xml.StartElement{Name: xml.Name{Local: "notifications"}}); err != nil {
-        return err
-    }
-    if err := e.EncodeToken(xml.EndElement{Name: xml.Name{Local: "notifications"}}); err != nil {
-        return err
-    }
     if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
         return err
     }
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOVProperty.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOVProperty.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOVProperty.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOVProperty.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOVPropertyMultiple.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOVPropertyMultiple.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOVPropertyMultiple.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOVPropertyMultiple.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTClose.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTClose.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTClose.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTClose.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTData.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTData.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTData.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTOpen.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTOpen.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTOpen.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestVTOpen.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWriteProperty.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWriteProperty.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWriteProperty.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWriteProperty.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWritePropertyMultiple.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWritePropertyMultiple.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWritePropertyMultiple.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWritePropertyMultiple.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetError.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetError.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetError.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetError.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorAtomicReadFile.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorAtomicReadFile.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorAtomicReadFile.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorAtomicReadFile.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorAtomicWriteFile.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorAtomicWriteFile.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorAtomicWriteFile.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorAtomicWriteFile.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorConfirmedPrivateTransfer.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorConfirmedPrivateTransfer.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorConfirmedPrivateTransfer.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorConfirmedPrivateTransfer.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorCreateObject.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorCreateObject.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorCreateObject.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorCreateObject.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetAlarmSummary.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetAlarmSummary.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetAlarmSummary.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetAlarmSummary.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetEnrollmentSummary.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetEnrollmentSummary.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetEnrollmentSummary.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetEnrollmentSummary.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetEventInformation.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetEventInformation.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetEventInformation.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorGetEventInformation.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadPropertyMultiple.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadPropertyMultiple.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadPropertyMultiple.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadPropertyMultiple.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadRange.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadRange.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadRange.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadRange.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorRemovedAuthenticate.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorRemovedAuthenticate.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorRemovedAuthenticate.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorRemovedAuthenticate.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorRemovedReadPropertyConditional.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorRemovedReadPropertyConditional.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorRemovedReadPropertyConditional.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorRemovedReadPropertyConditional.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorVTData.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorVTData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorVTData.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorVTData.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorVTOpen.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorVTOpen.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorVTOpen.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorVTOpen.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNetworkType.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNetworkType.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNetworkType.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNetworkType.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNodeType.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNodeType.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNodeType.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNodeType.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotifyType.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotifyType.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotifyType.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotifyType.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetObjectType.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetObjectType.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetObjectType.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetObjectType.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAck.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAck.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAck.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAck.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckAtomicReadFile.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckAtomicReadFile.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckAtomicReadFile.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckAtomicReadFile.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckAtomicWriteFile.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckAtomicWriteFile.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckAtomicWriteFile.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckAtomicWriteFile.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckConfirmedPrivateTransfer.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckConfirmedPrivateTransfer.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckConfirmedPrivateTransfer.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckConfirmedPrivateTransfer.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckCreateObject.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckCreateObject.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckCreateObject.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckCreateObject.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetAlarmSummary.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetAlarmSummary.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetAlarmSummary.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetAlarmSummary.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetEnrollmentSummary.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetEnrollmentSummary.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetEnrollmentSummary.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetEnrollmentSummary.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetEventInformation.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetEventInformation.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetEventInformation.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckGetEventInformation.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadProperty.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadProperty.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadProperty.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadProperty.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadPropertyMultiple.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadPropertyMultiple.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadPropertyMultiple.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadPropertyMultiple.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadRange.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadRange.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadRange.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadRange.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckRemovedAuthenticate.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckRemovedAuthenticate.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckRemovedAuthenticate.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckRemovedAuthenticate.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckRemovedReadPropertyConditional.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckRemovedReadPropertyConditional.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckRemovedReadPropertyConditional.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckRemovedReadPropertyConditional.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckVTData.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckVTData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckVTData.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckVTData.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckVTOpen.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckVTOpen.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckVTOpen.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckVTOpen.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTag.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTag.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTag.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTag.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBitString.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBitString.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBitString.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBitString.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBoolean.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBoolean.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBoolean.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBoolean.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationCharacterString.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationCharacterString.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationCharacterString.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationCharacterString.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationDate.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationDate.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationDate.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationDate.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationDouble.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationDouble.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationDouble.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationDouble.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationEnumerated.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationEnumerated.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationEnumerated.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationEnumerated.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationNull.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationNull.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationNull.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationNull.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationObjectIdentifier.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationObjectIdentifier.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationObjectIdentifier.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationObjectIdentifier.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationOctetString.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationOctetString.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationOctetString.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationOctetString.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationReal.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationReal.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationReal.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationReal.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationSignedInteger.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationSignedInteger.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationSignedInteger.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationSignedInteger.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationTime.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationTime.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationTime.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationTime.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationUnsignedInteger.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationUnsignedInteger.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationUnsignedInteger.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationUnsignedInteger.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagContext.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagContext.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagContext.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagContext.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagWithContent.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagWithContent.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagWithContent.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagWithContent.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequest.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequest.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIAm.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIAm.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIAm.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIAm.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIHave.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIHave.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIHave.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIHave.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestTimeSynchronization.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestTimeSynchronization.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestTimeSynchronization.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestTimeSynchronization.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUTCTimeSynchronization.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUTCTimeSynchronization.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUTCTimeSynchronization.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUTCTimeSynchronization.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedCOVNotification.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedCOVNotification.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedCOVNotification.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedCOVNotification.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedCOVNotificationMultiple.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedCOVNotificationMultiple.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedCOVNotificationMultiple.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedCOVNotificationMultiple.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedEventNotification.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedEventNotification.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedEventNotification.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedEventNotification.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedTextMessage.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedTextMessage.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedTextMessage.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedTextMessage.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoHas.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoHas.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoHas.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoHas.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoIs.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoIs.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoIs.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoIs.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWriteGroup.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWriteGroup.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWriteGroup.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWriteGroup.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLC.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLC.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLC.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLC.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDeleteForeignDeviceTableEntry.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDeleteForeignDeviceTableEntry.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDeleteForeignDeviceTableEntry.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDeleteForeignDeviceTableEntry.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDistributeBroadcastToNetwork.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDistributeBroadcastToNetwork.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDistributeBroadcastToNetwork.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDistributeBroadcastToNetwork.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCForwardedNPDU.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCForwardedNPDU.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCForwardedNPDU.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCForwardedNPDU.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCOriginalBroadcastNPDU.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCOriginalBroadcastNPDU.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCOriginalBroadcastNPDU.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCOriginalBroadcastNPDU.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCOriginalUnicastNPDU.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCOriginalUnicastNPDU.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCOriginalUnicastNPDU.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCOriginalUnicastNPDU.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTable.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTable.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTable.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTable.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTableAck.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTableAck.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTableAck.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTableAck.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTable.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTable.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTable.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTable.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTableAck.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTableAck.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTableAck.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTableAck.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCRegisterForeignDevice.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCRegisterForeignDevice.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCRegisterForeignDevice.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCRegisterForeignDevice.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCResult.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCResult.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCResult.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCResult.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCSecureBVLL.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCSecureBVLL.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCSecureBVLL.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCSecureBVLL.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWideBroadcastDistributionTable.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWideBroadcastDistributionTable.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWideBroadcastDistributionTable.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWideBroadcastDistributionTable.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/NLM.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/NLM.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/NLM.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/NLM.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/NLMIAmRouterToNetwork.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/NLMIAmRouterToNetwork.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/NLMIAmRouterToNetwork.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/NLMIAmRouterToNetwork.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/NLMWhoIsRouterToNetwork.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/NLMWhoIsRouterToNetwork.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/NLMWhoIsRouterToNetwork.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/NLMWhoIsRouterToNetwork.go
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/NPDU.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/NPDU.go
new file mode 100644
index 0000000..0d95d59
--- /dev/null
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/NPDU.go
@@ -0,0 +1,726 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    log "github.com/sirupsen/logrus"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    "reflect"
+)
+
+// The data-structure of this message
+type NPDU struct {
+    ProtocolVersionNumber uint8
+    MessageTypeFieldPresent bool
+    DestinationSpecified bool
+    SourceSpecified bool
+    ExpectingReply bool
+    NetworkPriority uint8
+    DestinationNetworkAddress *uint16
+    DestinationLength *uint8
+    DestinationAddress []uint8
+    SourceNetworkAddress *uint16
+    SourceLength *uint8
+    SourceAddress []uint8
+    HopCount *uint8
+    Nlm *INLM
+    Apdu *IAPDU
+
+}
+
+// The corresponding interface
+type INPDU interface {
+    spi.Message
+    Serialize(io utils.WriteBuffer) error
+}
+
+
+func NewNPDU(protocolVersionNumber uint8, messageTypeFieldPresent bool, destinationSpecified bool, sourceSpecified bool, expectingReply bool, networkPriority uint8, destinationNetworkAddress *uint16, destinationLength *uint8, destinationAddress []uint8, sourceNetworkAddress *uint16, sourceLength *uint8, sourceAddress []uint8, hopCount *uint8, nlm *INLM, apdu *IAPDU) spi.Message {
+    return &NPDU{ProtocolVersionNumber: protocolVersionNumber, MessageTypeFieldPresent: messageTypeFieldPresent, DestinationSpecified: destinationSpecified, SourceSpecified: sourceSpecified, ExpectingReply: expectingReply, NetworkPriority: networkPriority, DestinationNetworkAddress: destinationNetworkAddress, DestinationLength: destinationLength, DestinationAddress: destinationAddress, SourceNetworkAddress: sourceNetworkAddress, SourceLength: sourceLength, SourceAddress: sourceAddress, H [...]
+}
+
+func CastINPDU(structType interface{}) INPDU {
+    castFunc := func(typ interface{}) INPDU {
+        if iNPDU, ok := typ.(INPDU); ok {
+            return iNPDU
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastNPDU(structType interface{}) NPDU {
+    castFunc := func(typ interface{}) NPDU {
+        if sNPDU, ok := typ.(NPDU); ok {
+            return sNPDU
+        }
+        if sNPDU, ok := typ.(*NPDU); ok {
+            return *sNPDU
+        }
+        return NPDU{}
+    }
+    return castFunc(structType)
+}
+
+func (m NPDU) LengthInBits() uint16 {
+    var lengthInBits uint16 = 0
+
+    // Simple field (protocolVersionNumber)
+    lengthInBits += 8
+
+    // Simple field (messageTypeFieldPresent)
+    lengthInBits += 1
+
+    // Reserved Field (reserved)
+    lengthInBits += 1
+
+    // Simple field (destinationSpecified)
+    lengthInBits += 1
+
+    // Reserved Field (reserved)
+    lengthInBits += 1
+
+    // Simple field (sourceSpecified)
+    lengthInBits += 1
+
+    // Simple field (expectingReply)
+    lengthInBits += 1
+
+    // Simple field (networkPriority)
+    lengthInBits += 2
+
+    // Optional Field (destinationNetworkAddress)
+    if m.DestinationNetworkAddress != nil {
+        lengthInBits += 16
+    }
+
+    // Optional Field (destinationLength)
+    if m.DestinationLength != nil {
+        lengthInBits += 8
+    }
+
+    // Array field
+    if len(m.DestinationAddress) > 0 {
+        lengthInBits += 8 * uint16(len(m.DestinationAddress))
+    }
+
+    // Optional Field (sourceNetworkAddress)
+    if m.SourceNetworkAddress != nil {
+        lengthInBits += 16
+    }
+
+    // Optional Field (sourceLength)
+    if m.SourceLength != nil {
+        lengthInBits += 8
+    }
+
+    // Array field
+    if len(m.SourceAddress) > 0 {
+        lengthInBits += 8 * uint16(len(m.SourceAddress))
+    }
+
+    // Optional Field (hopCount)
+    if m.HopCount != nil {
+        lengthInBits += 8
+    }
+
+    // Optional Field (nlm)
+    if m.Nlm != nil {
+        lengthInBits += (*m.Nlm).LengthInBits()
+    }
+
+    // Optional Field (apdu)
+    if m.Apdu != nil {
+        lengthInBits += (*m.Apdu).LengthInBits()
+    }
+
+    return lengthInBits
+}
+
+func (m NPDU) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func NPDUParse(io *utils.ReadBuffer, npduLength uint16) (spi.Message, error) {
+
+    // Simple Field (protocolVersionNumber)
+    protocolVersionNumber, _protocolVersionNumberErr := io.ReadUint8(8)
+    if _protocolVersionNumberErr != nil {
+        return nil, errors.New("Error parsing 'protocolVersionNumber' field " + _protocolVersionNumberErr.Error())
+    }
+
+    // Simple Field (messageTypeFieldPresent)
+    messageTypeFieldPresent, _messageTypeFieldPresentErr := io.ReadBit()
+    if _messageTypeFieldPresentErr != nil {
+        return nil, errors.New("Error parsing 'messageTypeFieldPresent' field " + _messageTypeFieldPresentErr.Error())
+    }
+
+    // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+    {
+        reserved, _err := io.ReadUint8(1)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'reserved' field " + _err.Error())
+        }
+        if reserved != uint8(0) {
+            log.WithFields(log.Fields{
+                "expected value": uint8(0),
+                "got value": reserved,
+            }).Info("Got unexpected response.")
+        }
+    }
+
+    // Simple Field (destinationSpecified)
+    destinationSpecified, _destinationSpecifiedErr := io.ReadBit()
+    if _destinationSpecifiedErr != nil {
+        return nil, errors.New("Error parsing 'destinationSpecified' field " + _destinationSpecifiedErr.Error())
+    }
+
+    // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+    {
+        reserved, _err := io.ReadUint8(1)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'reserved' field " + _err.Error())
+        }
+        if reserved != uint8(0) {
+            log.WithFields(log.Fields{
+                "expected value": uint8(0),
+                "got value": reserved,
+            }).Info("Got unexpected response.")
+        }
+    }
+
+    // Simple Field (sourceSpecified)
+    sourceSpecified, _sourceSpecifiedErr := io.ReadBit()
+    if _sourceSpecifiedErr != nil {
+        return nil, errors.New("Error parsing 'sourceSpecified' field " + _sourceSpecifiedErr.Error())
+    }
+
+    // Simple Field (expectingReply)
+    expectingReply, _expectingReplyErr := io.ReadBit()
+    if _expectingReplyErr != nil {
+        return nil, errors.New("Error parsing 'expectingReply' field " + _expectingReplyErr.Error())
+    }
+
+    // Simple Field (networkPriority)
+    networkPriority, _networkPriorityErr := io.ReadUint8(2)
+    if _networkPriorityErr != nil {
+        return nil, errors.New("Error parsing 'networkPriority' field " + _networkPriorityErr.Error())
+    }
+
+    // Optional Field (destinationNetworkAddress) (Can be skipped, if a given expression evaluates to false)
+    var destinationNetworkAddress *uint16 = nil
+    if destinationSpecified {
+        _val, _err := io.ReadUint16(16)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'destinationNetworkAddress' field " + _err.Error())
+        }
+
+        destinationNetworkAddress = &_val
+    }
+
+    // Optional Field (destinationLength) (Can be skipped, if a given expression evaluates to false)
+    var destinationLength *uint8 = nil
+    if destinationSpecified {
+        _val, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'destinationLength' field " + _err.Error())
+        }
+
+        destinationLength = &_val
+    }
+
+    // Array field (destinationAddress)
+    // Count array
+    destinationAddress := make([]uint8, utils.InlineIf(destinationSpecified, uint16((*destinationLength)), uint16(uint16(0))))
+    for curItem := uint16(0); curItem < uint16(utils.InlineIf(destinationSpecified, uint16((*destinationLength)), uint16(uint16(0)))); curItem++ {
+
+        _item, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'destinationAddress' field " + _err.Error())
+        }
+        destinationAddress[curItem] = _item
+    }
+
+    // Optional Field (sourceNetworkAddress) (Can be skipped, if a given expression evaluates to false)
+    var sourceNetworkAddress *uint16 = nil
+    if sourceSpecified {
+        _val, _err := io.ReadUint16(16)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'sourceNetworkAddress' field " + _err.Error())
+        }
+
+        sourceNetworkAddress = &_val
+    }
+
+    // Optional Field (sourceLength) (Can be skipped, if a given expression evaluates to false)
+    var sourceLength *uint8 = nil
+    if sourceSpecified {
+        _val, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'sourceLength' field " + _err.Error())
+        }
+
+        sourceLength = &_val
+    }
+
+    // Array field (sourceAddress)
+    // Count array
+    sourceAddress := make([]uint8, utils.InlineIf(sourceSpecified, uint16((*sourceLength)), uint16(uint16(0))))
+    for curItem := uint16(0); curItem < uint16(utils.InlineIf(sourceSpecified, uint16((*sourceLength)), uint16(uint16(0)))); curItem++ {
+
+        _item, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'sourceAddress' field " + _err.Error())
+        }
+        sourceAddress[curItem] = _item
+    }
+
+    // Optional Field (hopCount) (Can be skipped, if a given expression evaluates to false)
+    var hopCount *uint8 = nil
+    if destinationSpecified {
+        _val, _err := io.ReadUint8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'hopCount' field " + _err.Error())
+        }
+
+        hopCount = &_val
+    }
+
+    // Optional Field (nlm) (Can be skipped, if a given expression evaluates to false)
+    var nlm *INLM = nil
+    if messageTypeFieldPresent {
+        _message, _err := NLMParse(io, uint16(npduLength) - uint16(uint16(uint16(uint16(uint16(uint16(2)) + uint16(uint16(utils.InlineIf(sourceSpecified, uint16(uint16(uint16(3)) + uint16((*sourceLength))), uint16(uint16(0)))))) + uint16(uint16(utils.InlineIf(destinationSpecified, uint16(uint16(uint16(3)) + uint16((*destinationLength))), uint16(uint16(0)))))) + uint16(uint16(utils.InlineIf(bool(bool(destinationSpecified) || bool(sourceSpecified)), uint16(uint16(1)), uint16(uint16(0))))))))
+        if _err != nil {
+            return nil, errors.New("Error parsing 'nlm' field " + _err.Error())
+        }
+        var _item INLM
+        _item, _ok := _message.(INLM)
+        if !_ok {
+            return nil, errors.New("Couldn't cast message of type " + reflect.TypeOf(_item).Name() + " to INLM")
+        }
+        nlm = &_item
+    }
+
+    // Optional Field (apdu) (Can be skipped, if a given expression evaluates to false)
+    var apdu *IAPDU = nil
+    if !(messageTypeFieldPresent) {
+        _message, _err := APDUParse(io, uint16(npduLength) - uint16(uint16(uint16(uint16(uint16(uint16(2)) + uint16(uint16(utils.InlineIf(sourceSpecified, uint16(uint16(uint16(3)) + uint16((*sourceLength))), uint16(uint16(0)))))) + uint16(uint16(utils.InlineIf(destinationSpecified, uint16(uint16(uint16(3)) + uint16((*destinationLength))), uint16(uint16(0)))))) + uint16(uint16(utils.InlineIf(bool(bool(destinationSpecified) || bool(sourceSpecified)), uint16(uint16(1)), uint16(uint16(0))))))))
+        if _err != nil {
+            return nil, errors.New("Error parsing 'apdu' field " + _err.Error())
+        }
+        var _item IAPDU
+        _item, _ok := _message.(IAPDU)
+        if !_ok {
+            return nil, errors.New("Couldn't cast message of type " + reflect.TypeOf(_item).Name() + " to IAPDU")
+        }
+        apdu = &_item
+    }
+
+    // Create the instance
+    return NewNPDU(protocolVersionNumber, messageTypeFieldPresent, destinationSpecified, sourceSpecified, expectingReply, networkPriority, destinationNetworkAddress, destinationLength, destinationAddress, sourceNetworkAddress, sourceLength, sourceAddress, hopCount, nlm, apdu), nil
+}
+
+func (m NPDU) Serialize(io utils.WriteBuffer) error {
+
+    // Simple Field (protocolVersionNumber)
+    protocolVersionNumber := uint8(m.ProtocolVersionNumber)
+    _protocolVersionNumberErr := io.WriteUint8(8, (protocolVersionNumber))
+    if _protocolVersionNumberErr != nil {
+        return errors.New("Error serializing 'protocolVersionNumber' field " + _protocolVersionNumberErr.Error())
+    }
+
+    // Simple Field (messageTypeFieldPresent)
+    messageTypeFieldPresent := bool(m.MessageTypeFieldPresent)
+    _messageTypeFieldPresentErr := io.WriteBit((messageTypeFieldPresent))
+    if _messageTypeFieldPresentErr != nil {
+        return errors.New("Error serializing 'messageTypeFieldPresent' field " + _messageTypeFieldPresentErr.Error())
+    }
+
+    // Reserved Field (reserved)
+    {
+        _err := io.WriteUint8(1, uint8(0))
+        if _err != nil {
+            return errors.New("Error serializing 'reserved' field " + _err.Error())
+        }
+    }
+
+    // Simple Field (destinationSpecified)
+    destinationSpecified := bool(m.DestinationSpecified)
+    _destinationSpecifiedErr := io.WriteBit((destinationSpecified))
+    if _destinationSpecifiedErr != nil {
+        return errors.New("Error serializing 'destinationSpecified' field " + _destinationSpecifiedErr.Error())
+    }
+
+    // Reserved Field (reserved)
+    {
+        _err := io.WriteUint8(1, uint8(0))
+        if _err != nil {
+            return errors.New("Error serializing 'reserved' field " + _err.Error())
+        }
+    }
+
+    // Simple Field (sourceSpecified)
+    sourceSpecified := bool(m.SourceSpecified)
+    _sourceSpecifiedErr := io.WriteBit((sourceSpecified))
+    if _sourceSpecifiedErr != nil {
+        return errors.New("Error serializing 'sourceSpecified' field " + _sourceSpecifiedErr.Error())
+    }
+
+    // Simple Field (expectingReply)
+    expectingReply := bool(m.ExpectingReply)
+    _expectingReplyErr := io.WriteBit((expectingReply))
+    if _expectingReplyErr != nil {
+        return errors.New("Error serializing 'expectingReply' field " + _expectingReplyErr.Error())
+    }
+
+    // Simple Field (networkPriority)
+    networkPriority := uint8(m.NetworkPriority)
+    _networkPriorityErr := io.WriteUint8(2, (networkPriority))
+    if _networkPriorityErr != nil {
+        return errors.New("Error serializing 'networkPriority' field " + _networkPriorityErr.Error())
+    }
+
+    // Optional Field (destinationNetworkAddress) (Can be skipped, if the value is null)
+    var destinationNetworkAddress *uint16 = nil
+    if m.DestinationNetworkAddress != nil {
+        destinationNetworkAddress = m.DestinationNetworkAddress
+        _destinationNetworkAddressErr := io.WriteUint16(16, *(destinationNetworkAddress))
+        if _destinationNetworkAddressErr != nil {
+            return errors.New("Error serializing 'destinationNetworkAddress' field " + _destinationNetworkAddressErr.Error())
+        }
+    }
+
+    // Optional Field (destinationLength) (Can be skipped, if the value is null)
+    var destinationLength *uint8 = nil
+    if m.DestinationLength != nil {
+        destinationLength = m.DestinationLength
+        _destinationLengthErr := io.WriteUint8(8, *(destinationLength))
+        if _destinationLengthErr != nil {
+            return errors.New("Error serializing 'destinationLength' field " + _destinationLengthErr.Error())
+        }
+    }
+
+    // Array Field (destinationAddress)
+    if m.DestinationAddress != nil {
+        for _, _element := range m.DestinationAddress {
+            _elementErr := io.WriteUint8(8, _element)
+            if _elementErr != nil {
+                return errors.New("Error serializing 'destinationAddress' field " + _elementErr.Error())
+            }
+        }
+    }
+
+    // Optional Field (sourceNetworkAddress) (Can be skipped, if the value is null)
+    var sourceNetworkAddress *uint16 = nil
+    if m.SourceNetworkAddress != nil {
+        sourceNetworkAddress = m.SourceNetworkAddress
+        _sourceNetworkAddressErr := io.WriteUint16(16, *(sourceNetworkAddress))
+        if _sourceNetworkAddressErr != nil {
+            return errors.New("Error serializing 'sourceNetworkAddress' field " + _sourceNetworkAddressErr.Error())
+        }
+    }
+
+    // Optional Field (sourceLength) (Can be skipped, if the value is null)
+    var sourceLength *uint8 = nil
+    if m.SourceLength != nil {
+        sourceLength = m.SourceLength
+        _sourceLengthErr := io.WriteUint8(8, *(sourceLength))
+        if _sourceLengthErr != nil {
+            return errors.New("Error serializing 'sourceLength' field " + _sourceLengthErr.Error())
+        }
+    }
+
+    // Array Field (sourceAddress)
+    if m.SourceAddress != nil {
+        for _, _element := range m.SourceAddress {
+            _elementErr := io.WriteUint8(8, _element)
+            if _elementErr != nil {
+                return errors.New("Error serializing 'sourceAddress' field " + _elementErr.Error())
+            }
+        }
+    }
+
+    // Optional Field (hopCount) (Can be skipped, if the value is null)
+    var hopCount *uint8 = nil
+    if m.HopCount != nil {
+        hopCount = m.HopCount
+        _hopCountErr := io.WriteUint8(8, *(hopCount))
+        if _hopCountErr != nil {
+            return errors.New("Error serializing 'hopCount' field " + _hopCountErr.Error())
+        }
+    }
+
+    // Optional Field (nlm) (Can be skipped, if the value is null)
+    var nlm *INLM = nil
+    if m.Nlm != nil {
+        nlm = m.Nlm
+        _nlmErr := CastINLM(*nlm).Serialize(io)
+        if _nlmErr != nil {
+            return errors.New("Error serializing 'nlm' field " + _nlmErr.Error())
+        }
+    }
+
+    // Optional Field (apdu) (Can be skipped, if the value is null)
+    var apdu *IAPDU = nil
+    if m.Apdu != nil {
+        apdu = m.Apdu
+        _apduErr := CastIAPDU(*apdu).Serialize(io)
+        if _apduErr != nil {
+            return errors.New("Error serializing 'apdu' field " + _apduErr.Error())
+        }
+    }
+
+    return nil
+}
+
+func (m *NPDU) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "protocolVersionNumber":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ProtocolVersionNumber = data
+            case "messageTypeFieldPresent":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.MessageTypeFieldPresent = data
+            case "destinationSpecified":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DestinationSpecified = data
+            case "sourceSpecified":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SourceSpecified = data
+            case "expectingReply":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ExpectingReply = data
+            case "networkPriority":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.NetworkPriority = data
+            case "destinationNetworkAddress":
+                var data *uint16
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DestinationNetworkAddress = data
+            case "destinationLength":
+                var data *uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DestinationLength = data
+            case "destinationAddress":
+                var data []uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DestinationAddress = data
+            case "sourceNetworkAddress":
+                var data *uint16
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SourceNetworkAddress = data
+            case "sourceLength":
+                var data *uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SourceLength = data
+            case "sourceAddress":
+                var data []uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SourceAddress = data
+            case "hopCount":
+                var data *uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.HopCount = data
+            case "nlm":
+                switch tok.Attr[0].Value {
+                    case "org.apache.plc4x.java.bacnetip.readwrite.NLMWhoIsRouterToNetwork":
+                        var dt *NLMWhoIsRouterToNetwork
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Nlm = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.NLMIAmRouterToNetwork":
+                        var dt *NLMIAmRouterToNetwork
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Nlm = dt
+                    }
+            case "apdu":
+                switch tok.Attr[0].Value {
+                    case "org.apache.plc4x.java.bacnetip.readwrite.APDUConfirmedRequest":
+                        var dt *APDUConfirmedRequest
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Apdu = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.APDUUnconfirmedRequest":
+                        var dt *APDUUnconfirmedRequest
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Apdu = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.APDUSimpleAck":
+                        var dt *APDUSimpleAck
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Apdu = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.APDUComplexAck":
+                        var dt *APDUComplexAck
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Apdu = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.APDUSegmentAck":
+                        var dt *APDUSegmentAck
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Apdu = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.APDUError":
+                        var dt *APDUError
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Apdu = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.APDUReject":
+                        var dt *APDUReject
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Apdu = dt
+                    case "org.apache.plc4x.java.bacnetip.readwrite.APDUAbort":
+                        var dt *APDUAbort
+                        if err := d.DecodeElement(&dt, &tok); err != nil {
+                            return err
+                        }
+                        *m.Apdu = dt
+                    }
+            }
+        }
+    }
+}
+
+func (m NPDU) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.bacnetip.readwrite.NPDU"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ProtocolVersionNumber, xml.StartElement{Name: xml.Name{Local: "protocolVersionNumber"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.MessageTypeFieldPresent, xml.StartElement{Name: xml.Name{Local: "messageTypeFieldPresent"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DestinationSpecified, xml.StartElement{Name: xml.Name{Local: "destinationSpecified"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SourceSpecified, xml.StartElement{Name: xml.Name{Local: "sourceSpecified"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ExpectingReply, xml.StartElement{Name: xml.Name{Local: "expectingReply"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.NetworkPriority, xml.StartElement{Name: xml.Name{Local: "networkPriority"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DestinationNetworkAddress, xml.StartElement{Name: xml.Name{Local: "destinationNetworkAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DestinationLength, xml.StartElement{Name: xml.Name{Local: "destinationLength"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.StartElement{Name: xml.Name{Local: "destinationAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DestinationAddress, xml.StartElement{Name: xml.Name{Local: "destinationAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: xml.Name{Local: "destinationAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SourceNetworkAddress, xml.StartElement{Name: xml.Name{Local: "sourceNetworkAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SourceLength, xml.StartElement{Name: xml.Name{Local: "sourceLength"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.StartElement{Name: xml.Name{Local: "sourceAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SourceAddress, xml.StartElement{Name: xml.Name{Local: "sourceAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: xml.Name{Local: "sourceAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.HopCount, xml.StartElement{Name: xml.Name{Local: "hopCount"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Nlm, xml.StartElement{Name: xml.Name{Local: "nlm"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Apdu, xml.StartElement{Name: xml.Name{Local: "apdu"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/ParserHelper.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/ParserHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/ParserHelper.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/ParserHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/XmlParserHelper.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/XmlParserHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/XmlParserHelper.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/XmlParserHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/KnxNetIpDriver.go b/plc4go/internal/plc4go/knxnetip/KnxNetIpDriver.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/KnxNetIpDriver.go
rename to plc4go/internal/plc4go/knxnetip/KnxNetIpDriver.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/APCI.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/APCI.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/APCI.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/APCI.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMI.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMI.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMI.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMI.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformation.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformation.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformation.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformation.go
diff --git a/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.go
new file mode 100644
index 0000000..9627ff5
--- /dev/null
+++ b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformationBusmonitorInfo.go
@@ -0,0 +1,307 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    "strconv"
+)
+
+// Constant values.
+const CEMIAdditionalInformationBusmonitorInfo_LEN uint8 = 1
+
+// The data-structure of this message
+type CEMIAdditionalInformationBusmonitorInfo struct {
+    FrameErrorFlag bool
+    BitErrorFlag bool
+    ParityErrorFlag bool
+    UnknownFlag bool
+    LostFlag bool
+    SequenceNumber uint8
+    CEMIAdditionalInformation
+}
+
+// The corresponding interface
+type ICEMIAdditionalInformationBusmonitorInfo interface {
+    ICEMIAdditionalInformation
+    Serialize(io utils.WriteBuffer) error
+}
+
+// Accessors for discriminator values.
+func (m CEMIAdditionalInformationBusmonitorInfo) AdditionalInformationType() uint8 {
+    return 0x03
+}
+
+func (m CEMIAdditionalInformationBusmonitorInfo) initialize() spi.Message {
+    return m
+}
+
+func NewCEMIAdditionalInformationBusmonitorInfo(frameErrorFlag bool, bitErrorFlag bool, parityErrorFlag bool, unknownFlag bool, lostFlag bool, sequenceNumber uint8) CEMIAdditionalInformationInitializer {
+    return &CEMIAdditionalInformationBusmonitorInfo{FrameErrorFlag: frameErrorFlag, BitErrorFlag: bitErrorFlag, ParityErrorFlag: parityErrorFlag, UnknownFlag: unknownFlag, LostFlag: lostFlag, SequenceNumber: sequenceNumber}
+}
+
+func CastICEMIAdditionalInformationBusmonitorInfo(structType interface{}) ICEMIAdditionalInformationBusmonitorInfo {
+    castFunc := func(typ interface{}) ICEMIAdditionalInformationBusmonitorInfo {
+        if iCEMIAdditionalInformationBusmonitorInfo, ok := typ.(ICEMIAdditionalInformationBusmonitorInfo); ok {
+            return iCEMIAdditionalInformationBusmonitorInfo
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastCEMIAdditionalInformationBusmonitorInfo(structType interface{}) CEMIAdditionalInformationBusmonitorInfo {
+    castFunc := func(typ interface{}) CEMIAdditionalInformationBusmonitorInfo {
+        if sCEMIAdditionalInformationBusmonitorInfo, ok := typ.(CEMIAdditionalInformationBusmonitorInfo); ok {
+            return sCEMIAdditionalInformationBusmonitorInfo
+        }
+        if sCEMIAdditionalInformationBusmonitorInfo, ok := typ.(*CEMIAdditionalInformationBusmonitorInfo); ok {
+            return *sCEMIAdditionalInformationBusmonitorInfo
+        }
+        return CEMIAdditionalInformationBusmonitorInfo{}
+    }
+    return castFunc(structType)
+}
+
+func (m CEMIAdditionalInformationBusmonitorInfo) LengthInBits() uint16 {
+    var lengthInBits uint16 = m.CEMIAdditionalInformation.LengthInBits()
+
+    // Const Field (len)
+    lengthInBits += 8
+
+    // Simple field (frameErrorFlag)
+    lengthInBits += 1
+
+    // Simple field (bitErrorFlag)
+    lengthInBits += 1
+
+    // Simple field (parityErrorFlag)
+    lengthInBits += 1
+
+    // Simple field (unknownFlag)
+    lengthInBits += 1
+
+    // Simple field (lostFlag)
+    lengthInBits += 1
+
+    // Simple field (sequenceNumber)
+    lengthInBits += 3
+
+    return lengthInBits
+}
+
+func (m CEMIAdditionalInformationBusmonitorInfo) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func CEMIAdditionalInformationBusmonitorInfoParse(io *utils.ReadBuffer) (CEMIAdditionalInformationInitializer, error) {
+
+    // Const Field (len)
+    len, _lenErr := io.ReadUint8(8)
+    if _lenErr != nil {
+        return nil, errors.New("Error parsing 'len' field " + _lenErr.Error())
+    }
+    if len != CEMIAdditionalInformationBusmonitorInfo_LEN {
+        return nil, errors.New("Expected constant value " + strconv.Itoa(int(CEMIAdditionalInformationBusmonitorInfo_LEN)) + " but got " + strconv.Itoa(int(len)))
+    }
+
+    // Simple Field (frameErrorFlag)
+    frameErrorFlag, _frameErrorFlagErr := io.ReadBit()
+    if _frameErrorFlagErr != nil {
+        return nil, errors.New("Error parsing 'frameErrorFlag' field " + _frameErrorFlagErr.Error())
+    }
+
+    // Simple Field (bitErrorFlag)
+    bitErrorFlag, _bitErrorFlagErr := io.ReadBit()
+    if _bitErrorFlagErr != nil {
+        return nil, errors.New("Error parsing 'bitErrorFlag' field " + _bitErrorFlagErr.Error())
+    }
+
+    // Simple Field (parityErrorFlag)
+    parityErrorFlag, _parityErrorFlagErr := io.ReadBit()
+    if _parityErrorFlagErr != nil {
+        return nil, errors.New("Error parsing 'parityErrorFlag' field " + _parityErrorFlagErr.Error())
+    }
+
+    // Simple Field (unknownFlag)
+    unknownFlag, _unknownFlagErr := io.ReadBit()
+    if _unknownFlagErr != nil {
+        return nil, errors.New("Error parsing 'unknownFlag' field " + _unknownFlagErr.Error())
+    }
+
+    // Simple Field (lostFlag)
+    lostFlag, _lostFlagErr := io.ReadBit()
+    if _lostFlagErr != nil {
+        return nil, errors.New("Error parsing 'lostFlag' field " + _lostFlagErr.Error())
+    }
+
+    // Simple Field (sequenceNumber)
+    sequenceNumber, _sequenceNumberErr := io.ReadUint8(3)
+    if _sequenceNumberErr != nil {
+        return nil, errors.New("Error parsing 'sequenceNumber' field " + _sequenceNumberErr.Error())
+    }
+
+    // Create the instance
+    return NewCEMIAdditionalInformationBusmonitorInfo(frameErrorFlag, bitErrorFlag, parityErrorFlag, unknownFlag, lostFlag, sequenceNumber), nil
+}
+
+func (m CEMIAdditionalInformationBusmonitorInfo) Serialize(io utils.WriteBuffer) error {
+    ser := func() error {
+
+    // Const Field (len)
+    _lenErr := io.WriteUint8(8, 1)
+    if _lenErr != nil {
+        return errors.New("Error serializing 'len' field " + _lenErr.Error())
+    }
+
+    // Simple Field (frameErrorFlag)
+    frameErrorFlag := bool(m.FrameErrorFlag)
+    _frameErrorFlagErr := io.WriteBit((frameErrorFlag))
+    if _frameErrorFlagErr != nil {
+        return errors.New("Error serializing 'frameErrorFlag' field " + _frameErrorFlagErr.Error())
+    }
+
+    // Simple Field (bitErrorFlag)
+    bitErrorFlag := bool(m.BitErrorFlag)
+    _bitErrorFlagErr := io.WriteBit((bitErrorFlag))
+    if _bitErrorFlagErr != nil {
+        return errors.New("Error serializing 'bitErrorFlag' field " + _bitErrorFlagErr.Error())
+    }
+
+    // Simple Field (parityErrorFlag)
+    parityErrorFlag := bool(m.ParityErrorFlag)
+    _parityErrorFlagErr := io.WriteBit((parityErrorFlag))
+    if _parityErrorFlagErr != nil {
+        return errors.New("Error serializing 'parityErrorFlag' field " + _parityErrorFlagErr.Error())
+    }
+
+    // Simple Field (unknownFlag)
+    unknownFlag := bool(m.UnknownFlag)
+    _unknownFlagErr := io.WriteBit((unknownFlag))
+    if _unknownFlagErr != nil {
+        return errors.New("Error serializing 'unknownFlag' field " + _unknownFlagErr.Error())
+    }
+
+    // Simple Field (lostFlag)
+    lostFlag := bool(m.LostFlag)
+    _lostFlagErr := io.WriteBit((lostFlag))
+    if _lostFlagErr != nil {
+        return errors.New("Error serializing 'lostFlag' field " + _lostFlagErr.Error())
+    }
+
+    // Simple Field (sequenceNumber)
+    sequenceNumber := uint8(m.SequenceNumber)
+    _sequenceNumberErr := io.WriteUint8(3, (sequenceNumber))
+    if _sequenceNumberErr != nil {
+        return errors.New("Error serializing 'sequenceNumber' field " + _sequenceNumberErr.Error())
+    }
+
+        return nil
+    }
+    return CEMIAdditionalInformationSerialize(io, m.CEMIAdditionalInformation, CastICEMIAdditionalInformation(m), ser)
+}
+
+func (m *CEMIAdditionalInformationBusmonitorInfo) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "frameErrorFlag":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.FrameErrorFlag = data
+            case "bitErrorFlag":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.BitErrorFlag = data
+            case "parityErrorFlag":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ParityErrorFlag = data
+            case "unknownFlag":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.UnknownFlag = data
+            case "lostFlag":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.LostFlag = data
+            case "sequenceNumber":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SequenceNumber = data
+            }
+        }
+    }
+}
+
+func (m CEMIAdditionalInformationBusmonitorInfo) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.knxnetip.readwrite.CEMIAdditionalInformationBusmonitorInfo"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.FrameErrorFlag, xml.StartElement{Name: xml.Name{Local: "frameErrorFlag"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.BitErrorFlag, xml.StartElement{Name: xml.Name{Local: "bitErrorFlag"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ParityErrorFlag, xml.StartElement{Name: xml.Name{Local: "parityErrorFlag"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.UnknownFlag, xml.StartElement{Name: xml.Name{Local: "unknownFlag"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.LostFlag, xml.StartElement{Name: xml.Name{Local: "lostFlag"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SequenceNumber, xml.StartElement{Name: xml.Name{Local: "sequenceNumber"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIAdditionalInformationRelativeTimestamp.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIBusmonInd.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIBusmonInd.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIBusmonInd.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIBusmonInd.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataCon.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataCon.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataCon.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataCon.go
diff --git a/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataFrame.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataFrame.go
new file mode 100644
index 0000000..940c33e
--- /dev/null
+++ b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataFrame.go
@@ -0,0 +1,629 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/base64"
+    "encoding/xml"
+    "errors"
+    "io"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    "reflect"
+)
+
+// The data-structure of this message
+type CEMIDataFrame struct {
+    StandardFrame bool
+    Polling bool
+    NotRepeated bool
+    NotAckFrame bool
+    Priority ICEMIPriority
+    AcknowledgeRequested bool
+    ErrorFlag bool
+    GroupDestinationAddress bool
+    HopCount uint8
+    ExtendedFrameFormat uint8
+    SourceAddress IKNXAddress
+    DestinationAddress []int8
+    DataLength uint8
+    Tcpi ITPCI
+    Counter uint8
+    Apci IAPCI
+    DataFirstByte int8
+    Data []int8
+
+}
+
+// The corresponding interface
+type ICEMIDataFrame interface {
+    spi.Message
+    Serialize(io utils.WriteBuffer) error
+}
+
+
+func NewCEMIDataFrame(standardFrame bool, polling bool, notRepeated bool, notAckFrame bool, priority ICEMIPriority, acknowledgeRequested bool, errorFlag bool, groupDestinationAddress bool, hopCount uint8, extendedFrameFormat uint8, sourceAddress IKNXAddress, destinationAddress []int8, dataLength uint8, tcpi ITPCI, counter uint8, apci IAPCI, dataFirstByte int8, data []int8) spi.Message {
+    return &CEMIDataFrame{StandardFrame: standardFrame, Polling: polling, NotRepeated: notRepeated, NotAckFrame: notAckFrame, Priority: priority, AcknowledgeRequested: acknowledgeRequested, ErrorFlag: errorFlag, GroupDestinationAddress: groupDestinationAddress, HopCount: hopCount, ExtendedFrameFormat: extendedFrameFormat, SourceAddress: sourceAddress, DestinationAddress: destinationAddress, DataLength: dataLength, Tcpi: tcpi, Counter: counter, Apci: apci, DataFirstByte: dataFirstByte, Da [...]
+}
+
+func CastICEMIDataFrame(structType interface{}) ICEMIDataFrame {
+    castFunc := func(typ interface{}) ICEMIDataFrame {
+        if iCEMIDataFrame, ok := typ.(ICEMIDataFrame); ok {
+            return iCEMIDataFrame
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastCEMIDataFrame(structType interface{}) CEMIDataFrame {
+    castFunc := func(typ interface{}) CEMIDataFrame {
+        if sCEMIDataFrame, ok := typ.(CEMIDataFrame); ok {
+            return sCEMIDataFrame
+        }
+        if sCEMIDataFrame, ok := typ.(*CEMIDataFrame); ok {
+            return *sCEMIDataFrame
+        }
+        return CEMIDataFrame{}
+    }
+    return castFunc(structType)
+}
+
+func (m CEMIDataFrame) LengthInBits() uint16 {
+    var lengthInBits uint16 = 0
+
+    // Simple field (standardFrame)
+    lengthInBits += 1
+
+    // Simple field (polling)
+    lengthInBits += 1
+
+    // Simple field (notRepeated)
+    lengthInBits += 1
+
+    // Simple field (notAckFrame)
+    lengthInBits += 1
+
+    // Enum Field (priority)
+    lengthInBits += 2
+
+    // Simple field (acknowledgeRequested)
+    lengthInBits += 1
+
+    // Simple field (errorFlag)
+    lengthInBits += 1
+
+    // Simple field (groupDestinationAddress)
+    lengthInBits += 1
+
+    // Simple field (hopCount)
+    lengthInBits += 3
+
+    // Simple field (extendedFrameFormat)
+    lengthInBits += 4
+
+    // Simple field (sourceAddress)
+    lengthInBits += m.SourceAddress.LengthInBits()
+
+    // Array field
+    if len(m.DestinationAddress) > 0 {
+        lengthInBits += 8 * uint16(len(m.DestinationAddress))
+    }
+
+    // Simple field (dataLength)
+    lengthInBits += 8
+
+    // Enum Field (tcpi)
+    lengthInBits += 2
+
+    // Simple field (counter)
+    lengthInBits += 4
+
+    // Enum Field (apci)
+    lengthInBits += 4
+
+    // Simple field (dataFirstByte)
+    lengthInBits += 6
+
+    // Array field
+    if len(m.Data) > 0 {
+        lengthInBits += 8 * uint16(len(m.Data))
+    }
+
+    return lengthInBits
+}
+
+func (m CEMIDataFrame) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func CEMIDataFrameParse(io *utils.ReadBuffer) (spi.Message, error) {
+
+    // Simple Field (standardFrame)
+    standardFrame, _standardFrameErr := io.ReadBit()
+    if _standardFrameErr != nil {
+        return nil, errors.New("Error parsing 'standardFrame' field " + _standardFrameErr.Error())
+    }
+
+    // Simple Field (polling)
+    polling, _pollingErr := io.ReadBit()
+    if _pollingErr != nil {
+        return nil, errors.New("Error parsing 'polling' field " + _pollingErr.Error())
+    }
+
+    // Simple Field (notRepeated)
+    notRepeated, _notRepeatedErr := io.ReadBit()
+    if _notRepeatedErr != nil {
+        return nil, errors.New("Error parsing 'notRepeated' field " + _notRepeatedErr.Error())
+    }
+
+    // Simple Field (notAckFrame)
+    notAckFrame, _notAckFrameErr := io.ReadBit()
+    if _notAckFrameErr != nil {
+        return nil, errors.New("Error parsing 'notAckFrame' field " + _notAckFrameErr.Error())
+    }
+
+    // Enum field (priority)
+    priority, _priorityErr := CEMIPriorityParse(io)
+    if _priorityErr != nil {
+        return nil, errors.New("Error parsing 'priority' field " + _priorityErr.Error())
+    }
+
+    // Simple Field (acknowledgeRequested)
+    acknowledgeRequested, _acknowledgeRequestedErr := io.ReadBit()
+    if _acknowledgeRequestedErr != nil {
+        return nil, errors.New("Error parsing 'acknowledgeRequested' field " + _acknowledgeRequestedErr.Error())
+    }
+
+    // Simple Field (errorFlag)
+    errorFlag, _errorFlagErr := io.ReadBit()
+    if _errorFlagErr != nil {
+        return nil, errors.New("Error parsing 'errorFlag' field " + _errorFlagErr.Error())
+    }
+
+    // Simple Field (groupDestinationAddress)
+    groupDestinationAddress, _groupDestinationAddressErr := io.ReadBit()
+    if _groupDestinationAddressErr != nil {
+        return nil, errors.New("Error parsing 'groupDestinationAddress' field " + _groupDestinationAddressErr.Error())
+    }
+
+    // Simple Field (hopCount)
+    hopCount, _hopCountErr := io.ReadUint8(3)
+    if _hopCountErr != nil {
+        return nil, errors.New("Error parsing 'hopCount' field " + _hopCountErr.Error())
+    }
+
+    // Simple Field (extendedFrameFormat)
+    extendedFrameFormat, _extendedFrameFormatErr := io.ReadUint8(4)
+    if _extendedFrameFormatErr != nil {
+        return nil, errors.New("Error parsing 'extendedFrameFormat' field " + _extendedFrameFormatErr.Error())
+    }
+
+    // Simple Field (sourceAddress)
+    _sourceAddressMessage, _err := KNXAddressParse(io)
+    if _err != nil {
+        return nil, errors.New("Error parsing simple field 'sourceAddress'. " + _err.Error())
+    }
+    var sourceAddress IKNXAddress
+    sourceAddress, _sourceAddressOk := _sourceAddressMessage.(IKNXAddress)
+    if !_sourceAddressOk {
+        return nil, errors.New("Couldn't cast message of type " + reflect.TypeOf(_sourceAddressMessage).Name() + " to IKNXAddress")
+    }
+
+    // Array field (destinationAddress)
+    // Count array
+    destinationAddress := make([]int8, uint16(2))
+    for curItem := uint16(0); curItem < uint16(uint16(2)); curItem++ {
+
+        _item, _err := io.ReadInt8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'destinationAddress' field " + _err.Error())
+        }
+        destinationAddress[curItem] = _item
+    }
+
+    // Simple Field (dataLength)
+    dataLength, _dataLengthErr := io.ReadUint8(8)
+    if _dataLengthErr != nil {
+        return nil, errors.New("Error parsing 'dataLength' field " + _dataLengthErr.Error())
+    }
+
+    // Enum field (tcpi)
+    tcpi, _tcpiErr := TPCIParse(io)
+    if _tcpiErr != nil {
+        return nil, errors.New("Error parsing 'tcpi' field " + _tcpiErr.Error())
+    }
+
+    // Simple Field (counter)
+    counter, _counterErr := io.ReadUint8(4)
+    if _counterErr != nil {
+        return nil, errors.New("Error parsing 'counter' field " + _counterErr.Error())
+    }
+
+    // Enum field (apci)
+    apci, _apciErr := APCIParse(io)
+    if _apciErr != nil {
+        return nil, errors.New("Error parsing 'apci' field " + _apciErr.Error())
+    }
+
+    // Simple Field (dataFirstByte)
+    dataFirstByte, _dataFirstByteErr := io.ReadInt8(6)
+    if _dataFirstByteErr != nil {
+        return nil, errors.New("Error parsing 'dataFirstByte' field " + _dataFirstByteErr.Error())
+    }
+
+    // Array field (data)
+    // Count array
+    data := make([]int8, uint16(dataLength) - uint16(uint16(1)))
+    for curItem := uint16(0); curItem < uint16(uint16(dataLength) - uint16(uint16(1))); curItem++ {
+
+        _item, _err := io.ReadInt8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'data' field " + _err.Error())
+        }
+        data[curItem] = _item
+    }
+
+    // Create the instance
+    return NewCEMIDataFrame(standardFrame, polling, notRepeated, notAckFrame, priority, acknowledgeRequested, errorFlag, groupDestinationAddress, hopCount, extendedFrameFormat, sourceAddress, destinationAddress, dataLength, tcpi, counter, apci, dataFirstByte, data), nil
+}
+
+func (m CEMIDataFrame) Serialize(io utils.WriteBuffer) error {
+
+    // Simple Field (standardFrame)
+    standardFrame := bool(m.StandardFrame)
+    _standardFrameErr := io.WriteBit((standardFrame))
+    if _standardFrameErr != nil {
+        return errors.New("Error serializing 'standardFrame' field " + _standardFrameErr.Error())
+    }
+
+    // Simple Field (polling)
+    polling := bool(m.Polling)
+    _pollingErr := io.WriteBit((polling))
+    if _pollingErr != nil {
+        return errors.New("Error serializing 'polling' field " + _pollingErr.Error())
+    }
+
+    // Simple Field (notRepeated)
+    notRepeated := bool(m.NotRepeated)
+    _notRepeatedErr := io.WriteBit((notRepeated))
+    if _notRepeatedErr != nil {
+        return errors.New("Error serializing 'notRepeated' field " + _notRepeatedErr.Error())
+    }
+
+    // Simple Field (notAckFrame)
+    notAckFrame := bool(m.NotAckFrame)
+    _notAckFrameErr := io.WriteBit((notAckFrame))
+    if _notAckFrameErr != nil {
+        return errors.New("Error serializing 'notAckFrame' field " + _notAckFrameErr.Error())
+    }
+
+    // Enum field (priority)
+    priority := CastCEMIPriority(m.Priority)
+    _priorityErr := priority.Serialize(io)
+    if _priorityErr != nil {
+        return errors.New("Error serializing 'priority' field " + _priorityErr.Error())
+    }
+
+    // Simple Field (acknowledgeRequested)
+    acknowledgeRequested := bool(m.AcknowledgeRequested)
+    _acknowledgeRequestedErr := io.WriteBit((acknowledgeRequested))
+    if _acknowledgeRequestedErr != nil {
+        return errors.New("Error serializing 'acknowledgeRequested' field " + _acknowledgeRequestedErr.Error())
+    }
+
+    // Simple Field (errorFlag)
+    errorFlag := bool(m.ErrorFlag)
+    _errorFlagErr := io.WriteBit((errorFlag))
+    if _errorFlagErr != nil {
+        return errors.New("Error serializing 'errorFlag' field " + _errorFlagErr.Error())
+    }
+
+    // Simple Field (groupDestinationAddress)
+    groupDestinationAddress := bool(m.GroupDestinationAddress)
+    _groupDestinationAddressErr := io.WriteBit((groupDestinationAddress))
+    if _groupDestinationAddressErr != nil {
+        return errors.New("Error serializing 'groupDestinationAddress' field " + _groupDestinationAddressErr.Error())
+    }
+
+    // Simple Field (hopCount)
+    hopCount := uint8(m.HopCount)
+    _hopCountErr := io.WriteUint8(3, (hopCount))
+    if _hopCountErr != nil {
+        return errors.New("Error serializing 'hopCount' field " + _hopCountErr.Error())
+    }
+
+    // Simple Field (extendedFrameFormat)
+    extendedFrameFormat := uint8(m.ExtendedFrameFormat)
+    _extendedFrameFormatErr := io.WriteUint8(4, (extendedFrameFormat))
+    if _extendedFrameFormatErr != nil {
+        return errors.New("Error serializing 'extendedFrameFormat' field " + _extendedFrameFormatErr.Error())
+    }
+
+    // Simple Field (sourceAddress)
+    sourceAddress := CastIKNXAddress(m.SourceAddress)
+    _sourceAddressErr := sourceAddress.Serialize(io)
+    if _sourceAddressErr != nil {
+        return errors.New("Error serializing 'sourceAddress' field " + _sourceAddressErr.Error())
+    }
+
+    // Array Field (destinationAddress)
+    if m.DestinationAddress != nil {
+        for _, _element := range m.DestinationAddress {
+            _elementErr := io.WriteInt8(8, _element)
+            if _elementErr != nil {
+                return errors.New("Error serializing 'destinationAddress' field " + _elementErr.Error())
+            }
+        }
+    }
+
+    // Simple Field (dataLength)
+    dataLength := uint8(m.DataLength)
+    _dataLengthErr := io.WriteUint8(8, (dataLength))
+    if _dataLengthErr != nil {
+        return errors.New("Error serializing 'dataLength' field " + _dataLengthErr.Error())
+    }
+
+    // Enum field (tcpi)
+    tcpi := CastTPCI(m.Tcpi)
+    _tcpiErr := tcpi.Serialize(io)
+    if _tcpiErr != nil {
+        return errors.New("Error serializing 'tcpi' field " + _tcpiErr.Error())
+    }
+
+    // Simple Field (counter)
+    counter := uint8(m.Counter)
+    _counterErr := io.WriteUint8(4, (counter))
+    if _counterErr != nil {
+        return errors.New("Error serializing 'counter' field " + _counterErr.Error())
+    }
+
+    // Enum field (apci)
+    apci := CastAPCI(m.Apci)
+    _apciErr := apci.Serialize(io)
+    if _apciErr != nil {
+        return errors.New("Error serializing 'apci' field " + _apciErr.Error())
+    }
+
+    // Simple Field (dataFirstByte)
+    dataFirstByte := int8(m.DataFirstByte)
+    _dataFirstByteErr := io.WriteInt8(6, (dataFirstByte))
+    if _dataFirstByteErr != nil {
+        return errors.New("Error serializing 'dataFirstByte' field " + _dataFirstByteErr.Error())
+    }
+
+    // Array Field (data)
+    if m.Data != nil {
+        for _, _element := range m.Data {
+            _elementErr := io.WriteInt8(8, _element)
+            if _elementErr != nil {
+                return errors.New("Error serializing 'data' field " + _elementErr.Error())
+            }
+        }
+    }
+
+    return nil
+}
+
+func (m *CEMIDataFrame) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "standardFrame":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.StandardFrame = data
+            case "polling":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Polling = data
+            case "notRepeated":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.NotRepeated = data
+            case "notAckFrame":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.NotAckFrame = data
+            case "priority":
+                var data *CEMIPriority
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Priority = data
+            case "acknowledgeRequested":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.AcknowledgeRequested = data
+            case "errorFlag":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ErrorFlag = data
+            case "groupDestinationAddress":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.GroupDestinationAddress = data
+            case "hopCount":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.HopCount = data
+            case "extendedFrameFormat":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ExtendedFrameFormat = data
+            case "sourceAddress":
+                var data *KNXAddress
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SourceAddress = CastIKNXAddress(data)
+            case "destinationAddress":
+                var _encoded string
+                if err := d.DecodeElement(&_encoded, &tok); err != nil {
+                    return err
+                }
+                _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+                _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+                if err != nil {
+                    return err
+                }
+                m.DestinationAddress = utils.ByteToInt8(_decoded[0:_len])
+            case "dataLength":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DataLength = data
+            case "tcpi":
+                var data *TPCI
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Tcpi = data
+            case "counter":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Counter = data
+            case "apci":
+                var data *APCI
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Apci = data
+            case "dataFirstByte":
+                var data int8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DataFirstByte = data
+            case "data":
+                var _encoded string
+                if err := d.DecodeElement(&_encoded, &tok); err != nil {
+                    return err
+                }
+                _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+                _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+                if err != nil {
+                    return err
+                }
+                m.Data = utils.ByteToInt8(_decoded[0:_len])
+            }
+        }
+    }
+}
+
+func (m CEMIDataFrame) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.knxnetip.readwrite.CEMIDataFrame"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.StandardFrame, xml.StartElement{Name: xml.Name{Local: "standardFrame"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Polling, xml.StartElement{Name: xml.Name{Local: "polling"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.NotRepeated, xml.StartElement{Name: xml.Name{Local: "notRepeated"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.NotAckFrame, xml.StartElement{Name: xml.Name{Local: "notAckFrame"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Priority, xml.StartElement{Name: xml.Name{Local: "priority"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.AcknowledgeRequested, xml.StartElement{Name: xml.Name{Local: "acknowledgeRequested"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ErrorFlag, xml.StartElement{Name: xml.Name{Local: "errorFlag"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.GroupDestinationAddress, xml.StartElement{Name: xml.Name{Local: "groupDestinationAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.HopCount, xml.StartElement{Name: xml.Name{Local: "hopCount"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ExtendedFrameFormat, xml.StartElement{Name: xml.Name{Local: "extendedFrameFormat"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SourceAddress, xml.StartElement{Name: xml.Name{Local: "sourceAddress"}}); err != nil {
+        return err
+    }
+    _encodedDestinationAddress := make([]byte, base64.StdEncoding.EncodedLen(len(m.DestinationAddress)))
+    base64.StdEncoding.Encode(_encodedDestinationAddress, utils.Int8ToByte(m.DestinationAddress))
+    if err := e.EncodeElement(_encodedDestinationAddress, xml.StartElement{Name: xml.Name{Local: "destinationAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DataLength, xml.StartElement{Name: xml.Name{Local: "dataLength"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Tcpi, xml.StartElement{Name: xml.Name{Local: "tcpi"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Counter, xml.StartElement{Name: xml.Name{Local: "counter"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Apci, xml.StartElement{Name: xml.Name{Local: "apci"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DataFirstByte, xml.StartElement{Name: xml.Name{Local: "dataFirstByte"}}); err != nil {
+        return err
+    }
+    _encodedData := make([]byte, base64.StdEncoding.EncodedLen(len(m.Data)))
+    base64.StdEncoding.Encode(_encodedData, utils.Int8ToByte(m.Data))
+    if err := e.EncodeElement(_encodedData, xml.StartElement{Name: xml.Name{Local: "data"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataInd.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataInd.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataInd.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataInd.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataReq.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataReq.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataReq.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataReq.go
diff --git a/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrame.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrame.go
new file mode 100644
index 0000000..8737601
--- /dev/null
+++ b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrame.go
@@ -0,0 +1,312 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+// The data-structure of this message
+type CEMIFrame struct {
+    Repeated bool
+    Priority ICEMIPriority
+    AcknowledgeRequested bool
+    ErrorFlag bool
+
+}
+
+// The corresponding interface
+type ICEMIFrame interface {
+    spi.Message
+    NotAckFrame() bool
+    Polling() bool
+    StandardFrame() bool
+    Serialize(io utils.WriteBuffer) error
+}
+
+type CEMIFrameInitializer interface {
+    initialize(repeated bool, priority ICEMIPriority, acknowledgeRequested bool, errorFlag bool) spi.Message
+}
+
+func CEMIFrameNotAckFrame(m ICEMIFrame) bool {
+    return m.NotAckFrame()
+}
+
+func CEMIFramePolling(m ICEMIFrame) bool {
+    return m.Polling()
+}
+
+func CEMIFrameStandardFrame(m ICEMIFrame) bool {
+    return m.StandardFrame()
+}
+
+
+func CastICEMIFrame(structType interface{}) ICEMIFrame {
+    castFunc := func(typ interface{}) ICEMIFrame {
+        if iCEMIFrame, ok := typ.(ICEMIFrame); ok {
+            return iCEMIFrame
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastCEMIFrame(structType interface{}) CEMIFrame {
+    castFunc := func(typ interface{}) CEMIFrame {
+        if sCEMIFrame, ok := typ.(CEMIFrame); ok {
+            return sCEMIFrame
+        }
+        if sCEMIFrame, ok := typ.(*CEMIFrame); ok {
+            return *sCEMIFrame
+        }
+        return CEMIFrame{}
+    }
+    return castFunc(structType)
+}
+
+func (m CEMIFrame) LengthInBits() uint16 {
+    var lengthInBits uint16 = 0
+
+    // Discriminator Field (standardFrame)
+    lengthInBits += 1
+
+    // Discriminator Field (polling)
+    lengthInBits += 1
+
+    // Simple field (repeated)
+    lengthInBits += 1
+
+    // Discriminator Field (notAckFrame)
+    lengthInBits += 1
+
+    // Enum Field (priority)
+    lengthInBits += 2
+
+    // Simple field (acknowledgeRequested)
+    lengthInBits += 1
+
+    // Simple field (errorFlag)
+    lengthInBits += 1
+
+    // Length of sub-type elements will be added by sub-type...
+
+    return lengthInBits
+}
+
+func (m CEMIFrame) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func CEMIFrameParse(io *utils.ReadBuffer) (spi.Message, error) {
+
+    // Discriminator Field (standardFrame) (Used as input to a switch field)
+    standardFrame, _standardFrameErr := io.ReadBit()
+    if _standardFrameErr != nil {
+        return nil, errors.New("Error parsing 'standardFrame' field " + _standardFrameErr.Error())
+    }
+
+    // Discriminator Field (polling) (Used as input to a switch field)
+    polling, _pollingErr := io.ReadBit()
+    if _pollingErr != nil {
+        return nil, errors.New("Error parsing 'polling' field " + _pollingErr.Error())
+    }
+
+    // Simple Field (repeated)
+    repeated, _repeatedErr := io.ReadBit()
+    if _repeatedErr != nil {
+        return nil, errors.New("Error parsing 'repeated' field " + _repeatedErr.Error())
+    }
+
+    // Discriminator Field (notAckFrame) (Used as input to a switch field)
+    notAckFrame, _notAckFrameErr := io.ReadBit()
+    if _notAckFrameErr != nil {
+        return nil, errors.New("Error parsing 'notAckFrame' field " + _notAckFrameErr.Error())
+    }
+
+    // Enum field (priority)
+    priority, _priorityErr := CEMIPriorityParse(io)
+    if _priorityErr != nil {
+        return nil, errors.New("Error parsing 'priority' field " + _priorityErr.Error())
+    }
+
+    // Simple Field (acknowledgeRequested)
+    acknowledgeRequested, _acknowledgeRequestedErr := io.ReadBit()
+    if _acknowledgeRequestedErr != nil {
+        return nil, errors.New("Error parsing 'acknowledgeRequested' field " + _acknowledgeRequestedErr.Error())
+    }
+
+    // Simple Field (errorFlag)
+    errorFlag, _errorFlagErr := io.ReadBit()
+    if _errorFlagErr != nil {
+        return nil, errors.New("Error parsing 'errorFlag' field " + _errorFlagErr.Error())
+    }
+
+    // Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
+    var initializer CEMIFrameInitializer
+    var typeSwitchError error
+    switch {
+    case notAckFrame == false:
+        initializer, typeSwitchError = CEMIFrameAckParse(io)
+    case notAckFrame == true && standardFrame == true && polling == false:
+        initializer, typeSwitchError = CEMIFrameDataParse(io)
+    case notAckFrame == true && standardFrame == true && polling == true:
+        initializer, typeSwitchError = CEMIFramePollingDataParse(io)
+    case notAckFrame == true && standardFrame == false && polling == false:
+        initializer, typeSwitchError = CEMIFrameDataExtParse(io)
+    case notAckFrame == true && standardFrame == false && polling == true:
+        initializer, typeSwitchError = CEMIFramePollingDataExtParse(io)
+    }
+    if typeSwitchError != nil {
+        return nil, errors.New("Error parsing sub-type for type-switch. " + typeSwitchError.Error())
+    }
+
+    // Create the instance
+    return initializer.initialize(repeated, priority, acknowledgeRequested, errorFlag), nil
+}
+
+func CEMIFrameSerialize(io utils.WriteBuffer, m CEMIFrame, i ICEMIFrame, childSerialize func() error) error {
+
+    // Discriminator Field (standardFrame) (Used as input to a switch field)
+    standardFrame := bool(i.StandardFrame())
+    _standardFrameErr := io.WriteBit((standardFrame))
+    if _standardFrameErr != nil {
+        return errors.New("Error serializing 'standardFrame' field " + _standardFrameErr.Error())
+    }
+
+    // Discriminator Field (polling) (Used as input to a switch field)
+    polling := bool(i.Polling())
+    _pollingErr := io.WriteBit((polling))
+    if _pollingErr != nil {
+        return errors.New("Error serializing 'polling' field " + _pollingErr.Error())
+    }
+
+    // Simple Field (repeated)
+    repeated := bool(m.Repeated)
+    _repeatedErr := io.WriteBit((repeated))
+    if _repeatedErr != nil {
+        return errors.New("Error serializing 'repeated' field " + _repeatedErr.Error())
+    }
+
+    // Discriminator Field (notAckFrame) (Used as input to a switch field)
+    notAckFrame := bool(i.NotAckFrame())
+    _notAckFrameErr := io.WriteBit((notAckFrame))
+    if _notAckFrameErr != nil {
+        return errors.New("Error serializing 'notAckFrame' field " + _notAckFrameErr.Error())
+    }
+
+    // Enum field (priority)
+    priority := CastCEMIPriority(m.Priority)
+    _priorityErr := priority.Serialize(io)
+    if _priorityErr != nil {
+        return errors.New("Error serializing 'priority' field " + _priorityErr.Error())
+    }
+
+    // Simple Field (acknowledgeRequested)
+    acknowledgeRequested := bool(m.AcknowledgeRequested)
+    _acknowledgeRequestedErr := io.WriteBit((acknowledgeRequested))
+    if _acknowledgeRequestedErr != nil {
+        return errors.New("Error serializing 'acknowledgeRequested' field " + _acknowledgeRequestedErr.Error())
+    }
+
+    // Simple Field (errorFlag)
+    errorFlag := bool(m.ErrorFlag)
+    _errorFlagErr := io.WriteBit((errorFlag))
+    if _errorFlagErr != nil {
+        return errors.New("Error serializing 'errorFlag' field " + _errorFlagErr.Error())
+    }
+
+    // Switch field (Depending on the discriminator values, passes the serialization to a sub-type)
+    _typeSwitchErr := childSerialize()
+    if _typeSwitchErr != nil {
+        return errors.New("Error serializing sub-type field " + _typeSwitchErr.Error())
+    }
+
+    return nil
+}
+
+func (m *CEMIFrame) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "repeated":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Repeated = data
+            case "priority":
+                var data *CEMIPriority
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Priority = data
+            case "acknowledgeRequested":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.AcknowledgeRequested = data
+            case "errorFlag":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ErrorFlag = data
+            }
+        }
+    }
+}
+
+func (m CEMIFrame) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.knxnetip.readwrite.CEMIFrame"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Repeated, xml.StartElement{Name: xml.Name{Local: "repeated"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Priority, xml.StartElement{Name: xml.Name{Local: "priority"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.AcknowledgeRequested, xml.StartElement{Name: xml.Name{Local: "acknowledgeRequested"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ErrorFlag, xml.StartElement{Name: xml.Name{Local: "errorFlag"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameAck.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameAck.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameAck.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameAck.go
diff --git a/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameData.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameData.go
new file mode 100644
index 0000000..3c17f43
--- /dev/null
+++ b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameData.go
@@ -0,0 +1,470 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/base64"
+    "encoding/xml"
+    "errors"
+    "io"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    "reflect"
+)
+
+// The data-structure of this message
+type CEMIFrameData struct {
+    SourceAddress IKNXAddress
+    DestinationAddress []int8
+    GroupAddress bool
+    HopCount uint8
+    DataLength uint8
+    Tcpi ITPCI
+    Counter uint8
+    Apci IAPCI
+    DataFirstByte int8
+    Data []int8
+    Crc uint8
+    CEMIFrame
+}
+
+// The corresponding interface
+type ICEMIFrameData interface {
+    ICEMIFrame
+    Serialize(io utils.WriteBuffer) error
+}
+
+// Accessors for discriminator values.
+func (m CEMIFrameData) NotAckFrame() bool {
+    return true
+}
+
+func (m CEMIFrameData) StandardFrame() bool {
+    return true
+}
+
+func (m CEMIFrameData) Polling() bool {
+    return false
+}
+
+func (m CEMIFrameData) initialize(repeated bool, priority ICEMIPriority, acknowledgeRequested bool, errorFlag bool) spi.Message {
+    m.Repeated = repeated
+    m.Priority = priority
+    m.AcknowledgeRequested = acknowledgeRequested
+    m.ErrorFlag = errorFlag
+    return m
+}
+
+func NewCEMIFrameData(sourceAddress IKNXAddress, destinationAddress []int8, groupAddress bool, hopCount uint8, dataLength uint8, tcpi ITPCI, counter uint8, apci IAPCI, dataFirstByte int8, data []int8, crc uint8) CEMIFrameInitializer {
+    return &CEMIFrameData{SourceAddress: sourceAddress, DestinationAddress: destinationAddress, GroupAddress: groupAddress, HopCount: hopCount, DataLength: dataLength, Tcpi: tcpi, Counter: counter, Apci: apci, DataFirstByte: dataFirstByte, Data: data, Crc: crc}
+}
+
+func CastICEMIFrameData(structType interface{}) ICEMIFrameData {
+    castFunc := func(typ interface{}) ICEMIFrameData {
+        if iCEMIFrameData, ok := typ.(ICEMIFrameData); ok {
+            return iCEMIFrameData
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastCEMIFrameData(structType interface{}) CEMIFrameData {
+    castFunc := func(typ interface{}) CEMIFrameData {
+        if sCEMIFrameData, ok := typ.(CEMIFrameData); ok {
+            return sCEMIFrameData
+        }
+        if sCEMIFrameData, ok := typ.(*CEMIFrameData); ok {
+            return *sCEMIFrameData
+        }
+        return CEMIFrameData{}
+    }
+    return castFunc(structType)
+}
+
+func (m CEMIFrameData) LengthInBits() uint16 {
+    var lengthInBits uint16 = m.CEMIFrame.LengthInBits()
+
+    // Simple field (sourceAddress)
+    lengthInBits += m.SourceAddress.LengthInBits()
+
+    // Array field
+    if len(m.DestinationAddress) > 0 {
+        lengthInBits += 8 * uint16(len(m.DestinationAddress))
+    }
+
+    // Simple field (groupAddress)
+    lengthInBits += 1
+
+    // Simple field (hopCount)
+    lengthInBits += 3
+
+    // Simple field (dataLength)
+    lengthInBits += 4
+
+    // Enum Field (tcpi)
+    lengthInBits += 2
+
+    // Simple field (counter)
+    lengthInBits += 4
+
+    // Enum Field (apci)
+    lengthInBits += 4
+
+    // Simple field (dataFirstByte)
+    lengthInBits += 6
+
+    // Array field
+    if len(m.Data) > 0 {
+        lengthInBits += 8 * uint16(len(m.Data))
+    }
+
+    // Simple field (crc)
+    lengthInBits += 8
+
+    return lengthInBits
+}
+
+func (m CEMIFrameData) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func CEMIFrameDataParse(io *utils.ReadBuffer) (CEMIFrameInitializer, error) {
+
+    // Simple Field (sourceAddress)
+    _sourceAddressMessage, _err := KNXAddressParse(io)
+    if _err != nil {
+        return nil, errors.New("Error parsing simple field 'sourceAddress'. " + _err.Error())
+    }
+    var sourceAddress IKNXAddress
+    sourceAddress, _sourceAddressOk := _sourceAddressMessage.(IKNXAddress)
+    if !_sourceAddressOk {
+        return nil, errors.New("Couldn't cast message of type " + reflect.TypeOf(_sourceAddressMessage).Name() + " to IKNXAddress")
+    }
+
+    // Array field (destinationAddress)
+    // Count array
+    destinationAddress := make([]int8, uint16(2))
+    for curItem := uint16(0); curItem < uint16(uint16(2)); curItem++ {
+
+        _item, _err := io.ReadInt8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'destinationAddress' field " + _err.Error())
+        }
+        destinationAddress[curItem] = _item
+    }
+
+    // Simple Field (groupAddress)
+    groupAddress, _groupAddressErr := io.ReadBit()
+    if _groupAddressErr != nil {
+        return nil, errors.New("Error parsing 'groupAddress' field " + _groupAddressErr.Error())
+    }
+
+    // Simple Field (hopCount)
+    hopCount, _hopCountErr := io.ReadUint8(3)
+    if _hopCountErr != nil {
+        return nil, errors.New("Error parsing 'hopCount' field " + _hopCountErr.Error())
+    }
+
+    // Simple Field (dataLength)
+    dataLength, _dataLengthErr := io.ReadUint8(4)
+    if _dataLengthErr != nil {
+        return nil, errors.New("Error parsing 'dataLength' field " + _dataLengthErr.Error())
+    }
+
+    // Enum field (tcpi)
+    tcpi, _tcpiErr := TPCIParse(io)
+    if _tcpiErr != nil {
+        return nil, errors.New("Error parsing 'tcpi' field " + _tcpiErr.Error())
+    }
+
+    // Simple Field (counter)
+    counter, _counterErr := io.ReadUint8(4)
+    if _counterErr != nil {
+        return nil, errors.New("Error parsing 'counter' field " + _counterErr.Error())
+    }
+
+    // Enum field (apci)
+    apci, _apciErr := APCIParse(io)
+    if _apciErr != nil {
+        return nil, errors.New("Error parsing 'apci' field " + _apciErr.Error())
+    }
+
+    // Simple Field (dataFirstByte)
+    dataFirstByte, _dataFirstByteErr := io.ReadInt8(6)
+    if _dataFirstByteErr != nil {
+        return nil, errors.New("Error parsing 'dataFirstByte' field " + _dataFirstByteErr.Error())
+    }
+
+    // Array field (data)
+    // Count array
+    data := make([]int8, uint16(dataLength) - uint16(uint16(1)))
+    for curItem := uint16(0); curItem < uint16(uint16(dataLength) - uint16(uint16(1))); curItem++ {
+
+        _item, _err := io.ReadInt8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'data' field " + _err.Error())
+        }
+        data[curItem] = _item
+    }
+
+    // Simple Field (crc)
+    crc, _crcErr := io.ReadUint8(8)
+    if _crcErr != nil {
+        return nil, errors.New("Error parsing 'crc' field " + _crcErr.Error())
+    }
+
+    // Create the instance
+    return NewCEMIFrameData(sourceAddress, destinationAddress, groupAddress, hopCount, dataLength, tcpi, counter, apci, dataFirstByte, data, crc), nil
+}
+
+func (m CEMIFrameData) Serialize(io utils.WriteBuffer) error {
+    ser := func() error {
+
+    // Simple Field (sourceAddress)
+    sourceAddress := CastIKNXAddress(m.SourceAddress)
+    _sourceAddressErr := sourceAddress.Serialize(io)
+    if _sourceAddressErr != nil {
+        return errors.New("Error serializing 'sourceAddress' field " + _sourceAddressErr.Error())
+    }
+
+    // Array Field (destinationAddress)
+    if m.DestinationAddress != nil {
+        for _, _element := range m.DestinationAddress {
+            _elementErr := io.WriteInt8(8, _element)
+            if _elementErr != nil {
+                return errors.New("Error serializing 'destinationAddress' field " + _elementErr.Error())
+            }
+        }
+    }
+
+    // Simple Field (groupAddress)
+    groupAddress := bool(m.GroupAddress)
+    _groupAddressErr := io.WriteBit((groupAddress))
+    if _groupAddressErr != nil {
+        return errors.New("Error serializing 'groupAddress' field " + _groupAddressErr.Error())
+    }
+
+    // Simple Field (hopCount)
+    hopCount := uint8(m.HopCount)
+    _hopCountErr := io.WriteUint8(3, (hopCount))
+    if _hopCountErr != nil {
+        return errors.New("Error serializing 'hopCount' field " + _hopCountErr.Error())
+    }
+
+    // Simple Field (dataLength)
+    dataLength := uint8(m.DataLength)
+    _dataLengthErr := io.WriteUint8(4, (dataLength))
+    if _dataLengthErr != nil {
+        return errors.New("Error serializing 'dataLength' field " + _dataLengthErr.Error())
+    }
+
+    // Enum field (tcpi)
+    tcpi := CastTPCI(m.Tcpi)
+    _tcpiErr := tcpi.Serialize(io)
+    if _tcpiErr != nil {
+        return errors.New("Error serializing 'tcpi' field " + _tcpiErr.Error())
+    }
+
+    // Simple Field (counter)
+    counter := uint8(m.Counter)
+    _counterErr := io.WriteUint8(4, (counter))
+    if _counterErr != nil {
+        return errors.New("Error serializing 'counter' field " + _counterErr.Error())
+    }
+
+    // Enum field (apci)
+    apci := CastAPCI(m.Apci)
+    _apciErr := apci.Serialize(io)
+    if _apciErr != nil {
+        return errors.New("Error serializing 'apci' field " + _apciErr.Error())
+    }
+
+    // Simple Field (dataFirstByte)
+    dataFirstByte := int8(m.DataFirstByte)
+    _dataFirstByteErr := io.WriteInt8(6, (dataFirstByte))
+    if _dataFirstByteErr != nil {
+        return errors.New("Error serializing 'dataFirstByte' field " + _dataFirstByteErr.Error())
+    }
+
+    // Array Field (data)
+    if m.Data != nil {
+        for _, _element := range m.Data {
+            _elementErr := io.WriteInt8(8, _element)
+            if _elementErr != nil {
+                return errors.New("Error serializing 'data' field " + _elementErr.Error())
+            }
+        }
+    }
+
+    // Simple Field (crc)
+    crc := uint8(m.Crc)
+    _crcErr := io.WriteUint8(8, (crc))
+    if _crcErr != nil {
+        return errors.New("Error serializing 'crc' field " + _crcErr.Error())
+    }
+
+        return nil
+    }
+    return CEMIFrameSerialize(io, m.CEMIFrame, CastICEMIFrame(m), ser)
+}
+
+func (m *CEMIFrameData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "sourceAddress":
+                var data *KNXAddress
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SourceAddress = CastIKNXAddress(data)
+            case "destinationAddress":
+                var _encoded string
+                if err := d.DecodeElement(&_encoded, &tok); err != nil {
+                    return err
+                }
+                _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+                _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+                if err != nil {
+                    return err
+                }
+                m.DestinationAddress = utils.ByteToInt8(_decoded[0:_len])
+            case "groupAddress":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.GroupAddress = data
+            case "hopCount":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.HopCount = data
+            case "dataLength":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DataLength = data
+            case "tcpi":
+                var data *TPCI
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Tcpi = data
+            case "counter":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Counter = data
+            case "apci":
+                var data *APCI
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Apci = data
+            case "dataFirstByte":
+                var data int8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DataFirstByte = data
+            case "data":
+                var _encoded string
+                if err := d.DecodeElement(&_encoded, &tok); err != nil {
+                    return err
+                }
+                _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+                _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+                if err != nil {
+                    return err
+                }
+                m.Data = utils.ByteToInt8(_decoded[0:_len])
+            case "crc":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Crc = data
+            }
+        }
+    }
+}
+
+func (m CEMIFrameData) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.knxnetip.readwrite.CEMIFrameData"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SourceAddress, xml.StartElement{Name: xml.Name{Local: "sourceAddress"}}); err != nil {
+        return err
+    }
+    _encodedDestinationAddress := make([]byte, base64.StdEncoding.EncodedLen(len(m.DestinationAddress)))
+    base64.StdEncoding.Encode(_encodedDestinationAddress, utils.Int8ToByte(m.DestinationAddress))
+    if err := e.EncodeElement(_encodedDestinationAddress, xml.StartElement{Name: xml.Name{Local: "destinationAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.GroupAddress, xml.StartElement{Name: xml.Name{Local: "groupAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.HopCount, xml.StartElement{Name: xml.Name{Local: "hopCount"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DataLength, xml.StartElement{Name: xml.Name{Local: "dataLength"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Tcpi, xml.StartElement{Name: xml.Name{Local: "tcpi"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Counter, xml.StartElement{Name: xml.Name{Local: "counter"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Apci, xml.StartElement{Name: xml.Name{Local: "apci"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DataFirstByte, xml.StartElement{Name: xml.Name{Local: "dataFirstByte"}}); err != nil {
+        return err
+    }
+    _encodedData := make([]byte, base64.StdEncoding.EncodedLen(len(m.Data)))
+    base64.StdEncoding.Encode(_encodedData, utils.Int8ToByte(m.Data))
+    if err := e.EncodeElement(_encodedData, xml.StartElement{Name: xml.Name{Local: "data"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Crc, xml.StartElement{Name: xml.Name{Local: "crc"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameDataExt.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameDataExt.go
new file mode 100644
index 0000000..fcb2e01
--- /dev/null
+++ b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameDataExt.go
@@ -0,0 +1,496 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/base64"
+    "encoding/xml"
+    "errors"
+    "io"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    "reflect"
+)
+
+// The data-structure of this message
+type CEMIFrameDataExt struct {
+    GroupAddress bool
+    HopCount uint8
+    ExtendedFrameFormat uint8
+    SourceAddress IKNXAddress
+    DestinationAddress []int8
+    DataLength uint8
+    Tcpi ITPCI
+    Counter uint8
+    Apci IAPCI
+    DataFirstByte int8
+    Data []int8
+    Crc uint8
+    CEMIFrame
+}
+
+// The corresponding interface
+type ICEMIFrameDataExt interface {
+    ICEMIFrame
+    Serialize(io utils.WriteBuffer) error
+}
+
+// Accessors for discriminator values.
+func (m CEMIFrameDataExt) NotAckFrame() bool {
+    return true
+}
+
+func (m CEMIFrameDataExt) StandardFrame() bool {
+    return false
+}
+
+func (m CEMIFrameDataExt) Polling() bool {
+    return false
+}
+
+func (m CEMIFrameDataExt) initialize(repeated bool, priority ICEMIPriority, acknowledgeRequested bool, errorFlag bool) spi.Message {
+    m.Repeated = repeated
+    m.Priority = priority
+    m.AcknowledgeRequested = acknowledgeRequested
+    m.ErrorFlag = errorFlag
+    return m
+}
+
+func NewCEMIFrameDataExt(groupAddress bool, hopCount uint8, extendedFrameFormat uint8, sourceAddress IKNXAddress, destinationAddress []int8, dataLength uint8, tcpi ITPCI, counter uint8, apci IAPCI, dataFirstByte int8, data []int8, crc uint8) CEMIFrameInitializer {
+    return &CEMIFrameDataExt{GroupAddress: groupAddress, HopCount: hopCount, ExtendedFrameFormat: extendedFrameFormat, SourceAddress: sourceAddress, DestinationAddress: destinationAddress, DataLength: dataLength, Tcpi: tcpi, Counter: counter, Apci: apci, DataFirstByte: dataFirstByte, Data: data, Crc: crc}
+}
+
+func CastICEMIFrameDataExt(structType interface{}) ICEMIFrameDataExt {
+    castFunc := func(typ interface{}) ICEMIFrameDataExt {
+        if iCEMIFrameDataExt, ok := typ.(ICEMIFrameDataExt); ok {
+            return iCEMIFrameDataExt
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastCEMIFrameDataExt(structType interface{}) CEMIFrameDataExt {
+    castFunc := func(typ interface{}) CEMIFrameDataExt {
+        if sCEMIFrameDataExt, ok := typ.(CEMIFrameDataExt); ok {
+            return sCEMIFrameDataExt
+        }
+        if sCEMIFrameDataExt, ok := typ.(*CEMIFrameDataExt); ok {
+            return *sCEMIFrameDataExt
+        }
+        return CEMIFrameDataExt{}
+    }
+    return castFunc(structType)
+}
+
+func (m CEMIFrameDataExt) LengthInBits() uint16 {
+    var lengthInBits uint16 = m.CEMIFrame.LengthInBits()
+
+    // Simple field (groupAddress)
+    lengthInBits += 1
+
+    // Simple field (hopCount)
+    lengthInBits += 3
+
+    // Simple field (extendedFrameFormat)
+    lengthInBits += 4
+
+    // Simple field (sourceAddress)
+    lengthInBits += m.SourceAddress.LengthInBits()
+
+    // Array field
+    if len(m.DestinationAddress) > 0 {
+        lengthInBits += 8 * uint16(len(m.DestinationAddress))
+    }
+
+    // Simple field (dataLength)
+    lengthInBits += 8
+
+    // Enum Field (tcpi)
+    lengthInBits += 2
+
+    // Simple field (counter)
+    lengthInBits += 4
+
+    // Enum Field (apci)
+    lengthInBits += 4
+
+    // Simple field (dataFirstByte)
+    lengthInBits += 6
+
+    // Array field
+    if len(m.Data) > 0 {
+        lengthInBits += 8 * uint16(len(m.Data))
+    }
+
+    // Simple field (crc)
+    lengthInBits += 8
+
+    return lengthInBits
+}
+
+func (m CEMIFrameDataExt) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func CEMIFrameDataExtParse(io *utils.ReadBuffer) (CEMIFrameInitializer, error) {
+
+    // Simple Field (groupAddress)
+    groupAddress, _groupAddressErr := io.ReadBit()
+    if _groupAddressErr != nil {
+        return nil, errors.New("Error parsing 'groupAddress' field " + _groupAddressErr.Error())
+    }
+
+    // Simple Field (hopCount)
+    hopCount, _hopCountErr := io.ReadUint8(3)
+    if _hopCountErr != nil {
+        return nil, errors.New("Error parsing 'hopCount' field " + _hopCountErr.Error())
+    }
+
+    // Simple Field (extendedFrameFormat)
+    extendedFrameFormat, _extendedFrameFormatErr := io.ReadUint8(4)
+    if _extendedFrameFormatErr != nil {
+        return nil, errors.New("Error parsing 'extendedFrameFormat' field " + _extendedFrameFormatErr.Error())
+    }
+
+    // Simple Field (sourceAddress)
+    _sourceAddressMessage, _err := KNXAddressParse(io)
+    if _err != nil {
+        return nil, errors.New("Error parsing simple field 'sourceAddress'. " + _err.Error())
+    }
+    var sourceAddress IKNXAddress
+    sourceAddress, _sourceAddressOk := _sourceAddressMessage.(IKNXAddress)
+    if !_sourceAddressOk {
+        return nil, errors.New("Couldn't cast message of type " + reflect.TypeOf(_sourceAddressMessage).Name() + " to IKNXAddress")
+    }
+
+    // Array field (destinationAddress)
+    // Count array
+    destinationAddress := make([]int8, uint16(2))
+    for curItem := uint16(0); curItem < uint16(uint16(2)); curItem++ {
+
+        _item, _err := io.ReadInt8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'destinationAddress' field " + _err.Error())
+        }
+        destinationAddress[curItem] = _item
+    }
+
+    // Simple Field (dataLength)
+    dataLength, _dataLengthErr := io.ReadUint8(8)
+    if _dataLengthErr != nil {
+        return nil, errors.New("Error parsing 'dataLength' field " + _dataLengthErr.Error())
+    }
+
+    // Enum field (tcpi)
+    tcpi, _tcpiErr := TPCIParse(io)
+    if _tcpiErr != nil {
+        return nil, errors.New("Error parsing 'tcpi' field " + _tcpiErr.Error())
+    }
+
+    // Simple Field (counter)
+    counter, _counterErr := io.ReadUint8(4)
+    if _counterErr != nil {
+        return nil, errors.New("Error parsing 'counter' field " + _counterErr.Error())
+    }
+
+    // Enum field (apci)
+    apci, _apciErr := APCIParse(io)
+    if _apciErr != nil {
+        return nil, errors.New("Error parsing 'apci' field " + _apciErr.Error())
+    }
+
+    // Simple Field (dataFirstByte)
+    dataFirstByte, _dataFirstByteErr := io.ReadInt8(6)
+    if _dataFirstByteErr != nil {
+        return nil, errors.New("Error parsing 'dataFirstByte' field " + _dataFirstByteErr.Error())
+    }
+
+    // Array field (data)
+    // Count array
+    data := make([]int8, uint16(dataLength) - uint16(uint16(1)))
+    for curItem := uint16(0); curItem < uint16(uint16(dataLength) - uint16(uint16(1))); curItem++ {
+
+        _item, _err := io.ReadInt8(8)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'data' field " + _err.Error())
+        }
+        data[curItem] = _item
+    }
+
+    // Simple Field (crc)
+    crc, _crcErr := io.ReadUint8(8)
+    if _crcErr != nil {
+        return nil, errors.New("Error parsing 'crc' field " + _crcErr.Error())
+    }
+
+    // Create the instance
+    return NewCEMIFrameDataExt(groupAddress, hopCount, extendedFrameFormat, sourceAddress, destinationAddress, dataLength, tcpi, counter, apci, dataFirstByte, data, crc), nil
+}
+
+func (m CEMIFrameDataExt) Serialize(io utils.WriteBuffer) error {
+    ser := func() error {
+
+    // Simple Field (groupAddress)
+    groupAddress := bool(m.GroupAddress)
+    _groupAddressErr := io.WriteBit((groupAddress))
+    if _groupAddressErr != nil {
+        return errors.New("Error serializing 'groupAddress' field " + _groupAddressErr.Error())
+    }
+
+    // Simple Field (hopCount)
+    hopCount := uint8(m.HopCount)
+    _hopCountErr := io.WriteUint8(3, (hopCount))
+    if _hopCountErr != nil {
+        return errors.New("Error serializing 'hopCount' field " + _hopCountErr.Error())
+    }
+
+    // Simple Field (extendedFrameFormat)
+    extendedFrameFormat := uint8(m.ExtendedFrameFormat)
+    _extendedFrameFormatErr := io.WriteUint8(4, (extendedFrameFormat))
+    if _extendedFrameFormatErr != nil {
+        return errors.New("Error serializing 'extendedFrameFormat' field " + _extendedFrameFormatErr.Error())
+    }
+
+    // Simple Field (sourceAddress)
+    sourceAddress := CastIKNXAddress(m.SourceAddress)
+    _sourceAddressErr := sourceAddress.Serialize(io)
+    if _sourceAddressErr != nil {
+        return errors.New("Error serializing 'sourceAddress' field " + _sourceAddressErr.Error())
+    }
+
+    // Array Field (destinationAddress)
+    if m.DestinationAddress != nil {
+        for _, _element := range m.DestinationAddress {
+            _elementErr := io.WriteInt8(8, _element)
+            if _elementErr != nil {
+                return errors.New("Error serializing 'destinationAddress' field " + _elementErr.Error())
+            }
+        }
+    }
+
+    // Simple Field (dataLength)
+    dataLength := uint8(m.DataLength)
+    _dataLengthErr := io.WriteUint8(8, (dataLength))
+    if _dataLengthErr != nil {
+        return errors.New("Error serializing 'dataLength' field " + _dataLengthErr.Error())
+    }
+
+    // Enum field (tcpi)
+    tcpi := CastTPCI(m.Tcpi)
+    _tcpiErr := tcpi.Serialize(io)
+    if _tcpiErr != nil {
+        return errors.New("Error serializing 'tcpi' field " + _tcpiErr.Error())
+    }
+
+    // Simple Field (counter)
+    counter := uint8(m.Counter)
+    _counterErr := io.WriteUint8(4, (counter))
+    if _counterErr != nil {
+        return errors.New("Error serializing 'counter' field " + _counterErr.Error())
+    }
+
+    // Enum field (apci)
+    apci := CastAPCI(m.Apci)
+    _apciErr := apci.Serialize(io)
+    if _apciErr != nil {
+        return errors.New("Error serializing 'apci' field " + _apciErr.Error())
+    }
+
+    // Simple Field (dataFirstByte)
+    dataFirstByte := int8(m.DataFirstByte)
+    _dataFirstByteErr := io.WriteInt8(6, (dataFirstByte))
+    if _dataFirstByteErr != nil {
+        return errors.New("Error serializing 'dataFirstByte' field " + _dataFirstByteErr.Error())
+    }
+
+    // Array Field (data)
+    if m.Data != nil {
+        for _, _element := range m.Data {
+            _elementErr := io.WriteInt8(8, _element)
+            if _elementErr != nil {
+                return errors.New("Error serializing 'data' field " + _elementErr.Error())
+            }
+        }
+    }
+
+    // Simple Field (crc)
+    crc := uint8(m.Crc)
+    _crcErr := io.WriteUint8(8, (crc))
+    if _crcErr != nil {
+        return errors.New("Error serializing 'crc' field " + _crcErr.Error())
+    }
+
+        return nil
+    }
+    return CEMIFrameSerialize(io, m.CEMIFrame, CastICEMIFrame(m), ser)
+}
+
+func (m *CEMIFrameDataExt) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "groupAddress":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.GroupAddress = data
+            case "hopCount":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.HopCount = data
+            case "extendedFrameFormat":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ExtendedFrameFormat = data
+            case "sourceAddress":
+                var data *KNXAddress
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.SourceAddress = CastIKNXAddress(data)
+            case "destinationAddress":
+                var _encoded string
+                if err := d.DecodeElement(&_encoded, &tok); err != nil {
+                    return err
+                }
+                _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+                _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+                if err != nil {
+                    return err
+                }
+                m.DestinationAddress = utils.ByteToInt8(_decoded[0:_len])
+            case "dataLength":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DataLength = data
+            case "tcpi":
+                var data *TPCI
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Tcpi = data
+            case "counter":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Counter = data
+            case "apci":
+                var data *APCI
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Apci = data
+            case "dataFirstByte":
+                var data int8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.DataFirstByte = data
+            case "data":
+                var _encoded string
+                if err := d.DecodeElement(&_encoded, &tok); err != nil {
+                    return err
+                }
+                _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+                _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+                if err != nil {
+                    return err
+                }
+                m.Data = utils.ByteToInt8(_decoded[0:_len])
+            case "crc":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Crc = data
+            }
+        }
+    }
+}
+
+func (m CEMIFrameDataExt) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.knxnetip.readwrite.CEMIFrameDataExt"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.GroupAddress, xml.StartElement{Name: xml.Name{Local: "groupAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.HopCount, xml.StartElement{Name: xml.Name{Local: "hopCount"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ExtendedFrameFormat, xml.StartElement{Name: xml.Name{Local: "extendedFrameFormat"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.SourceAddress, xml.StartElement{Name: xml.Name{Local: "sourceAddress"}}); err != nil {
+        return err
+    }
+    _encodedDestinationAddress := make([]byte, base64.StdEncoding.EncodedLen(len(m.DestinationAddress)))
+    base64.StdEncoding.Encode(_encodedDestinationAddress, utils.Int8ToByte(m.DestinationAddress))
+    if err := e.EncodeElement(_encodedDestinationAddress, xml.StartElement{Name: xml.Name{Local: "destinationAddress"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DataLength, xml.StartElement{Name: xml.Name{Local: "dataLength"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Tcpi, xml.StartElement{Name: xml.Name{Local: "tcpi"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Counter, xml.StartElement{Name: xml.Name{Local: "counter"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Apci, xml.StartElement{Name: xml.Name{Local: "apci"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.DataFirstByte, xml.StartElement{Name: xml.Name{Local: "dataFirstByte"}}); err != nil {
+        return err
+    }
+    _encodedData := make([]byte, base64.StdEncoding.EncodedLen(len(m.Data)))
+    base64.StdEncoding.Encode(_encodedData, utils.Int8ToByte(m.Data))
+    if err := e.EncodeElement(_encodedData, xml.StartElement{Name: xml.Name{Local: "data"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Crc, xml.StartElement{Name: xml.Name{Local: "crc"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFramePollingData.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFramePollingData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFramePollingData.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFramePollingData.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFramePollingDataExt.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFramePollingDataExt.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFramePollingDataExt.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFramePollingDataExt.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIMPropReadCon.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIMPropReadCon.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIMPropReadCon.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIMPropReadCon.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIMPropReadReq.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIMPropReadReq.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIMPropReadReq.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIMPropReadReq.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPollDataCon.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPollDataCon.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPollDataCon.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPollDataCon.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPollDataReq.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPollDataReq.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPollDataReq.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPollDataReq.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPriority.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPriority.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPriority.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIPriority.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawCon.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawCon.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawCon.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawCon.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawInd.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawInd.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawInd.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawInd.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawReq.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawReq.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawReq.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIRawReq.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequest.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequest.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformation.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformation.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformation.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformation.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformationDeviceManagement.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformationDeviceManagement.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformationDeviceManagement.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformationDeviceManagement.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformationTunnelConnection.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformationTunnelConnection.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformationTunnelConnection.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionRequestInformationTunnelConnection.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponse.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponse.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlock.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlock.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlock.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlock.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlockDeviceManagement.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlockDeviceManagement.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlockDeviceManagement.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlockDeviceManagement.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlockTunnelConnection.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlockTunnelConnection.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlockTunnelConnection.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionResponseDataBlockTunnelConnection.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionStateRequest.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionStateRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionStateRequest.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionStateRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionStateResponse.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionStateResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionStateResponse.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ConnectionStateResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBDeviceInfo.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBDeviceInfo.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBDeviceInfo.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DIBDeviceInfo.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBSuppSvcFamilies.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBSuppSvcFamilies.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBSuppSvcFamilies.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DIBSuppSvcFamilies.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DescriptionRequest.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DescriptionRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DescriptionRequest.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DescriptionRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DescriptionResponse.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DescriptionResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DescriptionResponse.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DescriptionResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationAck.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationAck.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationAck.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationAck.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationAckDataBlock.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationAckDataBlock.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationAckDataBlock.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationAckDataBlock.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationRequest.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationRequest.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationRequestDataBlock.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationRequestDataBlock.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationRequestDataBlock.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceConfigurationRequestDataBlock.go
diff --git a/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceStatus.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceStatus.go
new file mode 100644
index 0000000..603e059
--- /dev/null
+++ b/plc4go/internal/plc4go/knxnetip/readwrite/model/DeviceStatus.go
@@ -0,0 +1,170 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    log "github.com/sirupsen/logrus"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+// The data-structure of this message
+type DeviceStatus struct {
+    ProgramMode bool
+
+}
+
+// The corresponding interface
+type IDeviceStatus interface {
+    spi.Message
+    Serialize(io utils.WriteBuffer) error
+}
+
+
+func NewDeviceStatus(programMode bool) spi.Message {
+    return &DeviceStatus{ProgramMode: programMode}
+}
+
+func CastIDeviceStatus(structType interface{}) IDeviceStatus {
+    castFunc := func(typ interface{}) IDeviceStatus {
+        if iDeviceStatus, ok := typ.(IDeviceStatus); ok {
+            return iDeviceStatus
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastDeviceStatus(structType interface{}) DeviceStatus {
+    castFunc := func(typ interface{}) DeviceStatus {
+        if sDeviceStatus, ok := typ.(DeviceStatus); ok {
+            return sDeviceStatus
+        }
+        if sDeviceStatus, ok := typ.(*DeviceStatus); ok {
+            return *sDeviceStatus
+        }
+        return DeviceStatus{}
+    }
+    return castFunc(structType)
+}
+
+func (m DeviceStatus) LengthInBits() uint16 {
+    var lengthInBits uint16 = 0
+
+    // Reserved Field (reserved)
+    lengthInBits += 7
+
+    // Simple field (programMode)
+    lengthInBits += 1
+
+    return lengthInBits
+}
+
+func (m DeviceStatus) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func DeviceStatusParse(io *utils.ReadBuffer) (spi.Message, error) {
+
+    // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+    {
+        reserved, _err := io.ReadUint8(7)
+        if _err != nil {
+            return nil, errors.New("Error parsing 'reserved' field " + _err.Error())
+        }
+        if reserved != uint8(0x00) {
+            log.WithFields(log.Fields{
+                "expected value": uint8(0x00),
+                "got value": reserved,
+            }).Info("Got unexpected response.")
+        }
+    }
+
+    // Simple Field (programMode)
+    programMode, _programModeErr := io.ReadBit()
+    if _programModeErr != nil {
+        return nil, errors.New("Error parsing 'programMode' field " + _programModeErr.Error())
+    }
+
+    // Create the instance
+    return NewDeviceStatus(programMode), nil
+}
+
+func (m DeviceStatus) Serialize(io utils.WriteBuffer) error {
+
+    // Reserved Field (reserved)
+    {
+        _err := io.WriteUint8(7, uint8(0x00))
+        if _err != nil {
+            return errors.New("Error serializing 'reserved' field " + _err.Error())
+        }
+    }
+
+    // Simple Field (programMode)
+    programMode := bool(m.ProgramMode)
+    _programModeErr := io.WriteBit((programMode))
+    if _programModeErr != nil {
+        return errors.New("Error serializing 'programMode' field " + _programModeErr.Error())
+    }
+
+    return nil
+}
+
+func (m *DeviceStatus) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "programMode":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ProgramMode = data
+            }
+        }
+    }
+}
+
+func (m DeviceStatus) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.knxnetip.readwrite.DeviceStatus"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ProgramMode, xml.StartElement{Name: xml.Name{Local: "programMode"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DisconnectRequest.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DisconnectRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DisconnectRequest.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DisconnectRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DisconnectResponse.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/DisconnectResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DisconnectResponse.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/DisconnectResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIControlEndpoint.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIControlEndpoint.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIControlEndpoint.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIControlEndpoint.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIDataEndpoint.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIDataEndpoint.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIDataEndpoint.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIDataEndpoint.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIDiscoveryEndpoint.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIDiscoveryEndpoint.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIDiscoveryEndpoint.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/HPAIDiscoveryEndpoint.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/HostProtocolCode.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/HostProtocolCode.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/HostProtocolCode.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/HostProtocolCode.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/IPAddress.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/IPAddress.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/IPAddress.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/IPAddress.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXAddress.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXAddress.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXAddress.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KNXAddress.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress2Level.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress2Level.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress2Level.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress2Level.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress3Level.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress3Level.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress3Level.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddress3Level.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddressFreeLevel.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddressFreeLevel.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddressFreeLevel.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KNXGroupAddressFreeLevel.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXNetIPMessage.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXNetIPMessage.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KNXNetIPMessage.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KNXNetIPMessage.go
diff --git a/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxDatapoint.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxDatapoint.go
new file mode 100644
index 0000000..fc993f0
--- /dev/null
+++ b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxDatapoint.go
@@ -0,0 +1,1090 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
+)
+
+func KnxDatapointParse(io *utils.ReadBuffer, mainNumber uint16, subNumber uint16) (api.PlcValue, error) {
+    switch {
+        case mainNumber == 1: // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(7); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadBit()
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcBOOL(value), nil
+        case mainNumber == 2: // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(6); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (control)
+            _, _controlErr := io.ReadBit()
+            if _controlErr != nil {
+                return nil, errors.New("Error parsing 'control' field " + _controlErr.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadBit()
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcBOOL(value), nil
+        case mainNumber == 21: // Struct
+            _map := map[string]interface{}{}
+
+            // Simple Field (b7)
+            b7, _b7Err := io.ReadBit()
+            if _b7Err != nil {
+                return nil, errors.New("Error parsing 'b7' field " + _b7Err.Error())
+            }
+            _map["Struct"] = b7
+
+            // Simple Field (b6)
+            b6, _b6Err := io.ReadBit()
+            if _b6Err != nil {
+                return nil, errors.New("Error parsing 'b6' field " + _b6Err.Error())
+            }
+            _map["Struct"] = b6
+
+            // Simple Field (b5)
+            b5, _b5Err := io.ReadBit()
+            if _b5Err != nil {
+                return nil, errors.New("Error parsing 'b5' field " + _b5Err.Error())
+            }
+            _map["Struct"] = b5
+
+            // Simple Field (b4)
+            b4, _b4Err := io.ReadBit()
+            if _b4Err != nil {
+                return nil, errors.New("Error parsing 'b4' field " + _b4Err.Error())
+            }
+            _map["Struct"] = b4
+
+            // Simple Field (b3)
+            b3, _b3Err := io.ReadBit()
+            if _b3Err != nil {
+                return nil, errors.New("Error parsing 'b3' field " + _b3Err.Error())
+            }
+            _map["Struct"] = b3
+
+            // Simple Field (b2)
+            b2, _b2Err := io.ReadBit()
+            if _b2Err != nil {
+                return nil, errors.New("Error parsing 'b2' field " + _b2Err.Error())
+            }
+            _map["Struct"] = b2
+
+            // Simple Field (b1)
+            b1, _b1Err := io.ReadBit()
+            if _b1Err != nil {
+                return nil, errors.New("Error parsing 'b1' field " + _b1Err.Error())
+            }
+            _map["Struct"] = b1
+
+            // Simple Field (b0)
+            b0, _b0Err := io.ReadBit()
+            if _b0Err != nil {
+                return nil, errors.New("Error parsing 'b0' field " + _b0Err.Error())
+            }
+            _map["Struct"] = b0
+        case mainNumber == 3: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(4); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (control)
+            _, _controlErr := io.ReadBit()
+            if _controlErr != nil {
+                return nil, errors.New("Error parsing 'control' field " + _controlErr.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(3)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case mainNumber == 18: // USINT
+
+            // Simple Field (control)
+            _, _controlErr := io.ReadBit()
+            if _controlErr != nil {
+                return nil, errors.New("Error parsing 'control' field " + _controlErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(1); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(6)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case mainNumber == 17: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(2); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(6)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case mainNumber == 5: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case mainNumber == 7: // UINT
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUINT(value), nil
+        case mainNumber == 12: // UDINT
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUDINT(value), nil
+        case mainNumber == 6 && subNumber == 20: // SINT
+
+            // Simple Field (a)
+            _, _aErr := io.ReadBit()
+            if _aErr != nil {
+                return nil, errors.New("Error parsing 'a' field " + _aErr.Error())
+            }
+
+            // Simple Field (b)
+            _, _bErr := io.ReadBit()
+            if _bErr != nil {
+                return nil, errors.New("Error parsing 'b' field " + _bErr.Error())
+            }
+
+            // Simple Field (c)
+            _, _cErr := io.ReadBit()
+            if _cErr != nil {
+                return nil, errors.New("Error parsing 'c' field " + _cErr.Error())
+            }
+
+            // Simple Field (d)
+            _, _dErr := io.ReadBit()
+            if _dErr != nil {
+                return nil, errors.New("Error parsing 'd' field " + _dErr.Error())
+            }
+
+            // Simple Field (e)
+            _, _eErr := io.ReadBit()
+            if _eErr != nil {
+                return nil, errors.New("Error parsing 'e' field " + _eErr.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSINT(value), nil
+        case mainNumber == 6: // SINT
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSINT(value), nil
+        case mainNumber == 8: // INT
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcINT(value), nil
+        case mainNumber == 13: // DINT
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcDINT(value), nil
+        case mainNumber == 9: // REAL
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Manual Field (value)
+            value, _valueErr := KnxHelperBytesToF16(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcREAL(value), nil
+        case mainNumber == 14: // REAL
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadFloat32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcREAL(value), nil
+        case mainNumber == 4: // STRING
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadString(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSTRING(value), nil
+        case mainNumber == 16: // STRING
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(8); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadString(112)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSTRING(value), nil
+        case mainNumber == 10: // Time
+
+            // Simple Field (day)
+            _, _dayErr := io.ReadUint8(3)
+            if _dayErr != nil {
+                return nil, errors.New("Error parsing 'day' field " + _dayErr.Error())
+            }
+
+            // Simple Field (hours)
+            _, _hoursErr := io.ReadUint8(5)
+            if _hoursErr != nil {
+                return nil, errors.New("Error parsing 'hours' field " + _hoursErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(2); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (minutes)
+            _, _minutesErr := io.ReadUint8(6)
+            if _minutesErr != nil {
+                return nil, errors.New("Error parsing 'minutes' field " + _minutesErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(2); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (seconds)
+            _, _secondsErr := io.ReadUint8(6)
+            if _secondsErr != nil {
+                return nil, errors.New("Error parsing 'seconds' field " + _secondsErr.Error())
+            }
+        case mainNumber == 11: // Date
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(3); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (day)
+            _, _dayErr := io.ReadUint8(5)
+            if _dayErr != nil {
+                return nil, errors.New("Error parsing 'day' field " + _dayErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(4); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (month)
+            _, _monthErr := io.ReadUint8(4)
+            if _monthErr != nil {
+                return nil, errors.New("Error parsing 'month' field " + _monthErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(1); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (year)
+            _, _yearErr := io.ReadUint8(6)
+            if _yearErr != nil {
+                return nil, errors.New("Error parsing 'year' field " + _yearErr.Error())
+            }
+        case mainNumber == 19: // DateTime
+
+            // Simple Field (year)
+            _, _yearErr := io.ReadUint8(8)
+            if _yearErr != nil {
+                return nil, errors.New("Error parsing 'year' field " + _yearErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(4); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (month)
+            _, _monthErr := io.ReadUint8(4)
+            if _monthErr != nil {
+                return nil, errors.New("Error parsing 'month' field " + _monthErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(3); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (day)
+            _, _dayErr := io.ReadUint8(5)
+            if _dayErr != nil {
+                return nil, errors.New("Error parsing 'day' field " + _dayErr.Error())
+            }
+
+            // Simple Field (dayOfWeek)
+            _, _dayOfWeekErr := io.ReadUint8(3)
+            if _dayOfWeekErr != nil {
+                return nil, errors.New("Error parsing 'dayOfWeek' field " + _dayOfWeekErr.Error())
+            }
+
+            // Simple Field (hours)
+            _, _hoursErr := io.ReadUint8(5)
+            if _hoursErr != nil {
+                return nil, errors.New("Error parsing 'hours' field " + _hoursErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(2); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (minutes)
+            _, _minutesErr := io.ReadUint8(6)
+            if _minutesErr != nil {
+                return nil, errors.New("Error parsing 'minutes' field " + _minutesErr.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(2); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (seconds)
+            _, _secondsErr := io.ReadUint8(6)
+            if _secondsErr != nil {
+                return nil, errors.New("Error parsing 'seconds' field " + _secondsErr.Error())
+            }
+
+            // Simple Field (fault)
+            _, _faultErr := io.ReadBit()
+            if _faultErr != nil {
+                return nil, errors.New("Error parsing 'fault' field " + _faultErr.Error())
+            }
+
+            // Simple Field (workingDay)
+            _, _workingDayErr := io.ReadBit()
+            if _workingDayErr != nil {
+                return nil, errors.New("Error parsing 'workingDay' field " + _workingDayErr.Error())
+            }
+
+            // Simple Field (workingDayValid)
+            _, _workingDayValidErr := io.ReadBit()
+            if _workingDayValidErr != nil {
+                return nil, errors.New("Error parsing 'workingDayValid' field " + _workingDayValidErr.Error())
+            }
+
+            // Simple Field (yearValid)
+            _, _yearValidErr := io.ReadBit()
+            if _yearValidErr != nil {
+                return nil, errors.New("Error parsing 'yearValid' field " + _yearValidErr.Error())
+            }
+
+            // Simple Field (dayAndMonthValid)
+            _, _dayAndMonthValidErr := io.ReadBit()
+            if _dayAndMonthValidErr != nil {
+                return nil, errors.New("Error parsing 'dayAndMonthValid' field " + _dayAndMonthValidErr.Error())
+            }
+
+            // Simple Field (dayOfWeekValid)
+            _, _dayOfWeekValidErr := io.ReadBit()
+            if _dayOfWeekValidErr != nil {
+                return nil, errors.New("Error parsing 'dayOfWeekValid' field " + _dayOfWeekValidErr.Error())
+            }
+
+            // Simple Field (timeValid)
+            _, _timeValidErr := io.ReadBit()
+            if _timeValidErr != nil {
+                return nil, errors.New("Error parsing 'timeValid' field " + _timeValidErr.Error())
+            }
+
+            // Simple Field (standardSummerTime)
+            _, _standardSummerTimeErr := io.ReadBit()
+            if _standardSummerTimeErr != nil {
+                return nil, errors.New("Error parsing 'standardSummerTime' field " + _standardSummerTimeErr.Error())
+            }
+
+            // Simple Field (clockQuality)
+            _, _clockQualityErr := io.ReadBit()
+            if _clockQualityErr != nil {
+                return nil, errors.New("Error parsing 'clockQuality' field " + _clockQualityErr.Error())
+            }
+        case mainNumber == 15: // Struct
+            _map := map[string]interface{}{}
+
+            // Simple Field (D6)
+            D6, _D6Err := io.ReadUint8(4)
+            if _D6Err != nil {
+                return nil, errors.New("Error parsing 'D6' field " + _D6Err.Error())
+            }
+            _map["Struct"] = D6
+
+            // Simple Field (D5)
+            D5, _D5Err := io.ReadUint8(4)
+            if _D5Err != nil {
+                return nil, errors.New("Error parsing 'D5' field " + _D5Err.Error())
+            }
+            _map["Struct"] = D5
+
+            // Simple Field (D4)
+            D4, _D4Err := io.ReadUint8(4)
+            if _D4Err != nil {
+                return nil, errors.New("Error parsing 'D4' field " + _D4Err.Error())
+            }
+            _map["Struct"] = D4
+
+            // Simple Field (D3)
+            D3, _D3Err := io.ReadUint8(4)
+            if _D3Err != nil {
+                return nil, errors.New("Error parsing 'D3' field " + _D3Err.Error())
+            }
+            _map["Struct"] = D3
+
+            // Simple Field (D2)
+            D2, _D2Err := io.ReadUint8(4)
+            if _D2Err != nil {
+                return nil, errors.New("Error parsing 'D2' field " + _D2Err.Error())
+            }
+            _map["Struct"] = D2
+
+            // Simple Field (D1)
+            D1, _D1Err := io.ReadUint8(4)
+            if _D1Err != nil {
+                return nil, errors.New("Error parsing 'D1' field " + _D1Err.Error())
+            }
+            _map["Struct"] = D1
+
+            // Simple Field (BE)
+            BE, _BEErr := io.ReadBit()
+            if _BEErr != nil {
+                return nil, errors.New("Error parsing 'BE' field " + _BEErr.Error())
+            }
+            _map["Struct"] = BE
+
+            // Simple Field (BP)
+            BP, _BPErr := io.ReadBit()
+            if _BPErr != nil {
+                return nil, errors.New("Error parsing 'BP' field " + _BPErr.Error())
+            }
+            _map["Struct"] = BP
+
+            // Simple Field (BD)
+            BD, _BDErr := io.ReadBit()
+            if _BDErr != nil {
+                return nil, errors.New("Error parsing 'BD' field " + _BDErr.Error())
+            }
+            _map["Struct"] = BD
+
+            // Simple Field (BC)
+            BC, _BCErr := io.ReadBit()
+            if _BCErr != nil {
+                return nil, errors.New("Error parsing 'BC' field " + _BCErr.Error())
+            }
+            _map["Struct"] = BC
+
+            // Simple Field (index)
+            index, _indexErr := io.ReadUint8(4)
+            if _indexErr != nil {
+                return nil, errors.New("Error parsing 'index' field " + _indexErr.Error())
+            }
+            _map["Struct"] = index
+    }
+    return nil, errors.New("unsupported type")
+}
+
+func KnxDatapointSerialize(io *utils.WriteBuffer, value api.PlcValue, mainNumber uint16, subNumber uint16) error {
+    switch {
+        case mainNumber == 1: // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(7, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 2: // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(6, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (control)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'control' field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 21: // Struct
+            _map := map[string]interface{}{}
+
+            // Simple Field (b7)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b7' field " + _err.Error())
+            }
+
+            // Simple Field (b6)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b6' field " + _err.Error())
+            }
+
+            // Simple Field (b5)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b5' field " + _err.Error())
+            }
+
+            // Simple Field (b4)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b4' field " + _err.Error())
+            }
+
+            // Simple Field (b3)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b3' field " + _err.Error())
+            }
+
+            // Simple Field (b2)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b2' field " + _err.Error())
+            }
+
+            // Simple Field (b1)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b1' field " + _err.Error())
+            }
+
+            // Simple Field (b0)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b0' field " + _err.Error())
+            }
+        case mainNumber == 3: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(4, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (control)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'control' field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteUint8(3, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 18: // USINT
+
+            // Simple Field (control)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'control' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(1, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteUint8(6, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 17: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(2, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteUint8(6, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 5: // USINT
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteUint8(8, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 7: // UINT
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteUint16(16, value.GetUint16()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 12: // UDINT
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteUint32(32, value.GetUint32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 6 && subNumber == 20: // SINT
+
+            // Simple Field (a)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'a' field " + _err.Error())
+            }
+
+            // Simple Field (b)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'b' field " + _err.Error())
+            }
+
+            // Simple Field (c)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'c' field " + _err.Error())
+            }
+
+            // Simple Field (d)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'd' field " + _err.Error())
+            }
+
+            // Simple Field (e)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'e' field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteInt8(8, value.GetInt8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 6: // SINT
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteInt8(8, value.GetInt8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 8: // INT
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteInt16(16, value.GetInt16()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 13: // DINT
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteInt32(32, value.GetInt32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 9: // REAL
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Manual Field (value)
+            _valueErr := KnxHelperF16toBytes(io, m.Object)
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case mainNumber == 14: // REAL
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteFloat32(32, value.GetFloat32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 4: // STRING
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteString(8, "UTF-8", value.GetString()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 16: // STRING
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(8, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteString(112, "UTF-8", value.GetString()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case mainNumber == 10: // Time
+
+            // Simple Field (day)
+            if _err := io.WriteUint8(3, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'day' field " + _err.Error())
+            }
+
+            // Simple Field (hours)
+            if _err := io.WriteUint8(5, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'hours' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(2, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (minutes)
+            if _err := io.WriteUint8(6, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'minutes' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(2, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (seconds)
+            if _err := io.WriteUint8(6, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'seconds' field " + _err.Error())
+            }
+        case mainNumber == 11: // Date
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(3, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (day)
+            if _err := io.WriteUint8(5, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'day' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(4, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (month)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'month' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(1, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (year)
+            if _err := io.WriteUint8(6, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'year' field " + _err.Error())
+            }
+        case mainNumber == 19: // DateTime
+
+            // Simple Field (year)
+            if _err := io.WriteUint8(8, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'year' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(4, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (month)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'month' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(3, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (day)
+            if _err := io.WriteUint8(5, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'day' field " + _err.Error())
+            }
+
+            // Simple Field (dayOfWeek)
+            if _err := io.WriteUint8(3, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'dayOfWeek' field " + _err.Error())
+            }
+
+            // Simple Field (hours)
+            if _err := io.WriteUint8(5, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'hours' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(2, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (minutes)
+            if _err := io.WriteUint8(6, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'minutes' field " + _err.Error())
+            }
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(2, uint8(0x0)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (seconds)
+            if _err := io.WriteUint8(6, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'seconds' field " + _err.Error())
+            }
+
+            // Simple Field (fault)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'fault' field " + _err.Error())
+            }
+
+            // Simple Field (workingDay)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'workingDay' field " + _err.Error())
+            }
+
+            // Simple Field (workingDayValid)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'workingDayValid' field " + _err.Error())
+            }
+
+            // Simple Field (yearValid)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'yearValid' field " + _err.Error())
+            }
+
+            // Simple Field (dayAndMonthValid)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'dayAndMonthValid' field " + _err.Error())
+            }
+
+            // Simple Field (dayOfWeekValid)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'dayOfWeekValid' field " + _err.Error())
+            }
+
+            // Simple Field (timeValid)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'timeValid' field " + _err.Error())
+            }
+
+            // Simple Field (standardSummerTime)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'standardSummerTime' field " + _err.Error())
+            }
+
+            // Simple Field (clockQuality)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'clockQuality' field " + _err.Error())
+            }
+        case mainNumber == 15: // Struct
+            _map := map[string]interface{}{}
+
+            // Simple Field (D6)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'D6' field " + _err.Error())
+            }
+
+            // Simple Field (D5)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'D5' field " + _err.Error())
+            }
+
+            // Simple Field (D4)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'D4' field " + _err.Error())
+            }
+
+            // Simple Field (D3)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'D3' field " + _err.Error())
+            }
+
+            // Simple Field (D2)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'D2' field " + _err.Error())
+            }
+
+            // Simple Field (D1)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'D1' field " + _err.Error())
+            }
+
+            // Simple Field (BE)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'BE' field " + _err.Error())
+            }
+
+            // Simple Field (BP)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'BP' field " + _err.Error())
+            }
+
+            // Simple Field (BD)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'BD' field " + _err.Error())
+            }
+
+            // Simple Field (BC)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'BC' field " + _err.Error())
+            }
+
+            // Simple Field (index)
+            if _err := io.WriteUint8(4, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'index' field " + _err.Error())
+            }
+        default:
+
+            return errors.New("unsupported type")
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxLayer.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxLayer.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxLayer.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KnxLayer.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpCore.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpCore.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpCore.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpCore.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpDeviceManagement.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpDeviceManagement.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpDeviceManagement.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpDeviceManagement.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpTunneling.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpTunneling.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpTunneling.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetIpTunneling.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetObjectServer.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetObjectServer.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetObjectServer.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetObjectServer.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetRemoteConfigurationAndDiagnosis.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetRemoteConfigurationAndDiagnosis.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetRemoteConfigurationAndDiagnosis.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetRemoteConfigurationAndDiagnosis.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetRemoteLogging.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetRemoteLogging.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetRemoteLogging.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KnxNetRemoteLogging.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxStaticHelper.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxStaticHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/KnxStaticHelper.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/KnxStaticHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/MACAddress.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/MACAddress.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/MACAddress.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/MACAddress.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ParserHelper.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ParserHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ParserHelper.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ParserHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ProjectInstallationIdentifier.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ProjectInstallationIdentifier.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ProjectInstallationIdentifier.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ProjectInstallationIdentifier.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/RelativeTimestamp.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/RelativeTimestamp.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/RelativeTimestamp.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/RelativeTimestamp.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/RoutingIndication.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/RoutingIndication.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/RoutingIndication.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/RoutingIndication.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/SearchRequest.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/SearchRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/SearchRequest.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/SearchRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/SearchResponse.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/SearchResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/SearchResponse.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/SearchResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ServiceId.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/ServiceId.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ServiceId.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/ServiceId.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/Status.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/Status.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/Status.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/Status.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TPCI.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/TPCI.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TPCI.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/TPCI.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingRequest.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingRequest.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingRequestDataBlock.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingRequestDataBlock.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingRequestDataBlock.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingRequestDataBlock.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingResponse.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingResponse.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingResponseDataBlock.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingResponseDataBlock.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingResponseDataBlock.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/TunnelingResponseDataBlock.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/UnknownMessage.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/UnknownMessage.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/UnknownMessage.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/UnknownMessage.go
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/XmlParserHelper.go b/plc4go/internal/plc4go/knxnetip/readwrite/model/XmlParserHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/XmlParserHelper.go
rename to plc4go/internal/plc4go/knxnetip/readwrite/model/XmlParserHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusConnection.go b/plc4go/internal/plc4go/modbus/ModbusConnection.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/ModbusConnection.go
rename to plc4go/internal/plc4go/modbus/ModbusConnection.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusDriver.go b/plc4go/internal/plc4go/modbus/ModbusDriver.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/ModbusDriver.go
rename to plc4go/internal/plc4go/modbus/ModbusDriver.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusField.go b/plc4go/internal/plc4go/modbus/ModbusField.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/ModbusField.go
rename to plc4go/internal/plc4go/modbus/ModbusField.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusFieldHandler.go b/plc4go/internal/plc4go/modbus/ModbusFieldHandler.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/ModbusFieldHandler.go
rename to plc4go/internal/plc4go/modbus/ModbusFieldHandler.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusMessageCodec.go b/plc4go/internal/plc4go/modbus/ModbusMessageCodec.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/ModbusMessageCodec.go
rename to plc4go/internal/plc4go/modbus/ModbusMessageCodec.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go b/plc4go/internal/plc4go/modbus/ModbusReader.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
rename to plc4go/internal/plc4go/modbus/ModbusReader.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusValueHandler.go b/plc4go/internal/plc4go/modbus/ModbusValueHandler.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/ModbusValueHandler.go
rename to plc4go/internal/plc4go/modbus/ModbusValueHandler.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusWriter.go b/plc4go/internal/plc4go/modbus/ModbusWriter.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/ModbusWriter.go
rename to plc4go/internal/plc4go/modbus/ModbusWriter.go
diff --git a/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go b/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go
new file mode 100644
index 0000000..b2bec75
--- /dev/null
+++ b/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go
@@ -0,0 +1,647 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
+)
+
+func DataItemParse(io *utils.ReadBuffer, dataType string, numberOfValues uint16) (api.PlcValue, error) {
+    switch {
+        case dataType == "IEC61131_BOOL" && numberOfValues == 1: // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(7); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadBit()
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcBOOL(value), nil
+        case dataType == "IEC61131_BOOL": // BOOL
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_BYTE" && numberOfValues == 1: // BYTE
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcBYTE(value), nil
+        case dataType == "IEC61131_BYTE": // BYTE
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_WORD" && numberOfValues == 1: // WORD
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcWORD(value), nil
+        case dataType == "IEC61131_WORD": // WORD
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_DWORD" && numberOfValues == 1: // DWORD
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcDWORD(value), nil
+        case dataType == "IEC61131_DWORD": // DWORD
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_LWORD" && numberOfValues == 1: // LWORD
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint64(64)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcLWORD(value), nil
+        case dataType == "IEC61131_LWORD": // LWORD
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_SINT" && numberOfValues == 1: // SINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSINT(value), nil
+        case dataType == "IEC61131_SINT": // SINT
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_INT" && numberOfValues == 1: // INT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcINT(value), nil
+        case dataType == "IEC61131_INT": // INT
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_DINT" && numberOfValues == 1: // DINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcDINT(value), nil
+        case dataType == "IEC61131_DINT": // DINT
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_LINT" && numberOfValues == 1: // LINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt64(64)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcLINT(value), nil
+        case dataType == "IEC61131_LINT": // LINT
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_USINT" && numberOfValues == 1: // USINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case dataType == "IEC61131_USINT": // USINT
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_UINT" && numberOfValues == 1: // UINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUINT(value), nil
+        case dataType == "IEC61131_UINT": // UINT
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_UDINT" && numberOfValues == 1: // UDINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUDINT(value), nil
+        case dataType == "IEC61131_UDINT": // UDINT
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_ULINT" && numberOfValues == 1: // ULINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint64(64)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcULINT(value), nil
+        case dataType == "IEC61131_ULINT": // ULINT
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_REAL" && numberOfValues == 1: // REAL
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadFloat32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcREAL(value), nil
+        case dataType == "IEC61131_REAL": // REAL
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_LREAL" && numberOfValues == 1: // LREAL
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadFloat64(64)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcLREAL(value), nil
+        case dataType == "IEC61131_LREAL": // LREAL
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_CHAR" && numberOfValues == 1: // CHAR
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcCHAR(value), nil
+        case dataType == "IEC61131_CHAR": // CHAR
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataType == "IEC61131_WCHAR" && numberOfValues == 1: // WCHAR
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcWCHAR(value), nil
+        case dataType == "IEC61131_WCHAR": // WCHAR
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+    }
+    return nil, errors.New("unsupported type")
+}
+
+func DataItemSerialize(io *utils.WriteBuffer, value api.PlcValue, dataType string, numberOfValues uint16) error {
+    switch {
+        case dataType == "IEC61131_BOOL" && numberOfValues == 1: // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(7, uint8(0x00)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_BOOL": // BOOL
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_BYTE" && numberOfValues == 1: // BYTE
+
+            // Simple Field (value)
+            if _err := io.WriteUint8(8, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_BYTE": // BYTE
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_WORD" && numberOfValues == 1: // WORD
+
+            // Simple Field (value)
+            if _err := io.WriteUint16(16, value.GetUint16()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_WORD": // WORD
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_DWORD" && numberOfValues == 1: // DWORD
+
+            // Simple Field (value)
+            if _err := io.WriteUint32(32, value.GetUint32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_DWORD": // DWORD
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_LWORD" && numberOfValues == 1: // LWORD
+
+            // Simple Field (value)
+            if _err := io.WriteUint64(64, value.GetUint64()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_LWORD": // LWORD
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_SINT" && numberOfValues == 1: // SINT
+
+            // Simple Field (value)
+            if _err := io.WriteInt8(8, value.GetInt8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_SINT": // SINT
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_INT" && numberOfValues == 1: // INT
+
+            // Simple Field (value)
+            if _err := io.WriteInt16(16, value.GetInt16()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_INT": // INT
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_DINT" && numberOfValues == 1: // DINT
+
+            // Simple Field (value)
+            if _err := io.WriteInt32(32, value.GetInt32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_DINT": // DINT
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_LINT" && numberOfValues == 1: // LINT
+
+            // Simple Field (value)
+            if _err := io.WriteInt64(64, value.GetInt64()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_LINT": // LINT
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_USINT" && numberOfValues == 1: // USINT
+
+            // Simple Field (value)
+            if _err := io.WriteUint8(8, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_USINT": // USINT
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_UINT" && numberOfValues == 1: // UINT
+
+            // Simple Field (value)
+            if _err := io.WriteUint16(16, value.GetUint16()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_UINT": // UINT
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_UDINT" && numberOfValues == 1: // UDINT
+
+            // Simple Field (value)
+            if _err := io.WriteUint32(32, value.GetUint32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_UDINT": // UDINT
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_ULINT" && numberOfValues == 1: // ULINT
+
+            // Simple Field (value)
+            if _err := io.WriteUint64(64, value.GetUint64()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_ULINT": // ULINT
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_REAL" && numberOfValues == 1: // REAL
+
+            // Simple Field (value)
+            if _err := io.WriteFloat32(32, value.GetFloat32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_REAL": // REAL
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_LREAL" && numberOfValues == 1: // LREAL
+
+            // Simple Field (value)
+            if _err := io.WriteFloat64(64, value.GetFloat64()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_LREAL": // LREAL
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_CHAR" && numberOfValues == 1: // CHAR
+
+            // Simple Field (value)
+            if _err := io.WriteUint8(8, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_CHAR": // CHAR
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataType == "IEC61131_WCHAR" && numberOfValues == 1: // WCHAR
+
+            // Simple Field (value)
+            if _err := io.WriteUint16(16, value.GetUint16()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataType == "IEC61131_WCHAR": // WCHAR
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32(numberOfValues); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataType, uint16(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        default:
+
+            return errors.New("unsupported type")
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusConstants.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusConstants.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusConstants.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusConstants.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusDataTypeSizes.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusDataTypeSizes.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusDataTypeSizes.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusDataTypeSizes.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusErrorCode.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusErrorCode.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusErrorCode.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusErrorCode.go
diff --git a/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDU.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDU.go
new file mode 100644
index 0000000..5b7e84f
--- /dev/null
+++ b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDU.go
@@ -0,0 +1,260 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+// The data-structure of this message
+type ModbusPDU struct {
+
+}
+
+// The corresponding interface
+type IModbusPDU interface {
+    spi.Message
+    ErrorFlag() bool
+    FunctionFlag() uint8
+    Response() bool
+    Serialize(io utils.WriteBuffer) error
+}
+
+type ModbusPDUInitializer interface {
+    initialize() spi.Message
+}
+
+func ModbusPDUErrorFlag(m IModbusPDU) bool {
+    return m.ErrorFlag()
+}
+
+func ModbusPDUFunctionFlag(m IModbusPDU) uint8 {
+    return m.FunctionFlag()
+}
+
+func ModbusPDUResponse(m IModbusPDU) bool {
+    return m.Response()
+}
+
+
+func CastIModbusPDU(structType interface{}) IModbusPDU {
+    castFunc := func(typ interface{}) IModbusPDU {
+        if iModbusPDU, ok := typ.(IModbusPDU); ok {
+            return iModbusPDU
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastModbusPDU(structType interface{}) ModbusPDU {
+    castFunc := func(typ interface{}) ModbusPDU {
+        if sModbusPDU, ok := typ.(ModbusPDU); ok {
+            return sModbusPDU
+        }
+        if sModbusPDU, ok := typ.(*ModbusPDU); ok {
+            return *sModbusPDU
+        }
+        return ModbusPDU{}
+    }
+    return castFunc(structType)
+}
+
+func (m ModbusPDU) LengthInBits() uint16 {
+    var lengthInBits uint16 = 0
+
+    // Discriminator Field (errorFlag)
+    lengthInBits += 1
+
+    // Discriminator Field (functionFlag)
+    lengthInBits += 7
+
+    // Length of sub-type elements will be added by sub-type...
+
+    return lengthInBits
+}
+
+func (m ModbusPDU) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func ModbusPDUParse(io *utils.ReadBuffer, response bool) (spi.Message, error) {
+
+    // Discriminator Field (errorFlag) (Used as input to a switch field)
+    errorFlag, _errorFlagErr := io.ReadBit()
+    if _errorFlagErr != nil {
+        return nil, errors.New("Error parsing 'errorFlag' field " + _errorFlagErr.Error())
+    }
+
+    // Discriminator Field (functionFlag) (Used as input to a switch field)
+    functionFlag, _functionFlagErr := io.ReadUint8(7)
+    if _functionFlagErr != nil {
+        return nil, errors.New("Error parsing 'functionFlag' field " + _functionFlagErr.Error())
+    }
+
+    // Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
+    var initializer ModbusPDUInitializer
+    var typeSwitchError error
+    switch {
+    case errorFlag == true:
+        initializer, typeSwitchError = ModbusPDUErrorParse(io)
+    case errorFlag == false && functionFlag == 0x02 && response == false:
+        initializer, typeSwitchError = ModbusPDUReadDiscreteInputsRequestParse(io)
+    case errorFlag == false && functionFlag == 0x02 && response == true:
+        initializer, typeSwitchError = ModbusPDUReadDiscreteInputsResponseParse(io)
+    case errorFlag == false && functionFlag == 0x01 && response == false:
+        initializer, typeSwitchError = ModbusPDUReadCoilsRequestParse(io)
+    case errorFlag == false && functionFlag == 0x01 && response == true:
+        initializer, typeSwitchError = ModbusPDUReadCoilsResponseParse(io)
+    case errorFlag == false && functionFlag == 0x05 && response == false:
+        initializer, typeSwitchError = ModbusPDUWriteSingleCoilRequestParse(io)
+    case errorFlag == false && functionFlag == 0x05 && response == true:
+        initializer, typeSwitchError = ModbusPDUWriteSingleCoilResponseParse(io)
+    case errorFlag == false && functionFlag == 0x0F && response == false:
+        initializer, typeSwitchError = ModbusPDUWriteMultipleCoilsRequestParse(io)
+    case errorFlag == false && functionFlag == 0x0F && response == true:
+        initializer, typeSwitchError = ModbusPDUWriteMultipleCoilsResponseParse(io)
+    case errorFlag == false && functionFlag == 0x04 && response == false:
+        initializer, typeSwitchError = ModbusPDUReadInputRegistersRequestParse(io)
+    case errorFlag == false && functionFlag == 0x04 && response == true:
+        initializer, typeSwitchError = ModbusPDUReadInputRegistersResponseParse(io)
+    case errorFlag == false && functionFlag == 0x03 && response == false:
+        initializer, typeSwitchError = ModbusPDUReadHoldingRegistersRequestParse(io)
+    case errorFlag == false && functionFlag == 0x03 && response == true:
+        initializer, typeSwitchError = ModbusPDUReadHoldingRegistersResponseParse(io)
+    case errorFlag == false && functionFlag == 0x06 && response == false:
+        initializer, typeSwitchError = ModbusPDUWriteSingleRegisterRequestParse(io)
+    case errorFlag == false && functionFlag == 0x06 && response == true:
+        initializer, typeSwitchError = ModbusPDUWriteSingleRegisterResponseParse(io)
+    case errorFlag == false && functionFlag == 0x10 && response == false:
+        initializer, typeSwitchError = ModbusPDUWriteMultipleHoldingRegistersRequestParse(io)
+    case errorFlag == false && functionFlag == 0x10 && response == true:
+        initializer, typeSwitchError = ModbusPDUWriteMultipleHoldingRegistersResponseParse(io)
+    case errorFlag == false && functionFlag == 0x17 && response == false:
+        initializer, typeSwitchError = ModbusPDUReadWriteMultipleHoldingRegistersRequestParse(io)
+    case errorFlag == false && functionFlag == 0x17 && response == true:
+        initializer, typeSwitchError = ModbusPDUReadWriteMultipleHoldingRegistersResponseParse(io)
+    case errorFlag == false && functionFlag == 0x16 && response == false:
+        initializer, typeSwitchError = ModbusPDUMaskWriteHoldingRegisterRequestParse(io)
+    case errorFlag == false && functionFlag == 0x16 && response == true:
+        initializer, typeSwitchError = ModbusPDUMaskWriteHoldingRegisterResponseParse(io)
+    case errorFlag == false && functionFlag == 0x18 && response == false:
+        initializer, typeSwitchError = ModbusPDUReadFifoQueueRequestParse(io)
+    case errorFlag == false && functionFlag == 0x18 && response == true:
+        initializer, typeSwitchError = ModbusPDUReadFifoQueueResponseParse(io)
+    case errorFlag == false && functionFlag == 0x14 && response == false:
+        initializer, typeSwitchError = ModbusPDUReadFileRecordRequestParse(io)
+    case errorFlag == false && functionFlag == 0x14 && response == true:
+        initializer, typeSwitchError = ModbusPDUReadFileRecordResponseParse(io)
+    case errorFlag == false && functionFlag == 0x15 && response == false:
+        initializer, typeSwitchError = ModbusPDUWriteFileRecordRequestParse(io)
+    case errorFlag == false && functionFlag == 0x15 && response == true:
+        initializer, typeSwitchError = ModbusPDUWriteFileRecordResponseParse(io)
+    case errorFlag == false && functionFlag == 0x07 && response == false:
+        initializer, typeSwitchError = ModbusPDUReadExceptionStatusRequestParse(io)
+    case errorFlag == false && functionFlag == 0x07 && response == true:
+        initializer, typeSwitchError = ModbusPDUReadExceptionStatusResponseParse(io)
+    case errorFlag == false && functionFlag == 0x08 && response == false:
+        initializer, typeSwitchError = ModbusPDUDiagnosticRequestParse(io)
+    case errorFlag == false && functionFlag == 0x08 && response == true:
+        initializer, typeSwitchError = ModbusPDUDiagnosticResponseParse(io)
+    case errorFlag == false && functionFlag == 0x0B && response == false:
+        initializer, typeSwitchError = ModbusPDUGetComEventCounterRequestParse(io)
+    case errorFlag == false && functionFlag == 0x0B && response == true:
+        initializer, typeSwitchError = ModbusPDUGetComEventCounterResponseParse(io)
+    case errorFlag == false && functionFlag == 0x0C && response == false:
+        initializer, typeSwitchError = ModbusPDUGetComEventLogRequestParse(io)
+    case errorFlag == false && functionFlag == 0x0C && response == true:
+        initializer, typeSwitchError = ModbusPDUGetComEventLogResponseParse(io)
+    case errorFlag == false && functionFlag == 0x11 && response == false:
+        initializer, typeSwitchError = ModbusPDUReportServerIdRequestParse(io)
+    case errorFlag == false && functionFlag == 0x11 && response == true:
+        initializer, typeSwitchError = ModbusPDUReportServerIdResponseParse(io)
+    case errorFlag == false && functionFlag == 0x2B && response == false:
+        initializer, typeSwitchError = ModbusPDUReadDeviceIdentificationRequestParse(io)
+    case errorFlag == false && functionFlag == 0x2B && response == true:
+        initializer, typeSwitchError = ModbusPDUReadDeviceIdentificationResponseParse(io)
+    }
+    if typeSwitchError != nil {
+        return nil, errors.New("Error parsing sub-type for type-switch. " + typeSwitchError.Error())
+    }
+
+    // Create the instance
+    return initializer.initialize(), nil
+}
+
+func ModbusPDUSerialize(io utils.WriteBuffer, m ModbusPDU, i IModbusPDU, childSerialize func() error) error {
+
+    // Discriminator Field (errorFlag) (Used as input to a switch field)
+    errorFlag := bool(i.ErrorFlag())
+    _errorFlagErr := io.WriteBit((errorFlag))
+    if _errorFlagErr != nil {
+        return errors.New("Error serializing 'errorFlag' field " + _errorFlagErr.Error())
+    }
+
+    // Discriminator Field (functionFlag) (Used as input to a switch field)
+    functionFlag := uint8(i.FunctionFlag())
+    _functionFlagErr := io.WriteUint8(7, (functionFlag))
+    if _functionFlagErr != nil {
+        return errors.New("Error serializing 'functionFlag' field " + _functionFlagErr.Error())
+    }
+
+    // Switch field (Depending on the discriminator values, passes the serialization to a sub-type)
+    _typeSwitchErr := childSerialize()
+    if _typeSwitchErr != nil {
+        return errors.New("Error serializing sub-type field " + _typeSwitchErr.Error())
+    }
+
+    return nil
+}
+
+func (m *ModbusPDU) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            }
+        }
+    }
+}
+
+func (m ModbusPDU) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.modbus.readwrite.ModbusPDU"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUDiagnosticRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUDiagnosticRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUDiagnosticRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUDiagnosticRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUDiagnosticResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUDiagnosticResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUDiagnosticResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUDiagnosticResponse.go
diff --git a/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUError.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUError.go
new file mode 100644
index 0000000..84a26a7
--- /dev/null
+++ b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUError.go
@@ -0,0 +1,163 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+// The data-structure of this message
+type ModbusPDUError struct {
+    ExceptionCode IModbusErrorCode
+    ModbusPDU
+}
+
+// The corresponding interface
+type IModbusPDUError interface {
+    IModbusPDU
+    Serialize(io utils.WriteBuffer) error
+}
+
+// Accessors for discriminator values.
+func (m ModbusPDUError) ErrorFlag() bool {
+    return true
+}
+
+func (m ModbusPDUError) FunctionFlag() uint8 {
+    return 0
+}
+
+func (m ModbusPDUError) Response() bool {
+    return false
+}
+
+func (m ModbusPDUError) initialize() spi.Message {
+    return m
+}
+
+func NewModbusPDUError(exceptionCode IModbusErrorCode) ModbusPDUInitializer {
+    return &ModbusPDUError{ExceptionCode: exceptionCode}
+}
+
+func CastIModbusPDUError(structType interface{}) IModbusPDUError {
+    castFunc := func(typ interface{}) IModbusPDUError {
+        if iModbusPDUError, ok := typ.(IModbusPDUError); ok {
+            return iModbusPDUError
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastModbusPDUError(structType interface{}) ModbusPDUError {
+    castFunc := func(typ interface{}) ModbusPDUError {
+        if sModbusPDUError, ok := typ.(ModbusPDUError); ok {
+            return sModbusPDUError
+        }
+        if sModbusPDUError, ok := typ.(*ModbusPDUError); ok {
+            return *sModbusPDUError
+        }
+        return ModbusPDUError{}
+    }
+    return castFunc(structType)
+}
+
+func (m ModbusPDUError) LengthInBits() uint16 {
+    var lengthInBits uint16 = m.ModbusPDU.LengthInBits()
+
+    // Enum Field (exceptionCode)
+    lengthInBits += 8
+
+    return lengthInBits
+}
+
+func (m ModbusPDUError) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func ModbusPDUErrorParse(io *utils.ReadBuffer) (ModbusPDUInitializer, error) {
+
+    // Enum field (exceptionCode)
+    exceptionCode, _exceptionCodeErr := ModbusErrorCodeParse(io)
+    if _exceptionCodeErr != nil {
+        return nil, errors.New("Error parsing 'exceptionCode' field " + _exceptionCodeErr.Error())
+    }
+
+    // Create the instance
+    return NewModbusPDUError(exceptionCode), nil
+}
+
+func (m ModbusPDUError) Serialize(io utils.WriteBuffer) error {
+    ser := func() error {
+
+    // Enum field (exceptionCode)
+    exceptionCode := CastModbusErrorCode(m.ExceptionCode)
+    _exceptionCodeErr := exceptionCode.Serialize(io)
+    if _exceptionCodeErr != nil {
+        return errors.New("Error serializing 'exceptionCode' field " + _exceptionCodeErr.Error())
+    }
+
+        return nil
+    }
+    return ModbusPDUSerialize(io, m.ModbusPDU, CastIModbusPDU(m), ser)
+}
+
+func (m *ModbusPDUError) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "exceptionCode":
+                var data *ModbusErrorCode
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.ExceptionCode = data
+            }
+        }
+    }
+}
+
+func (m ModbusPDUError) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.modbus.readwrite.ModbusPDUError"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.ExceptionCode, xml.StartElement{Name: xml.Name{Local: "exceptionCode"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventCounterRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventCounterRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventCounterRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventCounterRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventCounterResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventCounterResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventCounterResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventCounterResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUMaskWriteHoldingRegisterRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUMaskWriteHoldingRegisterRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUMaskWriteHoldingRegisterRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUMaskWriteHoldingRegisterRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUMaskWriteHoldingRegisterResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUMaskWriteHoldingRegisterResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUMaskWriteHoldingRegisterResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUMaskWriteHoldingRegisterResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDeviceIdentificationRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDeviceIdentificationRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDeviceIdentificationRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDeviceIdentificationRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDeviceIdentificationResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDeviceIdentificationResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDeviceIdentificationResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDeviceIdentificationResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadExceptionStatusRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadExceptionStatusRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadExceptionStatusRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadExceptionStatusRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadExceptionStatusResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadExceptionStatusResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadExceptionStatusResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadExceptionStatusResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFifoQueueRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFifoQueueRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFifoQueueRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFifoQueueRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFifoQueueResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFifoQueueResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFifoQueueResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFifoQueueResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordRequestItem.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordRequestItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordRequestItem.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordRequestItem.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponseItem.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponseItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponseItem.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponseItem.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequestItem.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequestItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequestItem.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequestItem.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponseItem.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponseItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponseItem.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponseItem.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleCoilRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleCoilRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleCoilRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleCoilRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleCoilResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleCoilResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleCoilResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleCoilResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleRegisterRequest.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleRegisterRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleRegisterRequest.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleRegisterRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleRegisterResponse.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleRegisterResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleRegisterResponse.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteSingleRegisterResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusSerialADU.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusSerialADU.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusSerialADU.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusSerialADU.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusTcpADU.go b/plc4go/internal/plc4go/modbus/readwrite/model/ModbusTcpADU.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusTcpADU.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ModbusTcpADU.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ParserHelper.go b/plc4go/internal/plc4go/modbus/readwrite/model/ParserHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ParserHelper.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/ParserHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/XmlParserHelper.go b/plc4go/internal/plc4go/modbus/readwrite/model/XmlParserHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/modbus/readwrite/model/XmlParserHelper.go
rename to plc4go/internal/plc4go/modbus/readwrite/model/XmlParserHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadRequest.go b/plc4go/internal/plc4go/model/DefaultPlcReadRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/DefaultPlcReadRequest.go
rename to plc4go/internal/plc4go/model/DefaultPlcReadRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go b/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/DefaultPlcReadResponse.go
rename to plc4go/internal/plc4go/model/DefaultPlcReadResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/model/DefaultPlcWriteRequest.go b/plc4go/internal/plc4go/model/DefaultPlcWriteRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/DefaultPlcWriteRequest.go
rename to plc4go/internal/plc4go/model/DefaultPlcWriteRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/model/DefaultPlcWriteResponse.go b/plc4go/internal/plc4go/model/DefaultPlcWriteResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/DefaultPlcWriteResponse.go
rename to plc4go/internal/plc4go/model/DefaultPlcWriteResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/model/RequestInterceptor.go b/plc4go/internal/plc4go/model/RequestInterceptor.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/RequestInterceptor.go
rename to plc4go/internal/plc4go/model/RequestInterceptor.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/BOOL.go b/plc4go/internal/plc4go/model/values/BOOL.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/BOOL.go
rename to plc4go/internal/plc4go/model/values/BOOL.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/BYTE.go b/plc4go/internal/plc4go/model/values/BYTE.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/BYTE.go
rename to plc4go/internal/plc4go/model/values/BYTE.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/CHAR.go b/plc4go/internal/plc4go/model/values/CHAR.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/CHAR.go
rename to plc4go/internal/plc4go/model/values/CHAR.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/DATE.go b/plc4go/internal/plc4go/model/values/DATE.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/DATE.go
rename to plc4go/internal/plc4go/model/values/DATE.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/DATE_AND_TIME.go b/plc4go/internal/plc4go/model/values/DATE_AND_TIME.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/DATE_AND_TIME.go
rename to plc4go/internal/plc4go/model/values/DATE_AND_TIME.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/DINT.go b/plc4go/internal/plc4go/model/values/DINT.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/DINT.go
rename to plc4go/internal/plc4go/model/values/DINT.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/DWORD.go b/plc4go/internal/plc4go/model/values/DWORD.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/DWORD.go
rename to plc4go/internal/plc4go/model/values/DWORD.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/IEC61131ValueHandler.go b/plc4go/internal/plc4go/model/values/IEC61131ValueHandler.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/IEC61131ValueHandler.go
rename to plc4go/internal/plc4go/model/values/IEC61131ValueHandler.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/INT.go b/plc4go/internal/plc4go/model/values/INT.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/INT.go
rename to plc4go/internal/plc4go/model/values/INT.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/LINT.go b/plc4go/internal/plc4go/model/values/LINT.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/LINT.go
rename to plc4go/internal/plc4go/model/values/LINT.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/LREAL.go b/plc4go/internal/plc4go/model/values/LREAL.go
similarity index 98%
rename from sandbox/plc4go/internal/plc4go/model/values/LREAL.go
rename to plc4go/internal/plc4go/model/values/LREAL.go
index f59e4cd..d6f6d4a 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/LREAL.go
+++ b/plc4go/internal/plc4go/model/values/LREAL.go
@@ -150,7 +150,7 @@ func (m PlcLREAL) IsString() bool {
 }
 
 func (m PlcLREAL) GetString() string {
-	return fmt.Sprintf("%f", m.GetFloat64())
+	return fmt.Sprintf("%g", m.GetFloat64())
 }
 
 func (m PlcLREAL) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/LTIME.go b/plc4go/internal/plc4go/model/values/LTIME.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/LTIME.go
rename to plc4go/internal/plc4go/model/values/LTIME.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/LWORD.go b/plc4go/internal/plc4go/model/values/LWORD.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/LWORD.go
rename to plc4go/internal/plc4go/model/values/LWORD.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/NULL.go b/plc4go/internal/plc4go/model/values/NULL.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/NULL.go
rename to plc4go/internal/plc4go/model/values/NULL.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/PlcList.go b/plc4go/internal/plc4go/model/values/PlcList.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/PlcList.go
rename to plc4go/internal/plc4go/model/values/PlcList.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/PlcSimpleValueAdapter.go b/plc4go/internal/plc4go/model/values/PlcSimpleValueAdapter.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/PlcSimpleValueAdapter.go
rename to plc4go/internal/plc4go/model/values/PlcSimpleValueAdapter.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/PlcStruct.go b/plc4go/internal/plc4go/model/values/PlcStruct.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/PlcStruct.go
rename to plc4go/internal/plc4go/model/values/PlcStruct.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/PlcValueAdapter.go b/plc4go/internal/plc4go/model/values/PlcValueAdapter.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/PlcValueAdapter.go
rename to plc4go/internal/plc4go/model/values/PlcValueAdapter.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/REAL.go b/plc4go/internal/plc4go/model/values/REAL.go
similarity index 98%
rename from sandbox/plc4go/internal/plc4go/model/values/REAL.go
rename to plc4go/internal/plc4go/model/values/REAL.go
index b0f46ec..b77ceb6 100644
--- a/sandbox/plc4go/internal/plc4go/model/values/REAL.go
+++ b/plc4go/internal/plc4go/model/values/REAL.go
@@ -144,7 +144,7 @@ func (m PlcREAL) IsString() bool {
 }
 
 func (m PlcREAL) GetString() string {
-	return fmt.Sprintf("%f", m.GetFloat32())
+	return fmt.Sprintf("%g", m.GetFloat32())
 }
 
 func (m PlcREAL) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
diff --git a/sandbox/plc4go/internal/plc4go/model/values/SINT.go b/plc4go/internal/plc4go/model/values/SINT.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/SINT.go
rename to plc4go/internal/plc4go/model/values/SINT.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/STRING.go b/plc4go/internal/plc4go/model/values/STRING.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/STRING.go
rename to plc4go/internal/plc4go/model/values/STRING.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/TIME.go b/plc4go/internal/plc4go/model/values/TIME.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/TIME.go
rename to plc4go/internal/plc4go/model/values/TIME.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/TIME_OF_DAY.go b/plc4go/internal/plc4go/model/values/TIME_OF_DAY.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/TIME_OF_DAY.go
rename to plc4go/internal/plc4go/model/values/TIME_OF_DAY.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/UDINT.go b/plc4go/internal/plc4go/model/values/UDINT.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/UDINT.go
rename to plc4go/internal/plc4go/model/values/UDINT.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/UINT.go b/plc4go/internal/plc4go/model/values/UINT.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/UINT.go
rename to plc4go/internal/plc4go/model/values/UINT.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/ULINT.go b/plc4go/internal/plc4go/model/values/ULINT.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/ULINT.go
rename to plc4go/internal/plc4go/model/values/ULINT.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/USINT.go b/plc4go/internal/plc4go/model/values/USINT.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/USINT.go
rename to plc4go/internal/plc4go/model/values/USINT.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/WCHAR.go b/plc4go/internal/plc4go/model/values/WCHAR.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/WCHAR.go
rename to plc4go/internal/plc4go/model/values/WCHAR.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/WORD.go b/plc4go/internal/plc4go/model/values/WORD.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/WORD.go
rename to plc4go/internal/plc4go/model/values/WORD.go
diff --git a/sandbox/plc4go/internal/plc4go/model/values/WSTRING.go b/plc4go/internal/plc4go/model/values/WSTRING.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/model/values/WSTRING.go
rename to plc4go/internal/plc4go/model/values/WSTRING.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/S7Driver.go b/plc4go/internal/plc4go/s7/S7Driver.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/S7Driver.go
rename to plc4go/internal/plc4go/s7/S7Driver.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacket.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPPacket.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacket.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPPacket.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketConnectionRequest.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketConnectionRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketConnectionRequest.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPPacketConnectionRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketConnectionResponse.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketConnectionResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketConnectionResponse.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPPacketConnectionResponse.go
diff --git a/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketData.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketData.go
new file mode 100644
index 0000000..8595bee
--- /dev/null
+++ b/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketData.go
@@ -0,0 +1,183 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "encoding/xml"
+    "errors"
+    "io"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+// The data-structure of this message
+type COTPPacketData struct {
+    Eot bool
+    TpduRef uint8
+    COTPPacket
+}
+
+// The corresponding interface
+type ICOTPPacketData interface {
+    ICOTPPacket
+    Serialize(io utils.WriteBuffer) error
+}
+
+// Accessors for discriminator values.
+func (m COTPPacketData) TpduCode() uint8 {
+    return 0xF0
+}
+
+func (m COTPPacketData) initialize(parameters []ICOTPParameter, payload *IS7Message) spi.Message {
+    m.Parameters = parameters
+    m.Payload = payload
+    return m
+}
+
+func NewCOTPPacketData(eot bool, tpduRef uint8) COTPPacketInitializer {
+    return &COTPPacketData{Eot: eot, TpduRef: tpduRef}
+}
+
+func CastICOTPPacketData(structType interface{}) ICOTPPacketData {
+    castFunc := func(typ interface{}) ICOTPPacketData {
+        if iCOTPPacketData, ok := typ.(ICOTPPacketData); ok {
+            return iCOTPPacketData
+        }
+        return nil
+    }
+    return castFunc(structType)
+}
+
+func CastCOTPPacketData(structType interface{}) COTPPacketData {
+    castFunc := func(typ interface{}) COTPPacketData {
+        if sCOTPPacketData, ok := typ.(COTPPacketData); ok {
+            return sCOTPPacketData
+        }
+        if sCOTPPacketData, ok := typ.(*COTPPacketData); ok {
+            return *sCOTPPacketData
+        }
+        return COTPPacketData{}
+    }
+    return castFunc(structType)
+}
+
+func (m COTPPacketData) LengthInBits() uint16 {
+    var lengthInBits uint16 = m.COTPPacket.LengthInBits()
+
+    // Simple field (eot)
+    lengthInBits += 1
+
+    // Simple field (tpduRef)
+    lengthInBits += 7
+
+    return lengthInBits
+}
+
+func (m COTPPacketData) LengthInBytes() uint16 {
+    return m.LengthInBits() / 8
+}
+
+func COTPPacketDataParse(io *utils.ReadBuffer) (COTPPacketInitializer, error) {
+
+    // Simple Field (eot)
+    eot, _eotErr := io.ReadBit()
+    if _eotErr != nil {
+        return nil, errors.New("Error parsing 'eot' field " + _eotErr.Error())
+    }
+
+    // Simple Field (tpduRef)
+    tpduRef, _tpduRefErr := io.ReadUint8(7)
+    if _tpduRefErr != nil {
+        return nil, errors.New("Error parsing 'tpduRef' field " + _tpduRefErr.Error())
+    }
+
+    // Create the instance
+    return NewCOTPPacketData(eot, tpduRef), nil
+}
+
+func (m COTPPacketData) Serialize(io utils.WriteBuffer) error {
+    ser := func() error {
+
+    // Simple Field (eot)
+    eot := bool(m.Eot)
+    _eotErr := io.WriteBit((eot))
+    if _eotErr != nil {
+        return errors.New("Error serializing 'eot' field " + _eotErr.Error())
+    }
+
+    // Simple Field (tpduRef)
+    tpduRef := uint8(m.TpduRef)
+    _tpduRefErr := io.WriteUint8(7, (tpduRef))
+    if _tpduRefErr != nil {
+        return errors.New("Error serializing 'tpduRef' field " + _tpduRefErr.Error())
+    }
+
+        return nil
+    }
+    return COTPPacketSerialize(io, m.COTPPacket, CastICOTPPacket(m), ser)
+}
+
+func (m *COTPPacketData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+    for {
+        token, err := d.Token()
+        if err != nil {
+            if err == io.EOF {
+                return nil
+            }
+            return err
+        }
+        switch token.(type) {
+        case xml.StartElement:
+            tok := token.(xml.StartElement)
+            switch tok.Name.Local {
+            case "eot":
+                var data bool
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.Eot = data
+            case "tpduRef":
+                var data uint8
+                if err := d.DecodeElement(&data, &tok); err != nil {
+                    return err
+                }
+                m.TpduRef = data
+            }
+        }
+    }
+}
+
+func (m COTPPacketData) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+    if err := e.EncodeToken(xml.StartElement{Name: start.Name, Attr: []xml.Attr{
+            {Name: xml.Name{Local: "className"}, Value: "org.apache.plc4x.java.s7.readwrite.COTPPacketData"},
+        }}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.Eot, xml.StartElement{Name: xml.Name{Local: "eot"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeElement(m.TpduRef, xml.StartElement{Name: xml.Name{Local: "tpduRef"}}); err != nil {
+        return err
+    }
+    if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
+        return err
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketDisconnectRequest.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketDisconnectRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketDisconnectRequest.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPPacketDisconnectRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketDisconnectResponse.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketDisconnectResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketDisconnectResponse.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPPacketDisconnectResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketTpduError.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketTpduError.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPPacketTpduError.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPPacketTpduError.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameter.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPParameter.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameter.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPParameter.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterCalledTsap.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterCalledTsap.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterCalledTsap.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPParameterCalledTsap.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterCallingTsap.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterCallingTsap.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterCallingTsap.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPParameterCallingTsap.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterChecksum.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterChecksum.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterChecksum.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPParameterChecksum.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterDisconnectAdditionalInformation.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterDisconnectAdditionalInformation.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterDisconnectAdditionalInformation.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPParameterDisconnectAdditionalInformation.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterTpduSize.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterTpduSize.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPParameterTpduSize.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPParameterTpduSize.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPProtocolClass.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPProtocolClass.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPProtocolClass.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPProtocolClass.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPTpduSize.go b/plc4go/internal/plc4go/s7/readwrite/model/COTPTpduSize.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/COTPTpduSize.go
rename to plc4go/internal/plc4go/s7/readwrite/model/COTPTpduSize.go
diff --git a/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go b/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
new file mode 100644
index 0000000..52d974f
--- /dev/null
+++ b/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
@@ -0,0 +1,440 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model/values"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
+)
+
+func DataItemParse(io *utils.ReadBuffer, dataProtocolId string, stringLength int32) (api.PlcValue, error) {
+    switch {
+        case dataProtocolId == "IEC61131_BOOL": // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            if _, _err := io.ReadUint8(7); _err != nil {
+                return nil, errors.New("Error parsing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadBit()
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcBOOL(value), nil
+        case dataProtocolId == "IEC61131_BYTE": // BOOL
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int((8)); i++ {
+                _item, _itemErr := DataItemParse(io, dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataProtocolId == "IEC61131_WORD": // BOOL
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int((16)); i++ {
+                _item, _itemErr := DataItemParse(io, dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataProtocolId == "IEC61131_DWORD": // BOOL
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int((32)); i++ {
+                _item, _itemErr := DataItemParse(io, dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataProtocolId == "IEC61131_LWORD": // BOOL
+
+            // Array Field (value)
+            var value []api.PlcValue
+            for i := 0; i < int((64)); i++ {
+                _item, _itemErr := DataItemParse(io, dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
+            return values.NewPlcList(value), nil
+        case dataProtocolId == "IEC61131_SINT": // SINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSINT(value), nil
+        case dataProtocolId == "IEC61131_USINT": // USINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint8(8)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUSINT(value), nil
+        case dataProtocolId == "IEC61131_INT": // INT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcINT(value), nil
+        case dataProtocolId == "IEC61131_UINT": // UINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint16(16)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUINT(value), nil
+        case dataProtocolId == "IEC61131_DINT": // DINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcDINT(value), nil
+        case dataProtocolId == "IEC61131_UDINT": // UDINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcUDINT(value), nil
+        case dataProtocolId == "IEC61131_LINT": // LINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadInt64(64)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcLINT(value), nil
+        case dataProtocolId == "IEC61131_ULINT": // ULINT
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadUint64(64)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcULINT(value), nil
+        case dataProtocolId == "IEC61131_REAL": // REAL
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadFloat32(32)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcREAL(value), nil
+        case dataProtocolId == "IEC61131_LREAL": // LREAL
+
+            // Simple Field (value)
+            value, _valueErr := io.ReadFloat64(64)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcLREAL(value), nil
+        case dataProtocolId == "IEC61131_CHAR": // CHAR
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS7Char(io, "UTF-8")
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcCHAR(value), nil
+        case dataProtocolId == "IEC61131_WCHAR": // CHAR
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS7Char(io, "UTF-16")
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcCHAR(value), nil
+        case dataProtocolId == "IEC61131_STRING": // STRING
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS7String(io, stringLength, "UTF-8")
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSTRING(value), nil
+        case dataProtocolId == "IEC61131_WSTRING": // STRING
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS7String(io, stringLength, "UTF-16")
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcSTRING(value), nil
+        case dataProtocolId == "IEC61131_TIME": // Time
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaTime(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
+        case dataProtocolId == "S7_S5TIME": // Time
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS5Time(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
+        case dataProtocolId == "IEC61131_LTIME": // Time
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaLTime(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
+        case dataProtocolId == "IEC61131_DATE": // Date
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaDate(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
+        case dataProtocolId == "IEC61131_TIME_OF_DAY": // Time
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaTimeOfDay(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
+        case dataProtocolId == "IEC61131_DATE_AND_TIME": // DateTime
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseTiaDateTime(io)
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcTIME(value), nil
+    }
+    return nil, errors.New("unsupported type")
+}
+
+func DataItemSerialize(io *utils.WriteBuffer, value api.PlcValue, dataProtocolId string, stringLength int32) error {
+    switch {
+        case dataProtocolId == "IEC61131_BOOL": // BOOL
+
+            // Reserved Field (Just skip the bytes)
+            if _err := io.WriteUint8(7, uint8(0x00)); _err != nil {
+                return errors.New("Error serializing reserved field " + _err.Error())
+            }
+
+            // Simple Field (value)
+            if _err := io.WriteBit(value.GetBool()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_BYTE": // BOOL
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32((8)); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataProtocolId == "IEC61131_WORD": // BOOL
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32((16)); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataProtocolId == "IEC61131_DWORD": // BOOL
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32((32)); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataProtocolId == "IEC61131_LWORD": // BOOL
+
+            // Array Field (value)
+            for i := uint32(0); i < uint32((64)); i++ {
+                _itemErr := DataItemSerialize(io, value.GetIndex(i), dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return errors.New("Error serializing 'value' field " + _itemErr.Error())
+                }
+            }
+        case dataProtocolId == "IEC61131_SINT": // SINT
+
+            // Simple Field (value)
+            if _err := io.WriteInt8(8, value.GetInt8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_USINT": // USINT
+
+            // Simple Field (value)
+            if _err := io.WriteUint8(8, value.GetUint8()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_INT": // INT
+
+            // Simple Field (value)
+            if _err := io.WriteInt16(16, value.GetInt16()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_UINT": // UINT
+
+            // Simple Field (value)
+            if _err := io.WriteUint16(16, value.GetUint16()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_DINT": // DINT
+
+            // Simple Field (value)
+            if _err := io.WriteInt32(32, value.GetInt32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_UDINT": // UDINT
+
+            // Simple Field (value)
+            if _err := io.WriteUint32(32, value.GetUint32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_LINT": // LINT
+
+            // Simple Field (value)
+            if _err := io.WriteInt64(64, value.GetInt64()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_ULINT": // ULINT
+
+            // Simple Field (value)
+            if _err := io.WriteUint64(64, value.GetUint64()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_REAL": // REAL
+
+            // Simple Field (value)
+            if _err := io.WriteFloat32(32, value.GetFloat32()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_LREAL": // LREAL
+
+            // Simple Field (value)
+            if _err := io.WriteFloat64(64, value.GetFloat64()); _err != nil {
+                return errors.New("Error serializing 'value' field " + _err.Error())
+            }
+        case dataProtocolId == "IEC61131_CHAR": // CHAR
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeS7Char(io, value, "UTF-8")
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "IEC61131_WCHAR": // CHAR
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeS7Char(io, value, "UTF-16")
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "IEC61131_STRING": // STRING
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeS7String(io, value, stringLength, "UTF-8")
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "IEC61131_WSTRING": // STRING
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeS7String(io, value, stringLength, "UTF-16")
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "IEC61131_TIME": // Time
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeTiaTime(io, value)
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "S7_S5TIME": // Time
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeS5Time(io, value)
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "IEC61131_LTIME": // Time
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeTiaLTime(io, value)
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "IEC61131_DATE": // Date
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeTiaDate(io, value)
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "IEC61131_TIME_OF_DAY": // Time
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeTiaTimeOfDay(io, value)
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        case dataProtocolId == "IEC61131_DATE_AND_TIME": // DateTime
+
+            // Manual Field (value)
+            _valueErr := StaticHelperSerializeTiaDateTime(io, value)
+            if _valueErr != nil {
+                return errors.New("Error serializing 'value' field " + _valueErr.Error())
+            }
+        default:
+
+            return errors.New("unsupported type")
+    }
+    return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataTransportErrorCode.go b/plc4go/internal/plc4go/s7/readwrite/model/DataTransportErrorCode.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataTransportErrorCode.go
rename to plc4go/internal/plc4go/s7/readwrite/model/DataTransportErrorCode.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataTransportSize.go b/plc4go/internal/plc4go/s7/readwrite/model/DataTransportSize.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataTransportSize.go
rename to plc4go/internal/plc4go/s7/readwrite/model/DataTransportSize.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DeviceGroup.go b/plc4go/internal/plc4go/s7/readwrite/model/DeviceGroup.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/DeviceGroup.go
rename to plc4go/internal/plc4go/s7/readwrite/model/DeviceGroup.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/MemoryArea.go b/plc4go/internal/plc4go/s7/readwrite/model/MemoryArea.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/MemoryArea.go
rename to plc4go/internal/plc4go/s7/readwrite/model/MemoryArea.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/ParserHelper.go b/plc4go/internal/plc4go/s7/readwrite/model/ParserHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/ParserHelper.go
rename to plc4go/internal/plc4go/s7/readwrite/model/ParserHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7Address.go b/plc4go/internal/plc4go/s7/readwrite/model/S7Address.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7Address.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7Address.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7AddressAny.go b/plc4go/internal/plc4go/s7/readwrite/model/S7AddressAny.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7AddressAny.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7AddressAny.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7Message.go b/plc4go/internal/plc4go/s7/readwrite/model/S7Message.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7Message.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7Message.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7MessageRequest.go b/plc4go/internal/plc4go/s7/readwrite/model/S7MessageRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7MessageRequest.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7MessageRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7MessageResponse.go b/plc4go/internal/plc4go/s7/readwrite/model/S7MessageResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7MessageResponse.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7MessageResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7MessageResponseData.go b/plc4go/internal/plc4go/s7/readwrite/model/S7MessageResponseData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7MessageResponseData.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7MessageResponseData.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7MessageUserData.go b/plc4go/internal/plc4go/s7/readwrite/model/S7MessageUserData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7MessageUserData.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7MessageUserData.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7Parameter.go b/plc4go/internal/plc4go/s7/readwrite/model/S7Parameter.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7Parameter.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7Parameter.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterReadVarRequest.go b/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterReadVarRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterReadVarRequest.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7ParameterReadVarRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterReadVarResponse.go b/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterReadVarResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterReadVarResponse.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7ParameterReadVarResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterSetupCommunication.go b/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterSetupCommunication.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterSetupCommunication.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7ParameterSetupCommunication.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserData.go b/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserData.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserData.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserDataItem.go b/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserDataItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserDataItem.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserDataItem.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserDataItemCPUFunctions.go b/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserDataItemCPUFunctions.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserDataItemCPUFunctions.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7ParameterUserDataItemCPUFunctions.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterWriteVarRequest.go b/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterWriteVarRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterWriteVarRequest.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7ParameterWriteVarRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterWriteVarResponse.go b/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterWriteVarResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7ParameterWriteVarResponse.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7ParameterWriteVarResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7Payload.go b/plc4go/internal/plc4go/s7/readwrite/model/S7Payload.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7Payload.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7Payload.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadReadVarResponse.go b/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadReadVarResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadReadVarResponse.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7PayloadReadVarResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserData.go b/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserData.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserData.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserData.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItem.go b/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItem.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItem.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItemCpuFunctionReadSzlRequest.go b/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItemCpuFunctionReadSzlRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItemCpuFunctionReadSzlRequest.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItemCpuFunctionReadSzlRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItemCpuFunctionReadSzlResponse.go b/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItemCpuFunctionReadSzlResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItemCpuFunctionReadSzlResponse.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7PayloadUserDataItemCpuFunctionReadSzlResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadWriteVarRequest.go b/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadWriteVarRequest.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadWriteVarRequest.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7PayloadWriteVarRequest.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadWriteVarResponse.go b/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadWriteVarResponse.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7PayloadWriteVarResponse.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7PayloadWriteVarResponse.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go b/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadDataItem.go b/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadDataItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadDataItem.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadDataItem.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadStatusItem.go b/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadStatusItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadStatusItem.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadStatusItem.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarRequestParameterItem.go b/plc4go/internal/plc4go/s7/readwrite/model/S7VarRequestParameterItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarRequestParameterItem.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7VarRequestParameterItem.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarRequestParameterItemAddress.go b/plc4go/internal/plc4go/s7/readwrite/model/S7VarRequestParameterItemAddress.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarRequestParameterItemAddress.go
rename to plc4go/internal/plc4go/s7/readwrite/model/S7VarRequestParameterItemAddress.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlDataTreeItem.go b/plc4go/internal/plc4go/s7/readwrite/model/SzlDataTreeItem.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlDataTreeItem.go
rename to plc4go/internal/plc4go/s7/readwrite/model/SzlDataTreeItem.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlId.go b/plc4go/internal/plc4go/s7/readwrite/model/SzlId.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlId.go
rename to plc4go/internal/plc4go/s7/readwrite/model/SzlId.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlModuleTypeClass.go b/plc4go/internal/plc4go/s7/readwrite/model/SzlModuleTypeClass.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlModuleTypeClass.go
rename to plc4go/internal/plc4go/s7/readwrite/model/SzlModuleTypeClass.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlSublist.go b/plc4go/internal/plc4go/s7/readwrite/model/SzlSublist.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlSublist.go
rename to plc4go/internal/plc4go/s7/readwrite/model/SzlSublist.go
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/TPKTPacket.go b/plc4go/internal/plc4go/s7/readwrite/model/TPKTPacket.go
similarity index 100%
rename from sandbox/plc4go/internal/plc4go/s7/readwrite/model/TPKTPacket.go
rename to plc4go/internal/plc4go/s7/readwrite/model/TPKTPacket.go
diff --git a/plc4go/internal/plc4go/s7/readwrite/model/TransportSize.go b/plc4go/internal/plc4go/s7/readwrite/model/TransportSize.go
new file mode 100644
index 0000000..6c3af51
--- /dev/null
+++ b/plc4go/internal/plc4go/s7/readwrite/model/TransportSize.go
@@ -0,0 +1,695 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+type TransportSize int8
+
+type ITransportSize interface {
+    spi.Message
+    Supported_S7_300() bool
+    Supported_LOGO() bool
+    SizeInBytes() uint8
+    Supported_S7_400() bool
... 9868 lines suppressed ...