You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2024/08/29 11:57:58 UTC

(plc4x) branch develop updated: feat(plc4py): Parser Serializer Test Runner (#1737)

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

hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new 3a71145100 feat(plc4py): Parser Serializer Test Runner (#1737)
3a71145100 is described below

commit 3a71145100369fbe61bd4cd4204be5db1f8b5f89
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Thu Aug 29 19:57:54 2024 +0800

    feat(plc4py): Parser Serializer Test Runner (#1737)
    
    * fix(plc4py): Add plugin interface for transports
    
    * feat(plc4py): XML Test Suite Loader initial outline
    
    * feat(plc4py): XML Test Suite Loader initial test module
    
    * feat(plc4py): Change XML test suite to use xsdata
    
    * feat(plc4py): Test cases are automatically generated from parser serializer test files
    
    * feat(plc4py): start looking at implementing actual test
    
    * feat(plc4py): Parser Serializer Raw Byte Buffer is parsed correctly
    
    * feat(plc4py): Fixed passing of parameters and implemented a length based array
    
    * feat(plc4py): Implemented the XmlBasedBuffer
    
    * feat(plc4py): Realized I don't need to implement xml comparisions. Using the raw bytes to compare.
    
    * feat(plc4py): clean up the parser-serializer code a bit and move to driver specific section
    
    * feat(plc4py): tried to fix tests
    
    * feat(plc4py): Merged the transport plugin
    
    * feat(plc4py): Fixed issues with writing floats as ints in the byte based buffer
    
    * feat(plc4py): Removed unused files
    
    * feat(plc4py): Fixed an in issue with a type hint for test case
    
    * feat(plc4py): merge develop and formatting fixes
---
 .../python/PythonLanguageTemplateHelper.java       |   4 +-
 .../python/complex-type-template.python.ftlh       |  15 +
 plc4py/plc4py/PlcDriverManager.py                  |  55 ++-
 plc4py/plc4py/__init__.py                          |   4 -
 plc4py/plc4py/api/PlcConnection.py                 |   7 +-
 plc4py/plc4py/api/PlcDriver.py                     |   2 +-
 plc4py/plc4py/api/messages/PlcRequest.py           |   2 +-
 plc4py/plc4py/api/messages/PlcResponse.py          |   4 +-
 plc4py/plc4py/api/value/PlcValue.py                |   4 +-
 plc4py/plc4py/drivers/__init__.py                  |   4 +
 plc4py/plc4py/drivers/mock/MockConnection.py       |  15 +-
 .../plc4py/drivers/mock/MockReadRequestBuilder.py  |   6 +-
 plc4py/plc4py/drivers/modbus/ModbusConnection.py   |  14 +-
 plc4py/plc4py/drivers/modbus/ModbusDevice.py       |  31 +-
 plc4py/plc4py/drivers/modbus/ModbusProtocol.py     |   5 +-
 plc4py/plc4py/drivers/umas/UmasConnection.py       |  21 +-
 plc4py/plc4py/drivers/umas/UmasDevice.py           |  48 +-
 plc4py/plc4py/drivers/umas/UmasProtocol.py         |  12 +-
 plc4py/plc4py/drivers/umas/UmasTag.py              |   3 +-
 plc4py/plc4py/drivers/umas/UmasVariables.py        |  15 +-
 plc4py/plc4py/protocols/modbus/StaticHelper.py     |  66 +--
 .../plc4py/protocols/modbus/readwrite/ModbusADU.py |   6 +
 .../protocols/modbus/readwrite/ModbusAsciiADU.py   |   6 +
 .../plc4py/protocols/modbus/readwrite/ModbusPDU.py |   5 +
 .../modbus/readwrite/ModbusPDUDiagnosticRequest.py |   4 +
 .../readwrite/ModbusPDUDiagnosticResponse.py       |   4 +
 .../protocols/modbus/readwrite/ModbusPDUError.py   |   4 +
 .../ModbusPDUGetComEventCounterRequest.py          |   4 +
 .../ModbusPDUGetComEventCounterResponse.py         |   4 +
 .../readwrite/ModbusPDUGetComEventLogRequest.py    |   4 +
 .../readwrite/ModbusPDUGetComEventLogResponse.py   |   4 +
 .../ModbusPDUMaskWriteHoldingRegisterRequest.py    |   4 +
 .../ModbusPDUMaskWriteHoldingRegisterResponse.py   |   4 +
 .../modbus/readwrite/ModbusPDUReadCoilsRequest.py  |   4 +
 .../modbus/readwrite/ModbusPDUReadCoilsResponse.py |   4 +
 .../ModbusPDUReadDeviceIdentificationRequest.py    |   4 +
 .../ModbusPDUReadDeviceIdentificationResponse.py   |   4 +
 .../ModbusPDUReadDiscreteInputsRequest.py          |   4 +
 .../ModbusPDUReadDiscreteInputsResponse.py         |   4 +
 .../ModbusPDUReadExceptionStatusRequest.py         |   4 +
 .../ModbusPDUReadExceptionStatusResponse.py        |   4 +
 .../readwrite/ModbusPDUReadFifoQueueRequest.py     |   4 +
 .../readwrite/ModbusPDUReadFifoQueueResponse.py    |   4 +
 .../readwrite/ModbusPDUReadFileRecordRequest.py    |   8 +-
 .../readwrite/ModbusPDUReadFileRecordResponse.py   |   8 +-
 .../ModbusPDUReadHoldingRegistersRequest.py        |   4 +
 .../ModbusPDUReadHoldingRegistersResponse.py       |   4 +
 .../ModbusPDUReadInputRegistersRequest.py          |   4 +
 .../ModbusPDUReadInputRegistersResponse.py         |   4 +
 ...sPDUReadWriteMultipleHoldingRegistersRequest.py |   4 +
 ...PDUReadWriteMultipleHoldingRegistersResponse.py |   4 +
 .../readwrite/ModbusPDUReportServerIdRequest.py    |   4 +
 .../readwrite/ModbusPDUReportServerIdResponse.py   |   4 +
 .../readwrite/ModbusPDUWriteFileRecordRequest.py   |   8 +-
 .../readwrite/ModbusPDUWriteFileRecordResponse.py  |   8 +-
 .../ModbusPDUWriteMultipleCoilsRequest.py          |   4 +
 .../ModbusPDUWriteMultipleCoilsResponse.py         |   4 +
 ...odbusPDUWriteMultipleHoldingRegistersRequest.py |   4 +
 ...dbusPDUWriteMultipleHoldingRegistersResponse.py |   4 +
 .../readwrite/ModbusPDUWriteSingleCoilRequest.py   |   4 +
 .../readwrite/ModbusPDUWriteSingleCoilResponse.py  |   4 +
 .../ModbusPDUWriteSingleRegisterRequest.py         |   4 +
 .../ModbusPDUWriteSingleRegisterResponse.py        |   4 +
 .../protocols/modbus/readwrite/ModbusRtuADU.py     |   6 +
 .../protocols/modbus/readwrite/ModbusTcpADU.py     |   6 +
 .../{drivers => protocols/simulated}/__init__.py   |   0
 plc4py/plc4py/protocols/umas/StaticHelper.py       |  69 ++-
 .../plc4py/protocols/umas/readwrite/ModbusPDU.py   |   6 +
 .../protocols/umas/readwrite/ModbusPDUError.py     |   5 +
 .../umas/readwrite/UmasInitCommsRequest.py         |   5 +
 .../umas/readwrite/UmasInitCommsResponse.py        |   5 +
 .../protocols/umas/readwrite/UmasMemoryBlock.py    |   5 +
 .../umas/readwrite/UmasMemoryBlockBasicInfo.py     |   5 +
 plc4py/plc4py/protocols/umas/readwrite/UmasPDU.py  |   5 +
 .../plc4py/protocols/umas/readwrite/UmasPDUItem.py |   5 +
 .../umas/readwrite/UmasPDUPlcIdentRequest.py       |   5 +
 .../umas/readwrite/UmasPDUPlcIdentResponse.py      |   5 +
 .../umas/readwrite/UmasPDUPlcStatusRequest.py      |   5 +
 .../umas/readwrite/UmasPDUPlcStatusResponse.py     |   5 +
 .../umas/readwrite/UmasPDUProjectInfoRequest.py    |   5 +
 .../readwrite/UmasPDUReadMemoryBlockRequest.py     |   5 +
 .../readwrite/UmasPDUReadMemoryBlockResponse.py    |   5 +
 .../readwrite/UmasPDUReadUnlocatedVariableNames.py |  12 +-
 .../UmasPDUReadUnlocatedVariableNamesRequest.py    |   5 +
 .../UmasPDUReadUnlocatedVariableResponse.py        |   5 +
 .../umas/readwrite/UmasPDUReadVariableRequest.py   |   5 +
 .../umas/readwrite/UmasPDUReadVariableResponse.py  |   5 +
 .../umas/readwrite/UmasPDUWriteVariableRequest.py  |   5 +
 .../umas/readwrite/UmasPDUWriteVariableResponse.py |   5 +
 .../protocols/umas/readwrite/UmasVariableBlock.py  |  13 +-
 .../umas/readwrite/VariableRequestReference.py     |  15 +-
 plc4py/plc4py/spi/Plc4xBaseProtocol.py             |   2 +-
 plc4py/plc4py/spi/PlcDriverClassLoader.py          |  19 +-
 .../plc4py/spi/configuration/PlcConfiguration.py   |   2 +-
 plc4py/plc4py/spi/connection/ProtocolStack.py      |   4 +-
 plc4py/plc4py/spi/generation/ReadBuffer.py         |  45 +-
 plc4py/plc4py/spi/generation/WriteBuffer.py        | 546 +++++++++++----------
 plc4py/plc4py/spi/messages/PlcRequest.py           |   6 +-
 plc4py/plc4py/spi/transport/MockTransport.py       |  22 +-
 plc4py/plc4py/spi/transport/Plc4xBaseTransport.py  |   2 +-
 plc4py/plc4py/spi/transport/PlcTransportLoader.py  |  36 ++
 plc4py/plc4py/spi/transport/TCPTransport.py        |  20 +-
 plc4py/plc4py/spi/transport/__init__.py            |   4 +
 plc4py/plc4py/spi/values/Common.py                 |   8 +-
 plc4py/plc4py/spi/values/PlcValues.py              |   2 +-
 plc4py/setup.py                                    |   7 +-
 .../drivers/modbus/test_modbus_connection.py       |   2 +-
 .../modbus/test_modbus_parser_serializer.py        |  54 ++
 .../utils/ParserSerializerTestSuiteRunner.py       |  87 ++++
 .../tests/unit/plc4py/utils/XmlTestSuiteLoader.py  | 146 ++++++
 plc4py/tests/unit/plc4py/utils/__init__.py         |  16 +
 .../tests/unit/plc4py/utils/generated/__init__.py  |  16 +
 .../plc4py/utils/generated/driver_testsuite.py     | 447 +++++++++++++++++
 .../utils/generated/parser_serializer_testsuite.py | 188 +++++++
 114 files changed, 1962 insertions(+), 472 deletions(-)

diff --git a/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java b/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
index c66537bc40..bd2370721b 100644
--- a/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
+++ b/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
@@ -1658,9 +1658,9 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
         }
 
         // We need the getsizeof function from the sys module.
-        emitRequiredImport("from sys import getsizeof");
+        emitRequiredImport("from plc4py.spi.values.Common import get_size_of_array");
         // Cast the result to the correct type if necessary.
-        return tracer + getCastExpressionForTypeReference(typeReference) + "(getsizeof(" + sb + "))";
+        return tracer + getCastExpressionForTypeReference(typeReference) + "(get_size_of_array(" + sb + "))";
     }
 
     /**
diff --git a/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh b/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
index a98008359d..9cff1baffc 100644
--- a/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
+++ b/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
@@ -558,6 +558,21 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
         start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
         </#if>
+
+        <#if hasParserArguments>
+            <#list parserArguments as parserArgument>
+        if isinstance(${helper.camelCaseToSnakeCase(parserArgument.name)}, str):
+            <#if parserArgument.type.isEnumTypeReference()>
+            ${helper.camelCaseToSnakeCase(parserArgument.name)} = ${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)}[${helper.camelCaseToSnakeCase(parserArgument.name)}]
+            <#elseif helper.getLanguageTypeNameForTypeReference(parserArgument.type, false) = "bool">
+            <@emitImport import="from distutils.util import strtobool" />
+            ${helper.camelCaseToSnakeCase(parserArgument.name)} = bool(strtobool(${helper.camelCaseToSnakeCase(parserArgument.name)}))
+            <#else>
+            ${helper.camelCaseToSnakeCase(parserArgument.name)} = ${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)}(${helper.camelCaseToSnakeCase(parserArgument.name)})
+            </#if>
+            </#list>
+        </#if>
+
     <#assign reservedFieldIndex=0>
     <#list type.fields as field>
         <#switch field.typeName>
diff --git a/plc4py/plc4py/PlcDriverManager.py b/plc4py/plc4py/PlcDriverManager.py
index 9180c0fd3d..16f81c2538 100644
--- a/plc4py/plc4py/PlcDriverManager.py
+++ b/plc4py/plc4py/PlcDriverManager.py
@@ -20,19 +20,30 @@
 import logging
 from contextlib import asynccontextmanager
 from dataclasses import dataclass, field
-from typing import Type, AsyncIterator, List, Dict
+from typing import AsyncIterator, Dict, List, Type
+
 from pluggy import PluginManager  # type: ignore
 
 from plc4py.api.PlcConnection import PlcConnection
 from plc4py.api.PlcDriver import PlcDriver
 from plc4py.spi.PlcDriverClassLoader import PlcDriverClassLoader
 from plc4py.utils.ConnectionStringHandling import get_protocol_code
+from plc4py.spi.PlcDriverClassLoader import PlcTransportClassLoader
+from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
 
 
 @dataclass
 class PlcDriverManager:
-    class_loader: PluginManager = field(default_factory=lambda: PluginManager("plc4py"))
+    class_loader: PluginManager = field(
+        default_factory=lambda: PluginManager("plc4py.drivers")
+    )
+    transport_loader: PluginManager = field(
+        default_factory=lambda: PluginManager("plc4py.transports")
+    )
     _driver_map: Dict[str, Type[PlcDriver]] = field(default_factory=lambda: {})
+    _transport_map: Dict[str, Type[Plc4xBaseTransport]] = field(
+        default_factory=lambda: {}
+    )
 
     def __post_init__(self):
         """
@@ -68,7 +79,8 @@ class PlcDriverManager:
         self._driver_map = {
             key: loader
             for key, loader in zip(
-                self.class_loader.hook.key(), self.class_loader.hook.get_driver()
+                self.class_loader.hook.key(),
+                self.class_loader.hook.get_driver(),
             )
         }
 
@@ -79,6 +91,43 @@ class PlcDriverManager:
         # Check for any pending plugins
         self.class_loader.check_pending()
 
+        ######
+        # Log the class loader used
+        logging.info(
+            "Instantiating new PLC Transport Manager with class loader %s",
+            self.transport_loader,
+        )
+
+        # Add the PlcDriverClassLoader hookspecs to the class loader
+        self.transport_loader.add_hookspecs(PlcTransportClassLoader)
+
+        # Log the registration of drivers
+        logging.info("Registering available transports...")
+
+        # Register the plc4py.drivers package
+        import plc4py.spi.transport
+
+        self.transport_loader.register(plc4py.spi.transport)
+
+        # Load the setuptools entry points defined in the "plc4py.drivers" namespace
+        self.transport_loader.load_setuptools_entrypoints("plc4py.transports")
+
+        # Create a dictionary mapping the hook names to the PlcDriver instances
+        self._transport_map = {
+            key: loader
+            for key, loader in zip(
+                self.transport_loader.hook.key(),
+                self.transport_loader.hook.get_transport(),
+            )
+        }
+
+        # Log the successful registration of each driver
+        for transport in self._transport_map:
+            logging.info("... %s .. OK", transport)
+
+        # Check for any pending plugins
+        self.transport_loader.check_pending()
+
     @asynccontextmanager
     async def connection(self, url: str) -> AsyncIterator[PlcConnection]:
         """
diff --git a/plc4py/plc4py/__init__.py b/plc4py/plc4py/__init__.py
index edb4c5ab16..22eb734c9c 100644
--- a/plc4py/plc4py/__init__.py
+++ b/plc4py/plc4py/__init__.py
@@ -21,9 +21,5 @@ __version__ = "0.1.0"
 
 import logging
 
-import pluggy  # type: ignore
-
 # Place holder for logging configuration
 logging.basicConfig(level=logging.DEBUG)
-
-hookimpl = pluggy.HookimplMarker("plc4py")
diff --git a/plc4py/plc4py/api/PlcConnection.py b/plc4py/plc4py/api/PlcConnection.py
index db87c4a74d..6ea34f3e93 100644
--- a/plc4py/plc4py/api/PlcConnection.py
+++ b/plc4py/plc4py/api/PlcConnection.py
@@ -20,14 +20,14 @@ import asyncio
 from abc import abstractmethod
 from typing import Awaitable, Dict, Union
 
+from plc4py.api.messages.PlcRequest import PlcRequest, ReadRequestBuilder
 from plc4py.api.messages.PlcResponse import (
+    PlcBrowseResponse,
+    PlcReadResponse,
     PlcResponse,
     PlcTagResponse,
-    PlcReadResponse,
     PlcWriteResponse,
-    PlcBrowseResponse,
 )
-from plc4py.api.messages.PlcRequest import ReadRequestBuilder, PlcRequest
 from plc4py.api.value.PlcValue import PlcResponseCode, PlcValue
 from plc4py.spi.configuration.PlcConfiguration import PlcConfiguration
 from plc4py.spi.messages.utils.ResponseItem import ResponseItem
@@ -95,7 +95,6 @@ class PlcConnection(GenericGenerator):
 
 
 class PlcConnectionMetaData:
-
     @abstractmethod
     def is_read_supported(self) -> bool:
         """
diff --git a/plc4py/plc4py/api/PlcDriver.py b/plc4py/plc4py/api/PlcDriver.py
index 5b2802a328..9f0b374c0f 100644
--- a/plc4py/plc4py/api/PlcDriver.py
+++ b/plc4py/plc4py/api/PlcDriver.py
@@ -19,10 +19,10 @@
 from abc import abstractmethod
 from dataclasses import dataclass
 
-from plc4py.api.PlcConnection import PlcConnection
 from plc4py.api.authentication.PlcAuthentication import PlcAuthentication
 from plc4py.api.exceptions.exceptions import PlcNotImplementedException
 from plc4py.api.messages.PlcDiscovery import PlcDiscoveryRequestBuilder
+from plc4py.api.PlcConnection import PlcConnection
 
 
 @dataclass
diff --git a/plc4py/plc4py/api/messages/PlcRequest.py b/plc4py/plc4py/api/messages/PlcRequest.py
index 947cc31142..5a721d2c91 100644
--- a/plc4py/plc4py/api/messages/PlcRequest.py
+++ b/plc4py/plc4py/api/messages/PlcRequest.py
@@ -19,7 +19,7 @@
 from abc import abstractmethod
 from collections import OrderedDict
 from dataclasses import dataclass, field
-from typing import Union, List, Dict
+from typing import Dict, List, Union
 
 from plc4py.api.messages.PlcField import PlcTag
 from plc4py.api.messages.PlcMessage import PlcMessage
diff --git a/plc4py/plc4py/api/messages/PlcResponse.py b/plc4py/plc4py/api/messages/PlcResponse.py
index 33d726aa0a..807dba5d43 100644
--- a/plc4py/plc4py/api/messages/PlcResponse.py
+++ b/plc4py/plc4py/api/messages/PlcResponse.py
@@ -17,11 +17,11 @@
 # under the License.
 #
 from dataclasses import dataclass
-from typing import cast, List, Dict
+from typing import Dict, List, cast
 
 from plc4py.api.messages.PlcField import PlcTag
 from plc4py.api.messages.PlcMessage import PlcMessage
-from plc4py.api.value.PlcValue import PlcValue, PlcResponseCode
+from plc4py.api.value.PlcValue import PlcResponseCode, PlcValue
 from plc4py.spi.messages.utils.ResponseItem import ResponseItem
 
 
diff --git a/plc4py/plc4py/api/value/PlcValue.py b/plc4py/plc4py/api/value/PlcValue.py
index 6df4486dc0..972e689632 100644
--- a/plc4py/plc4py/api/value/PlcValue.py
+++ b/plc4py/plc4py/api/value/PlcValue.py
@@ -18,8 +18,8 @@
 #
 from abc import ABC
 from dataclasses import dataclass
-from enum import auto, Enum
-from typing import TypeVar, Generic, List
+from enum import Enum, auto
+from typing import Generic, List, TypeVar
 
 T = TypeVar("T")
 
diff --git a/plc4py/plc4py/drivers/__init__.py b/plc4py/plc4py/drivers/__init__.py
index 342be71799..e9877cb638 100644
--- a/plc4py/plc4py/drivers/__init__.py
+++ b/plc4py/plc4py/drivers/__init__.py
@@ -16,3 +16,7 @@
 # specific language governing permissions and limitations
 # under the License.
 #
+
+import pluggy  # type: ignore
+
+hookimpl = pluggy.HookimplMarker("plc4py.drivers")
diff --git a/plc4py/plc4py/drivers/mock/MockConnection.py b/plc4py/plc4py/drivers/mock/MockConnection.py
index 77a00437b8..b867b7fb8b 100644
--- a/plc4py/plc4py/drivers/mock/MockConnection.py
+++ b/plc4py/plc4py/drivers/mock/MockConnection.py
@@ -23,30 +23,29 @@ from dataclasses import dataclass, field
 from typing import Type, Union
 
 import plc4py
-from plc4py.api.PlcConnection import PlcConnection, PlcConnectionMetaData
-from plc4py.api.PlcDriver import PlcDriver
 from plc4py.api.authentication.PlcAuthentication import PlcAuthentication
 from plc4py.api.exceptions.exceptions import PlcFieldParseException
 from plc4py.api.messages.PlcRequest import (
-    ReadRequestBuilder,
     PlcReadRequest,
     PlcRequest,
+    ReadRequestBuilder,
 )
 from plc4py.api.messages.PlcResponse import (
     PlcReadResponse,
     PlcResponse,
 )
+from plc4py.api.PlcConnection import PlcConnection, PlcConnectionMetaData
+from plc4py.api.PlcDriver import PlcDriver
 from plc4py.api.value.PlcValue import PlcResponseCode
-from plc4py.drivers.PlcDriverLoader import PlcDriverLoader
 from plc4py.drivers.mock.MockTag import MockTagBuilder
+from plc4py.drivers.PlcDriverLoader import PlcDriverLoader
 from plc4py.spi.messages.PlcReader import DefaultPlcReader
 from plc4py.spi.messages.PlcRequest import DefaultReadRequestBuilder
 from plc4py.spi.messages.PlcWriter import DefaultPlcWriter
 from plc4py.spi.messages.utils.ResponseItem import ResponseItem
 from plc4py.spi.transport.MockTransport import MockTransport
 from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
-from plc4py.spi.values.PlcValues import PlcBOOL
-from plc4py.spi.values.PlcValues import PlcINT
+from plc4py.spi.values.PlcValues import PlcBOOL, PlcINT
 
 
 @dataclass
@@ -137,11 +136,11 @@ class MockDriverLoader(PlcDriverLoader):
     """
 
     @staticmethod
-    @plc4py.hookimpl
+    @plc4py.drivers.hookimpl
     def get_driver() -> Type[MockDriver]:
         return MockDriver
 
     @staticmethod
-    @plc4py.hookimpl
+    @plc4py.drivers.hookimpl
     def key() -> str:
         return "mock"
diff --git a/plc4py/plc4py/drivers/mock/MockReadRequestBuilder.py b/plc4py/plc4py/drivers/mock/MockReadRequestBuilder.py
index cb1cd08907..3fd5d7e1c9 100644
--- a/plc4py/plc4py/drivers/mock/MockReadRequestBuilder.py
+++ b/plc4py/plc4py/drivers/mock/MockReadRequestBuilder.py
@@ -18,13 +18,13 @@
 #
 
 from dataclasses import dataclass, field
-from typing import Union, List, Dict
+from typing import Dict, List, Union
 
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.api.messages.PlcRequest import (
-    ReadRequestBuilder,
-    PlcTag,
     PlcReadRequest,
+    PlcTag,
+    ReadRequestBuilder,
 )
 from plc4py.api.messages.PlcResponse import PlcReadResponse
 
diff --git a/plc4py/plc4py/drivers/modbus/ModbusConnection.py b/plc4py/plc4py/drivers/modbus/ModbusConnection.py
index 0a2a01baeb..81656baa75 100644
--- a/plc4py/plc4py/drivers/modbus/ModbusConnection.py
+++ b/plc4py/plc4py/drivers/modbus/ModbusConnection.py
@@ -20,24 +20,24 @@ import asyncio
 from typing import Type
 
 import plc4py
-from plc4py.api.PlcConnection import PlcConnection, PlcConnectionMetaData
-from plc4py.api.PlcDriver import PlcDriver
 from plc4py.api.authentication.PlcAuthentication import PlcAuthentication
 from plc4py.api.messages.PlcRequest import (
-    ReadRequestBuilder,
-    PlcRequest,
     PlcReadRequest,
+    PlcRequest,
     PlcWriteRequest,
+    ReadRequestBuilder,
 )
 from plc4py.api.messages.PlcResponse import (
     PlcResponse,
 )
+from plc4py.api.PlcConnection import PlcConnection, PlcConnectionMetaData
+from plc4py.api.PlcDriver import PlcDriver
 from plc4py.api.value.PlcValue import PlcResponseCode
-from plc4py.drivers.PlcDriverLoader import PlcDriverLoader
 from plc4py.drivers.modbus.ModbusConfiguration import ModbusConfiguration
 from plc4py.drivers.modbus.ModbusDevice import ModbusDevice
 from plc4py.drivers.modbus.ModbusProtocol import ModbusProtocol
 from plc4py.drivers.modbus.ModbusTag import ModbusTagBuilder
+from plc4py.drivers.PlcDriverLoader import PlcDriverLoader
 from plc4py.spi.messages.PlcReader import DefaultPlcReader
 from plc4py.spi.messages.PlcRequest import DefaultReadRequestBuilder
 from plc4py.spi.messages.PlcWriter import DefaultPlcWriter
@@ -175,7 +175,7 @@ class ModbusDriverLoader(PlcDriverLoader):
     """
 
     @staticmethod
-    @plc4py.hookimpl
+    @plc4py.drivers.hookimpl
     def get_driver() -> Type[ModbusDriver]:
         """
         Returns the ModbusDriver class used to instantiate Modbus plc drivers.
@@ -187,7 +187,7 @@ class ModbusDriverLoader(PlcDriverLoader):
         return ModbusDriver
 
     @staticmethod
-    @plc4py.hookimpl
+    @plc4py.drivers.hookimpl
     def key() -> str:
         """
         Returns the unique key for the Modbus driver.
diff --git a/plc4py/plc4py/drivers/modbus/ModbusDevice.py b/plc4py/plc4py/drivers/modbus/ModbusDevice.py
index dedda15406..08b9e7a8e8 100644
--- a/plc4py/plc4py/drivers/modbus/ModbusDevice.py
+++ b/plc4py/plc4py/drivers/modbus/ModbusDevice.py
@@ -24,40 +24,37 @@ from typing import Dict, List
 
 from bitarray import bitarray
 
-from plc4py.protocols.modbus.readwrite.DataItem import DataItem
-from plc4py.protocols.modbus.readwrite.ModbusPDUError import ModbusPDUError
-from plc4py.spi.generation.ReadBuffer import ReadBuffer, ReadBufferByteBased
-
+from plc4py.api.exceptions.exceptions import PlcRuntimeException
+from plc4py.api.messages.PlcRequest import PlcReadRequest, PlcWriteRequest
+from plc4py.api.messages.PlcResponse import PlcReadResponse, PlcWriteResponse
+from plc4py.api.value.PlcValue import PlcResponseCode, PlcValue
+from plc4py.drivers.modbus.ModbusConfiguration import ModbusConfiguration
 from plc4py.drivers.modbus.ModbusTag import (
-    ModbusTagHoldingRegister,
     ModbusTagCoil,
     ModbusTagDiscreteInput,
+    ModbusTagHoldingRegister,
     ModbusTagInputRegister,
 )
-
-from plc4py.api.exceptions.exceptions import PlcRuntimeException
-from plc4py.drivers.modbus.ModbusConfiguration import ModbusConfiguration
+from plc4py.protocols.modbus.readwrite.DataItem import DataItem
+from plc4py.protocols.modbus.readwrite.ModbusPDUError import ModbusPDUError
 from plc4py.protocols.modbus.readwrite.ModbusPDUReadCoilsRequest import (
     ModbusPDUReadCoilsRequest,
 )
 from plc4py.protocols.modbus.readwrite.ModbusPDUReadDiscreteInputsRequest import (
     ModbusPDUReadDiscreteInputsRequest,
 )
-from plc4py.protocols.modbus.readwrite.ModbusPDUReadInputRegistersRequest import (
-    ModbusPDUReadInputRegistersRequest,
-)
-from plc4py.spi.generation.WriteBuffer import WriteBufferByteBased
-
-from plc4py.api.messages.PlcRequest import PlcReadRequest, PlcWriteRequest
-from plc4py.api.messages.PlcResponse import PlcReadResponse, PlcWriteResponse
-from plc4py.api.value.PlcValue import PlcValue, PlcResponseCode
 from plc4py.protocols.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest import (
     ModbusPDUReadHoldingRegistersRequest,
 )
+from plc4py.protocols.modbus.readwrite.ModbusPDUReadInputRegistersRequest import (
+    ModbusPDUReadInputRegistersRequest,
+)
 from plc4py.protocols.modbus.readwrite.ModbusTcpADU import ModbusTcpADU
+from plc4py.spi.generation.ReadBuffer import ReadBuffer, ReadBufferByteBased
+from plc4py.spi.generation.WriteBuffer import WriteBufferByteBased
 from plc4py.spi.messages.utils.ResponseItem import ResponseItem
 from plc4py.spi.values.PlcValues import PlcList, PlcNull
-from plc4py.utils.GenericTypes import ByteOrder, AtomicInteger
+from plc4py.utils.GenericTypes import AtomicInteger, ByteOrder
 
 
 @dataclass
diff --git a/plc4py/plc4py/drivers/modbus/ModbusProtocol.py b/plc4py/plc4py/drivers/modbus/ModbusProtocol.py
index f3ae557611..ea1e976326 100644
--- a/plc4py/plc4py/drivers/modbus/ModbusProtocol.py
+++ b/plc4py/plc4py/drivers/modbus/ModbusProtocol.py
@@ -19,12 +19,11 @@
 import logging
 from asyncio import Future
 from dataclasses import dataclass, field
-from typing import Dict, Awaitable
+from typing import Awaitable, Dict
 
 from plc4py.protocols.modbus.readwrite.DriverType import DriverType
-from plc4py.spi.generation.ReadBuffer import ReadBufferByteBased
-
 from plc4py.protocols.modbus.readwrite.ModbusTcpADU import ModbusTcpADU
+from plc4py.spi.generation.ReadBuffer import ReadBufferByteBased
 from plc4py.spi.Plc4xBaseProtocol import Plc4xBaseProtocol
 from plc4py.utils.GenericTypes import ByteOrder
 
diff --git a/plc4py/plc4py/drivers/umas/UmasConnection.py b/plc4py/plc4py/drivers/umas/UmasConnection.py
index 5183151011..5fb02fe914 100644
--- a/plc4py/plc4py/drivers/umas/UmasConnection.py
+++ b/plc4py/plc4py/drivers/umas/UmasConnection.py
@@ -18,23 +18,23 @@
 #
 import asyncio
 import logging
-from typing import Type, Awaitable
+from typing import Awaitable, Type
 
 import plc4py
-from plc4py.api.PlcConnection import PlcConnection, PlcConnectionMetaData
-from plc4py.api.PlcDriver import PlcDriver
 from plc4py.api.authentication.PlcAuthentication import PlcAuthentication
 from plc4py.api.exceptions.exceptions import PlcConnectionException
 from plc4py.api.messages.PlcRequest import (
-    ReadRequestBuilder,
-    PlcRequest,
-    PlcReadRequest,
     BrowseRequestBuilder,
     PlcBrowseRequest,
+    PlcReadRequest,
+    PlcRequest,
+    ReadRequestBuilder,
 )
 from plc4py.api.messages.PlcResponse import (
     PlcResponse,
 )
+from plc4py.api.PlcConnection import PlcConnection, PlcConnectionMetaData
+from plc4py.api.PlcDriver import PlcDriver
 from plc4py.api.value.PlcValue import PlcResponseCode
 from plc4py.drivers.PlcDriverLoader import PlcDriverLoader
 from plc4py.drivers.umas.UmasConfiguration import UmasConfiguration
@@ -44,8 +44,8 @@ from plc4py.drivers.umas.UmasTag import UmasTagBuilder
 from plc4py.spi.messages.PlcBrowser import DefaultPlcBrowser
 from plc4py.spi.messages.PlcReader import DefaultPlcReader
 from plc4py.spi.messages.PlcRequest import (
-    DefaultReadRequestBuilder,
     DefaultBrowseRequestBuilder,
+    DefaultReadRequestBuilder,
 )
 from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
 from plc4py.spi.transport.TCPTransport import TCPTransport
@@ -104,7 +104,8 @@ class UmasConnection(PlcConnection, DefaultPlcReader, DefaultPlcBrowser):
             )
         except TimeoutError as e:
             raise PlcConnectionException(
-                f"Time out while opening UMAS connection to device - {config.host}", e
+                f"Time out while opening UMAS connection to device - {config.host}",
+                e,
             )
         return connection
 
@@ -162,11 +163,11 @@ class UmasDriverLoader(PlcDriverLoader):
     """
 
     @staticmethod
-    @plc4py.hookimpl
+    @plc4py.drivers.hookimpl
     def get_driver() -> Type[UmasDriver]:
         return UmasDriver
 
     @staticmethod
-    @plc4py.hookimpl
+    @plc4py.drivers.hookimpl
     def key() -> str:
         return "umas"
diff --git a/plc4py/plc4py/drivers/umas/UmasDevice.py b/plc4py/plc4py/drivers/umas/UmasDevice.py
index 0adc3210e1..5e8d5c710c 100644
--- a/plc4py/plc4py/drivers/umas/UmasDevice.py
+++ b/plc4py/plc4py/drivers/umas/UmasDevice.py
@@ -17,34 +17,40 @@
 # under the License.
 #
 import asyncio
-from asyncio import Transport, AbstractEventLoop
+from asyncio import AbstractEventLoop, Transport
 from dataclasses import dataclass, field
 from typing import Dict, List, Tuple, cast
 
-from plc4py.protocols.umas.readwrite.UmasUDTDefinition import UmasUDTDefinition
-
 from plc4py.api.messages.PlcRequest import (
-    PlcReadRequest,
     PlcBrowseRequest,
+    PlcReadRequest,
     PlcWriteRequest,
 )
 from plc4py.api.messages.PlcResponse import (
-    PlcReadResponse,
     PlcBrowseResponse,
+    PlcReadResponse,
     PlcWriteResponse,
 )
-from plc4py.api.value.PlcValue import PlcValue, PlcResponseCode
+from plc4py.api.value.PlcValue import PlcResponseCode, PlcValue
 from plc4py.drivers.umas.UmasConfiguration import UmasConfiguration
 from plc4py.drivers.umas.UmasTag import UmasTag
 from plc4py.drivers.umas.UmasVariables import UmasVariable, UmasVariableBuilder
-from plc4py.protocols.umas.readwrite import UmasPDUReadUnlocatedVariableResponse
+from plc4py.protocols.umas.readwrite import (
+    UmasPDUReadUnlocatedVariableResponse,
+)
 from plc4py.protocols.umas.readwrite.DataItem import DataItem
-from plc4py.protocols.umas.readwrite.PlcMemoryBlockIdent import PlcMemoryBlockIdent
-from plc4py.protocols.umas.readwrite.UmasDatatypeReference import UmasDatatypeReference
+from plc4py.protocols.umas.readwrite.PlcMemoryBlockIdent import (
+    PlcMemoryBlockIdent,
+)
+from plc4py.protocols.umas.readwrite.UmasDatatypeReference import (
+    UmasDatatypeReference,
+)
 from plc4py.protocols.umas.readwrite.UmasInitCommsRequest import (
     UmasInitCommsRequestBuilder,
 )
-from plc4py.protocols.umas.readwrite.UmasInitCommsResponse import UmasInitCommsResponse
+from plc4py.protocols.umas.readwrite.UmasInitCommsResponse import (
+    UmasInitCommsResponse,
+)
 from plc4py.protocols.umas.readwrite.UmasMemoryBlockBasicInfo import (
     UmasMemoryBlockBasicInfo,
 )
@@ -84,6 +90,7 @@ from plc4py.protocols.umas.readwrite.UmasPDUReadVariableRequest import (
 from plc4py.protocols.umas.readwrite.UmasPDUReadVariableResponse import (
     UmasPDUReadVariableResponse,
 )
+from plc4py.protocols.umas.readwrite.UmasUDTDefinition import UmasUDTDefinition
 from plc4py.protocols.umas.readwrite.UmasUnlocatedVariableReference import (
     UmasUnlocatedVariableReference,
 )
@@ -127,7 +134,10 @@ class UmasDevice:
         data_types: List[UmasDatatypeReference] = {}
         while offset != 0x0000 or first_message:
             first_message = False
-            offset, data_types = await self._send_unlocated_variable_datatype_request(
+            (
+                offset,
+                data_types,
+            ) = await self._send_unlocated_variable_datatype_request(
                 transport, loop, offset
             )
         data_type_children: Dict[str, List[UmasUDTDefinition]] = {}
@@ -248,7 +258,10 @@ class UmasDevice:
         self.index = basic_info.index
 
     async def _send_unlocated_variable_datatype_request(
-        self, transport: Transport, loop: AbstractEventLoop, offset: int = 0x0000
+        self,
+        transport: Transport,
+        loop: AbstractEventLoop,
+        offset: int = 0x0000,
     ):
         message_future = loop.create_future()
 
@@ -312,7 +325,10 @@ class UmasDevice:
         return basic_info.records
 
     async def _send_unlocated_variable_request(
-        self, transport: Transport, loop: AbstractEventLoop, offset: int = 0x0000
+        self,
+        transport: Transport,
+        loop: AbstractEventLoop,
+        offset: int = 0x0000,
     ):
         message_future = loop.create_future()
 
@@ -347,7 +363,11 @@ class UmasDevice:
         return variable_list.next_address, tags
 
     async def _send_read_variable_request(
-        self, transport: Transport, loop: AbstractEventLoop, request, sorted_tags
+        self,
+        transport: Transport,
+        loop: AbstractEventLoop,
+        request,
+        sorted_tags,
     ):
         message_future = loop.create_future()
 
diff --git a/plc4py/plc4py/drivers/umas/UmasProtocol.py b/plc4py/plc4py/drivers/umas/UmasProtocol.py
index b3c7cca3d5..a9912f8b44 100644
--- a/plc4py/plc4py/drivers/umas/UmasProtocol.py
+++ b/plc4py/plc4py/drivers/umas/UmasProtocol.py
@@ -19,18 +19,16 @@
 import logging
 from asyncio import Future
 from dataclasses import dataclass, field
-from typing import Dict, Awaitable, Tuple
+from typing import Awaitable, Dict, Tuple
 
 from plc4py.protocols.umas.readwrite.ModbusPDU import ModbusPDU
-from plc4py.protocols.umas.readwrite.UmasPDU import UmasPDUBuilder, UmasPDU
+from plc4py.protocols.umas.readwrite.ModbusTcpADU import ModbusTcpADU
+from plc4py.protocols.umas.readwrite.UmasPDU import UmasPDU, UmasPDUBuilder
 from plc4py.protocols.umas.readwrite.UmasPDUItem import UmasPDUItem
-from plc4py.spi.generation.WriteBuffer import WriteBufferByteBased
-
 from plc4py.spi.generation.ReadBuffer import ReadBufferByteBased
-
-from plc4py.protocols.umas.readwrite.ModbusTcpADU import ModbusTcpADU
+from plc4py.spi.generation.WriteBuffer import WriteBufferByteBased
 from plc4py.spi.Plc4xBaseProtocol import Plc4xBaseProtocol
-from plc4py.utils.GenericTypes import ByteOrder, AtomicInteger
+from plc4py.utils.GenericTypes import AtomicInteger, ByteOrder
 
 
 @dataclass
diff --git a/plc4py/plc4py/drivers/umas/UmasTag.py b/plc4py/plc4py/drivers/umas/UmasTag.py
index c1db37831c..480a41dc85 100644
--- a/plc4py/plc4py/drivers/umas/UmasTag.py
+++ b/plc4py/plc4py/drivers/umas/UmasTag.py
@@ -20,10 +20,9 @@ import re
 from typing import AnyStr, Pattern
 
 from plc4py.api.exceptions.exceptions import PlcFieldParseException
-from plc4py.spi.messages.PlcRequest import TagBuilder
-
 from plc4py.api.messages.PlcField import PlcTag
 from plc4py.protocols.umas.readwrite.UmasDataType import UmasDataType
+from plc4py.spi.messages.PlcRequest import TagBuilder
 
 
 class UmasTag(PlcTag):
diff --git a/plc4py/plc4py/drivers/umas/UmasVariables.py b/plc4py/plc4py/drivers/umas/UmasVariables.py
index 27b90c0d6b..265efc6b49 100644
--- a/plc4py/plc4py/drivers/umas/UmasVariables.py
+++ b/plc4py/plc4py/drivers/umas/UmasVariables.py
@@ -18,21 +18,20 @@
 #
 import re
 from dataclasses import dataclass
-from typing import Dict, List, Pattern, AnyStr, Union
+from typing import AnyStr, Dict, List, Pattern, Union
 
+from plc4py.api.exceptions.exceptions import PlcDataTypeNotFoundException
 from plc4py.protocols.umas.readwrite.UmasDataType import UmasDataType
-
-from plc4py.protocols.umas.readwrite.VariableReadRequestReference import (
-    VariableReadRequestReference,
+from plc4py.protocols.umas.readwrite.UmasDatatypeReference import (
+    UmasDatatypeReference,
 )
-
-from plc4py.api.exceptions.exceptions import PlcDataTypeNotFoundException
-from plc4py.protocols.umas.readwrite.UmasDatatypeReference import UmasDatatypeReference
 from plc4py.protocols.umas.readwrite.UmasUDTDefinition import UmasUDTDefinition
-
 from plc4py.protocols.umas.readwrite.UmasUnlocatedVariableReference import (
     UmasUnlocatedVariableReference,
 )
+from plc4py.protocols.umas.readwrite.VariableReadRequestReference import (
+    VariableReadRequestReference,
+)
 
 
 @dataclass
diff --git a/plc4py/plc4py/protocols/modbus/StaticHelper.py b/plc4py/plc4py/protocols/modbus/StaticHelper.py
index 386dd2e6bd..835e2b20ff 100644
--- a/plc4py/plc4py/protocols/modbus/StaticHelper.py
+++ b/plc4py/plc4py/protocols/modbus/StaticHelper.py
@@ -20,43 +20,43 @@ from plc4py.spi.generation.WriteBuffer import WriteBufferByteBased
 from plc4py.utils.GenericTypes import ByteOrder
 
 auch_crc_hi: bytearray = bytearray(
-    b"\x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81 \
-        \x40\x01\xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0 \
-        \x80\x41\x01\xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01 \
-        \xC0\x80\x41\x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0\x80\x41 \
-        \x00\xC1\x81\x40\x01\xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81 \
-        \x40\x01\xC0\x80\x41\x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0 \
-        \x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0\x80\x41\x01 \
-        \xC0\x80\x41\x00\xC1\x81\x40\x01\xC0\x80\x41\x00\xC1\x81\x40 \
-        \x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81 \
-        \x40\x00\xC1\x81\x40\x01\xC0\x80\x41\x00\xC1\x81\x40\x01\xC0 \
-        \x80\x41\x01\xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01 \
-        \xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81\x40\x01\xC0\x80\x41 \
-        \x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0\x80\x41\x00\xC1\x81 \
-        \x40\x01\xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81\x40\x01\xC0 \
-        \x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0\x80\x41\x01 \
-        \xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0\x80\x41 \
-        \x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81 \
+    b"\x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81 \
+        \x40\x01\xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0 \
+        \x80\x41\x01\xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01 \
+        \xc0\x80\x41\x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0\x80\x41 \
+        \x00\xc1\x81\x40\x01\xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81 \
+        \x40\x01\xc0\x80\x41\x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0 \
+        \x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0\x80\x41\x01 \
+        \xc0\x80\x41\x00\xc1\x81\x40\x01\xc0\x80\x41\x00\xc1\x81\x40 \
+        \x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81 \
+        \x40\x00\xc1\x81\x40\x01\xc0\x80\x41\x00\xc1\x81\x40\x01\xc0 \
+        \x80\x41\x01\xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01 \
+        \xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81\x40\x01\xc0\x80\x41 \
+        \x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0\x80\x41\x00\xc1\x81 \
+        \x40\x01\xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81\x40\x01\xc0 \
+        \x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0\x80\x41\x01 \
+        \xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0\x80\x41 \
+        \x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81 \
         \x40"
 )
 
 auch_crc_lo: bytearray = bytearray(
-    b"\x00\xC0\xC1\x01\xC3\x03\x02\xC2\xC6\x06\x07\xC7\x05\xC5\xC4 \
-        \x04\xCC\x0C\x0D\xCD\x0F\xCF\xCE\x0E\x0A\xCA\xCB\x0B\xC9\x09 \
-        \x08\xC8\xD8\x18\x19\xD9\x1B\xDB\xDA\x1A\x1E\xDE\xDF\x1F\xDD \
-        \x1D\x1C\xDC\x14\xD4\xD5\x15\xD7\x17\x16\xD6\xD2\x12\x13\xD3 \
-        \x11\xD1\xD0\x10\xF0\x30\x31\xF1\x33\xF3\xF2\x32\x36\xF6\xF7 \
-        \x37\xF5\x35\x34\xF4\x3C\xFC\xFD\x3D\xFF\x3F\x3E\xFE\xFA\x3A \
-        \x3B\xFB\x39\xF9\xF8\x38\x28\xE8\xE9\x29\xEB\x2B\x2A\xEA\xEE \
-        \x2E\x2F\xEF\x2D\xED\xEC\x2C\xE4\x24\x25\xE5\x27\xE7\xE6\x26 \
-        \x22\xE2\xE3\x23\xE1\x21\x20\xE0\xA0\x60\x61\xA1\x63\xA3\xA2 \
-        \x62\x66\xA6\xA7\x67\xA5\x65\x64\xA4\x6C\xAC\xAD\x6D\xAF\x6F \
-        \x6E\xAE\xAA\x6A\x6B\xAB\x69\xA9\xA8\x68\x78\xB8\xB9\x79\xBB \
-        \x7B\x7A\xBA\xBE\x7E\x7F\xBF\x7D\xBD\xBC\x7C\xB4\x74\x75\xB5 \
-        \x77\xB7\xB6\x76\x72\xB2\xB3\x73\xB1\x71\x70\xB0\x50\x90\x91 \
-        \x51\x93\x53\x52\x92\x96\x56\x57\x97\x55\x95\x94\x54\x9C\x5C \
-        \x5D\x9D\x5F\x9F\x9E\x5E\x5A\x9A\x9B\x5B\x99\x59\x58\x98\x88 \
-        \x48\x49\x89\x4B\x8B\x8A\x4A\x4E\x8E\x8F\x4F\x8D\x4D\x4C\x8C \
+    b"\x00\xc0\xc1\x01\xc3\x03\x02\xc2\xc6\x06\x07\xc7\x05\xc5\xc4 \
+        \x04\xcc\x0c\x0d\xcd\x0f\xcf\xce\x0e\x0a\xca\xcb\x0b\xc9\x09 \
+        \x08\xc8\xd8\x18\x19\xd9\x1b\xdb\xda\x1a\x1e\xde\xdf\x1f\xdd \
+        \x1d\x1c\xdc\x14\xd4\xd5\x15\xd7\x17\x16\xd6\xd2\x12\x13\xd3 \
+        \x11\xd1\xd0\x10\xf0\x30\x31\xf1\x33\xf3\xf2\x32\x36\xf6\xf7 \
+        \x37\xf5\x35\x34\xf4\x3c\xfc\xfd\x3d\xff\x3f\x3e\xfe\xfa\x3a \
+        \x3b\xfb\x39\xf9\xf8\x38\x28\xe8\xe9\x29\xeb\x2b\x2a\xea\xee \
+        \x2e\x2f\xef\x2d\xed\xec\x2c\xe4\x24\x25\xe5\x27\xe7\xe6\x26 \
+        \x22\xe2\xe3\x23\xe1\x21\x20\xe0\xa0\x60\x61\xa1\x63\xa3\xa2 \
+        \x62\x66\xa6\xa7\x67\xa5\x65\x64\xa4\x6c\xac\xad\x6d\xaf\x6f \
+        \x6e\xae\xaa\x6a\x6b\xab\x69\xa9\xa8\x68\x78\xb8\xb9\x79\xbb \
+        \x7b\x7a\xba\xbe\x7e\x7f\xbf\x7d\xbd\xbc\x7c\xb4\x74\x75\xb5 \
+        \x77\xb7\xb6\x76\x72\xb2\xb3\x73\xb1\x71\x70\xb0\x50\x90\x91 \
+        \x51\x93\x53\x52\x92\x96\x56\x57\x97\x55\x95\x94\x54\x9c\x5c \
+        \x5d\x9d\x5f\x9f\x9e\x5e\x5a\x9a\x9b\x5b\x99\x59\x58\x98\x88 \
+        \x48\x49\x89\x4b\x8b\x8a\x4a\x4e\x8e\x8f\x4f\x8d\x4d\x4c\x8c \
         \x44\x84\x85\x45\x87\x47\x46\x86\x82\x42\x43\x83\x41\x81\x80 \
         \x40"
 )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusADU.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusADU.py
index 9dcc6617b3..573c097d9c 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusADU.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusADU.py
@@ -21,6 +21,7 @@ from dataclasses import dataclass
 
 from abc import ABC
 from abc import abstractmethod
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import ParseException
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
@@ -102,6 +103,11 @@ class ModbusADU(ABC, PlcMessage):
     ):
         read_buffer.push_context("ModbusADU")
 
+        if isinstance(driver_type, str):
+            driver_type = DriverType[driver_type]
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         # Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
         builder: ModbusADUBuilder = None
         from plc4py.protocols.modbus.readwrite.ModbusTcpADU import ModbusTcpADU
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusAsciiADU.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusAsciiADU.py
index d3d2bf62c5..855549d401 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusAsciiADU.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusAsciiADU.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -84,6 +85,11 @@ class ModbusAsciiADU(ModbusADU):
     ):
         read_buffer.push_context("ModbusAsciiADU")
 
+        if isinstance(driver_type, str):
+            driver_type = DriverType[driver_type]
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         address: int = read_buffer.read_unsigned_byte(
             logical_name="address",
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDU.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDU.py
index 8b13c367e1..f9d904881f 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDU.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDU.py
@@ -21,6 +21,7 @@ from dataclasses import dataclass
 
 from abc import ABC
 from abc import abstractmethod
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import ParseException
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
@@ -107,6 +108,10 @@ class ModbusPDU(ABC, PlcMessage):
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDU")
+
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         error_flag: bool = read_buffer.read_bit(
             logical_name="error_flag", bit_length=1, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticRequest.py
index 7352d366ea..3015f728ea 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -70,6 +71,9 @@ class ModbusPDUDiagnosticRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUDiagnosticRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         sub_function: int = read_buffer.read_unsigned_short(
             logical_name="sub_function", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticResponse.py
index 23356067e2..cec882ff00 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -70,6 +71,9 @@ class ModbusPDUDiagnosticResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUDiagnosticResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         sub_function: int = read_buffer.read_unsigned_short(
             logical_name="sub_function", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUError.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUError.py
index 6931affc51..db1c6b8e81 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUError.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUError.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -64,6 +65,9 @@ class ModbusPDUError(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUError")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         exception_code: ModbusErrorCode = read_buffer.read_enum(
             read_function=ModbusErrorCode,
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterRequest.py
index af9594f09a..013e4fec3f 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -54,6 +55,9 @@ class ModbusPDUGetComEventCounterRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUGetComEventCounterRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         read_buffer.pop_context("ModbusPDUGetComEventCounterRequest")
         # Create the instance
         return ModbusPDUGetComEventCounterRequestBuilder()
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterResponse.py
index 81532a092c..04e11662f5 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUGetComEventCounterResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUGetComEventCounterResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         status: int = read_buffer.read_unsigned_short(
             logical_name="status", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogRequest.py
index 29fdeb2c36..e185d9a61f 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -54,6 +55,9 @@ class ModbusPDUGetComEventLogRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUGetComEventLogRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         read_buffer.pop_context("ModbusPDUGetComEventLogRequest")
         # Create the instance
         return ModbusPDUGetComEventLogRequestBuilder()
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogResponse.py
index a2e702c7d5..47be82ad93 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -98,6 +99,9 @@ class ModbusPDUGetComEventLogResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUGetComEventLogResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.py
index ac2317b491..74d37ddf1b 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -81,6 +82,9 @@ class ModbusPDUMaskWriteHoldingRegisterRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUMaskWriteHoldingRegisterRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         reference_address: int = read_buffer.read_unsigned_short(
             logical_name="reference_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.py
index 63c81c991c..6c927cc936 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -81,6 +82,9 @@ class ModbusPDUMaskWriteHoldingRegisterResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUMaskWriteHoldingRegisterResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         reference_address: int = read_buffer.read_unsigned_short(
             logical_name="reference_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsRequest.py
index 57f0ca2fca..0ca0b2c92a 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUReadCoilsRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadCoilsRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         starting_address: int = read_buffer.read_unsigned_short(
             logical_name="starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsResponse.py
index cd6a64fa78..2f08efdc1a 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -71,6 +72,9 @@ class ModbusPDUReadCoilsResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadCoilsResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.py
index 2bc888bc5b..ff2838f131 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -80,6 +81,9 @@ class ModbusPDUReadDeviceIdentificationRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadDeviceIdentificationRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         MEI_TYPE: int = read_buffer.read_unsigned_byte(
             logical_name="mei_type", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.py
index baf68e4199..5b14e8da36 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -134,6 +135,9 @@ class ModbusPDUReadDeviceIdentificationResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadDeviceIdentificationResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         MEI_TYPE: int = read_buffer.read_unsigned_byte(
             logical_name="mei_type", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.py
index 72d1fe455c..d4b0be0067 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUReadDiscreteInputsRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadDiscreteInputsRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         starting_address: int = read_buffer.read_unsigned_short(
             logical_name="starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.py
index 9f7a18d4a2..530fdea951 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -71,6 +72,9 @@ class ModbusPDUReadDiscreteInputsResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadDiscreteInputsResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.py
index b393b3746a..e209eb7095 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -54,6 +55,9 @@ class ModbusPDUReadExceptionStatusRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadExceptionStatusRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         read_buffer.pop_context("ModbusPDUReadExceptionStatusRequest")
         # Create the instance
         return ModbusPDUReadExceptionStatusRequestBuilder()
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.py
index 00429e123f..9a4e0aaaca 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -61,6 +62,9 @@ class ModbusPDUReadExceptionStatusResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadExceptionStatusResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         value: int = read_buffer.read_unsigned_byte(
             logical_name="value", bit_length=8, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueRequest.py
index dda62ad814..5731478e4b 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -63,6 +64,9 @@ class ModbusPDUReadFifoQueueRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadFifoQueueRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         fifo_pointer_address: int = read_buffer.read_unsigned_short(
             logical_name="fifo_pointer_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueResponse.py
index 9804bd3d25..52d49ecf63 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -82,6 +83,9 @@ class ModbusPDUReadFifoQueueResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadFifoQueueResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_short(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequest.py
index 0ca6b3409b..9e017d50bf 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -28,7 +29,7 @@ from plc4py.protocols.modbus.readwrite.ModbusPDUReadFileRecordRequestItem import
 )
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
-from sys import getsizeof
+from plc4py.spi.values.Common import get_size_of_array
 from typing import Any
 from typing import ClassVar
 from typing import List
@@ -47,7 +48,7 @@ class ModbusPDUReadFileRecordRequest(ModbusPDU):
         write_buffer.push_context("ModbusPDUReadFileRecordRequest")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: int = int(getsizeof(self.items))
+        byte_count: int = int(get_size_of_array(self.items))
         write_buffer.write_unsigned_byte(byte_count, logical_name="byte_count")
 
         # Array Field (items)
@@ -76,6 +77,9 @@ class ModbusPDUReadFileRecordRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadFileRecordRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponse.py
index 0d72de17a5..1b5f16b572 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -28,7 +29,7 @@ from plc4py.protocols.modbus.readwrite.ModbusPDUReadFileRecordResponseItem impor
 )
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
-from sys import getsizeof
+from plc4py.spi.values.Common import get_size_of_array
 from typing import Any
 from typing import ClassVar
 from typing import List
@@ -47,7 +48,7 @@ class ModbusPDUReadFileRecordResponse(ModbusPDU):
         write_buffer.push_context("ModbusPDUReadFileRecordResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: int = int(getsizeof(self.items))
+        byte_count: int = int(get_size_of_array(self.items))
         write_buffer.write_unsigned_byte(byte_count, logical_name="byte_count")
 
         # Array Field (items)
@@ -76,6 +77,9 @@ class ModbusPDUReadFileRecordResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadFileRecordResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.py
index 11730c441f..59ffd92603 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUReadHoldingRegistersRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadHoldingRegistersRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         starting_address: int = read_buffer.read_unsigned_short(
             logical_name="starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.py
index cd0b1eada0..f65ccf8597 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -71,6 +72,9 @@ class ModbusPDUReadHoldingRegistersResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadHoldingRegistersResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersRequest.py
index 92cec0d5ab..2e413e60bf 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUReadInputRegistersRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadInputRegistersRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         starting_address: int = read_buffer.read_unsigned_short(
             logical_name="starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersResponse.py
index 83a608c5fd..1839af2c49 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -71,6 +72,9 @@ class ModbusPDUReadInputRegistersResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadInputRegistersResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.py
index ea162927d8..83eec3b696 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -111,6 +112,9 @@ class ModbusPDUReadWriteMultipleHoldingRegistersRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadWriteMultipleHoldingRegistersRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         read_starting_address: int = read_buffer.read_unsigned_short(
             logical_name="read_starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.py
index c368ba85e5..d6bc4a1202 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -71,6 +72,9 @@ class ModbusPDUReadWriteMultipleHoldingRegistersResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReadWriteMultipleHoldingRegistersResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdRequest.py
index 5e47469d28..5488fff510 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -54,6 +55,9 @@ class ModbusPDUReportServerIdRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReportServerIdRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         read_buffer.pop_context("ModbusPDUReportServerIdRequest")
         # Create the instance
         return ModbusPDUReportServerIdRequestBuilder()
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdResponse.py
index 90b46c2c9a..ef0521fff3 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -71,6 +72,9 @@ class ModbusPDUReportServerIdResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUReportServerIdResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequest.py
index d9e9459933..2ca35b44d3 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -28,7 +29,7 @@ from plc4py.protocols.modbus.readwrite.ModbusPDUWriteFileRecordRequestItem impor
 )
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
-from sys import getsizeof
+from plc4py.spi.values.Common import get_size_of_array
 from typing import Any
 from typing import ClassVar
 from typing import List
@@ -47,7 +48,7 @@ class ModbusPDUWriteFileRecordRequest(ModbusPDU):
         write_buffer.push_context("ModbusPDUWriteFileRecordRequest")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: int = int(getsizeof(self.items))
+        byte_count: int = int(get_size_of_array(self.items))
         write_buffer.write_unsigned_byte(byte_count, logical_name="byte_count")
 
         # Array Field (items)
@@ -76,6 +77,9 @@ class ModbusPDUWriteFileRecordRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteFileRecordRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponse.py
index e093468183..d016f72198 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -28,7 +29,7 @@ from plc4py.protocols.modbus.readwrite.ModbusPDUWriteFileRecordResponseItem impo
 )
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
-from sys import getsizeof
+from plc4py.spi.values.Common import get_size_of_array
 from typing import Any
 from typing import ClassVar
 from typing import List
@@ -47,7 +48,7 @@ class ModbusPDUWriteFileRecordResponse(ModbusPDU):
         write_buffer.push_context("ModbusPDUWriteFileRecordResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: int = int(getsizeof(self.items))
+        byte_count: int = int(get_size_of_array(self.items))
         write_buffer.write_unsigned_byte(byte_count, logical_name="byte_count")
 
         # Array Field (items)
@@ -76,6 +77,9 @@ class ModbusPDUWriteFileRecordResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteFileRecordResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         byte_count: int = read_buffer.read_unsigned_byte(
             logical_name="byte_count", response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.py
index 0ff4236f33..0b995fd82a 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -89,6 +90,9 @@ class ModbusPDUWriteMultipleCoilsRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteMultipleCoilsRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         starting_address: int = read_buffer.read_unsigned_short(
             logical_name="starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.py
index 18c8a3fa34..430a7080fd 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUWriteMultipleCoilsResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteMultipleCoilsResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         starting_address: int = read_buffer.read_unsigned_short(
             logical_name="starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.py
index 1dd8467645..f11fc4f54a 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -89,6 +90,9 @@ class ModbusPDUWriteMultipleHoldingRegistersRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteMultipleHoldingRegistersRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         starting_address: int = read_buffer.read_unsigned_short(
             logical_name="starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.py
index d22e184831..fdb448a700 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUWriteMultipleHoldingRegistersResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteMultipleHoldingRegistersResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         starting_address: int = read_buffer.read_unsigned_short(
             logical_name="starting_address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.py
index f44615411c..d49318ffc3 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUWriteSingleCoilRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteSingleCoilRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         address: int = read_buffer.read_unsigned_short(
             logical_name="address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.py
index 8d96e13cb3..70b6f3295b 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUWriteSingleCoilResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteSingleCoilResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         address: int = read_buffer.read_unsigned_short(
             logical_name="address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.py
index 00d9eeb80f..2cdf4cf549 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUWriteSingleRegisterRequest(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteSingleRegisterRequest")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         address: int = read_buffer.read_unsigned_short(
             logical_name="address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.py
index f3609473d2..7e98410b2a 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -72,6 +73,9 @@ class ModbusPDUWriteSingleRegisterResponse(ModbusPDU):
     def static_parse_builder(read_buffer: ReadBuffer, response: bool):
         read_buffer.push_context("ModbusPDUWriteSingleRegisterResponse")
 
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         address: int = read_buffer.read_unsigned_short(
             logical_name="address", bit_length=16, response=response
         )
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusRtuADU.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusRtuADU.py
index c6026430a0..0a21a0cfd1 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusRtuADU.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusRtuADU.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -84,6 +85,11 @@ class ModbusRtuADU(ModbusADU):
     ):
         read_buffer.push_context("ModbusRtuADU")
 
+        if isinstance(driver_type, str):
+            driver_type = DriverType[driver_type]
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         address: int = read_buffer.read_unsigned_byte(
             logical_name="address",
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/modbus/readwrite/ModbusTcpADU.py b/plc4py/plc4py/protocols/modbus/readwrite/ModbusTcpADU.py
index f0edc3a8ee..3501ed5396 100644
--- a/plc4py/plc4py/protocols/modbus/readwrite/ModbusTcpADU.py
+++ b/plc4py/plc4py/protocols/modbus/readwrite/ModbusTcpADU.py
@@ -19,6 +19,7 @@
 
 from dataclasses import dataclass
 
+from distutils.util import strtobool
 from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -102,6 +103,11 @@ class ModbusTcpADU(ModbusADU):
     ):
         read_buffer.push_context("ModbusTcpADU")
 
+        if isinstance(driver_type, str):
+            driver_type = DriverType[driver_type]
+        if isinstance(response, str):
+            response = bool(strtobool(response))
+
         transaction_identifier: int = read_buffer.read_unsigned_short(
             logical_name="transaction_identifier",
             bit_length=16,
diff --git a/plc4py/plc4py/drivers/__init__.py b/plc4py/plc4py/protocols/simulated/__init__.py
similarity index 100%
copy from plc4py/plc4py/drivers/__init__.py
copy to plc4py/plc4py/protocols/simulated/__init__.py
diff --git a/plc4py/plc4py/protocols/umas/StaticHelper.py b/plc4py/plc4py/protocols/umas/StaticHelper.py
index 9a8074674d..b6f7e15392 100644
--- a/plc4py/plc4py/protocols/umas/StaticHelper.py
+++ b/plc4py/plc4py/protocols/umas/StaticHelper.py
@@ -14,50 +14,49 @@
 #  KIND, either express or implied.  See the License for the
 #  specific language governing permissions and limitations
 #  under the License.
-from plc4py.spi.generation.ReadBuffer import ReadBuffer
-
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
+from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBufferByteBased
 from plc4py.utils.GenericTypes import ByteOrder
 
 auch_crc_hi: bytearray = bytearray(
-    b"\x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81 \
-        \x40\x01\xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0 \
-        \x80\x41\x01\xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01 \
-        \xC0\x80\x41\x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0\x80\x41 \
-        \x00\xC1\x81\x40\x01\xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81 \
-        \x40\x01\xC0\x80\x41\x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0 \
-        \x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0\x80\x41\x01 \
-        \xC0\x80\x41\x00\xC1\x81\x40\x01\xC0\x80\x41\x00\xC1\x81\x40 \
-        \x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81 \
-        \x40\x00\xC1\x81\x40\x01\xC0\x80\x41\x00\xC1\x81\x40\x01\xC0 \
-        \x80\x41\x01\xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01 \
-        \xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81\x40\x01\xC0\x80\x41 \
-        \x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0\x80\x41\x00\xC1\x81 \
-        \x40\x01\xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81\x40\x01\xC0 \
-        \x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0\x80\x41\x01 \
-        \xC0\x80\x41\x00\xC1\x81\x40\x00\xC1\x81\x40\x01\xC0\x80\x41 \
-        \x00\xC1\x81\x40\x01\xC0\x80\x41\x01\xC0\x80\x41\x00\xC1\x81 \
+    b"\x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81 \
+        \x40\x01\xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0 \
+        \x80\x41\x01\xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01 \
+        \xc0\x80\x41\x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0\x80\x41 \
+        \x00\xc1\x81\x40\x01\xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81 \
+        \x40\x01\xc0\x80\x41\x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0 \
+        \x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0\x80\x41\x01 \
+        \xc0\x80\x41\x00\xc1\x81\x40\x01\xc0\x80\x41\x00\xc1\x81\x40 \
+        \x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81 \
+        \x40\x00\xc1\x81\x40\x01\xc0\x80\x41\x00\xc1\x81\x40\x01\xc0 \
+        \x80\x41\x01\xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01 \
+        \xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81\x40\x01\xc0\x80\x41 \
+        \x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0\x80\x41\x00\xc1\x81 \
+        \x40\x01\xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81\x40\x01\xc0 \
+        \x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0\x80\x41\x01 \
+        \xc0\x80\x41\x00\xc1\x81\x40\x00\xc1\x81\x40\x01\xc0\x80\x41 \
+        \x00\xc1\x81\x40\x01\xc0\x80\x41\x01\xc0\x80\x41\x00\xc1\x81 \
         \x40"
 )
 
 auch_crc_lo: bytearray = bytearray(
-    b"\x00\xC0\xC1\x01\xC3\x03\x02\xC2\xC6\x06\x07\xC7\x05\xC5\xC4 \
-        \x04\xCC\x0C\x0D\xCD\x0F\xCF\xCE\x0E\x0A\xCA\xCB\x0B\xC9\x09 \
-        \x08\xC8\xD8\x18\x19\xD9\x1B\xDB\xDA\x1A\x1E\xDE\xDF\x1F\xDD \
-        \x1D\x1C\xDC\x14\xD4\xD5\x15\xD7\x17\x16\xD6\xD2\x12\x13\xD3 \
-        \x11\xD1\xD0\x10\xF0\x30\x31\xF1\x33\xF3\xF2\x32\x36\xF6\xF7 \
-        \x37\xF5\x35\x34\xF4\x3C\xFC\xFD\x3D\xFF\x3F\x3E\xFE\xFA\x3A \
-        \x3B\xFB\x39\xF9\xF8\x38\x28\xE8\xE9\x29\xEB\x2B\x2A\xEA\xEE \
-        \x2E\x2F\xEF\x2D\xED\xEC\x2C\xE4\x24\x25\xE5\x27\xE7\xE6\x26 \
-        \x22\xE2\xE3\x23\xE1\x21\x20\xE0\xA0\x60\x61\xA1\x63\xA3\xA2 \
-        \x62\x66\xA6\xA7\x67\xA5\x65\x64\xA4\x6C\xAC\xAD\x6D\xAF\x6F \
-        \x6E\xAE\xAA\x6A\x6B\xAB\x69\xA9\xA8\x68\x78\xB8\xB9\x79\xBB \
-        \x7B\x7A\xBA\xBE\x7E\x7F\xBF\x7D\xBD\xBC\x7C\xB4\x74\x75\xB5 \
-        \x77\xB7\xB6\x76\x72\xB2\xB3\x73\xB1\x71\x70\xB0\x50\x90\x91 \
-        \x51\x93\x53\x52\x92\x96\x56\x57\x97\x55\x95\x94\x54\x9C\x5C \
-        \x5D\x9D\x5F\x9F\x9E\x5E\x5A\x9A\x9B\x5B\x99\x59\x58\x98\x88 \
-        \x48\x49\x89\x4B\x8B\x8A\x4A\x4E\x8E\x8F\x4F\x8D\x4D\x4C\x8C \
+    b"\x00\xc0\xc1\x01\xc3\x03\x02\xc2\xc6\x06\x07\xc7\x05\xc5\xc4 \
+        \x04\xcc\x0c\x0d\xcd\x0f\xcf\xce\x0e\x0a\xca\xcb\x0b\xc9\x09 \
+        \x08\xc8\xd8\x18\x19\xd9\x1b\xdb\xda\x1a\x1e\xde\xdf\x1f\xdd \
+        \x1d\x1c\xdc\x14\xd4\xd5\x15\xd7\x17\x16\xd6\xd2\x12\x13\xd3 \
+        \x11\xd1\xd0\x10\xf0\x30\x31\xf1\x33\xf3\xf2\x32\x36\xf6\xf7 \
+        \x37\xf5\x35\x34\xf4\x3c\xfc\xfd\x3d\xff\x3f\x3e\xfe\xfa\x3a \
+        \x3b\xfb\x39\xf9\xf8\x38\x28\xe8\xe9\x29\xeb\x2b\x2a\xea\xee \
+        \x2e\x2f\xef\x2d\xed\xec\x2c\xe4\x24\x25\xe5\x27\xe7\xe6\x26 \
+        \x22\xe2\xe3\x23\xe1\x21\x20\xe0\xa0\x60\x61\xa1\x63\xa3\xa2 \
+        \x62\x66\xa6\xa7\x67\xa5\x65\x64\xa4\x6c\xac\xad\x6d\xaf\x6f \
+        \x6e\xae\xaa\x6a\x6b\xab\x69\xa9\xa8\x68\x78\xb8\xb9\x79\xbb \
+        \x7b\x7a\xba\xbe\x7e\x7f\xbf\x7d\xbd\xbc\x7c\xb4\x74\x75\xb5 \
+        \x77\xb7\xb6\x76\x72\xb2\xb3\x73\xb1\x71\x70\xb0\x50\x90\x91 \
+        \x51\x93\x53\x52\x92\x96\x56\x57\x97\x55\x95\x94\x54\x9c\x5c \
+        \x5d\x9d\x5f\x9f\x9e\x5e\x5a\x9a\x9b\x5b\x99\x59\x58\x98\x88 \
+        \x48\x49\x89\x4b\x8b\x8a\x4a\x4e\x8e\x8f\x4f\x8d\x4d\x4c\x8c \
         \x44\x84\x85\x45\x87\x47\x46\x86\x82\x42\x43\x83\x41\x81\x80 \
         \x40"
 )
diff --git a/plc4py/plc4py/protocols/umas/readwrite/ModbusPDU.py b/plc4py/plc4py/protocols/umas/readwrite/ModbusPDU.py
index 3b347c107e..453d427759 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/ModbusPDU.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/ModbusPDU.py
@@ -123,6 +123,12 @@ class ModbusPDU(ABC, PlcMessage):
         read_buffer: ReadBuffer, umas_request_function_key: int, byte_length: int
     ):
         read_buffer.push_context("ModbusPDU")
+
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         error_flag: bool = read_buffer.read_bit(
             logical_name="error_flag",
             bit_length=1,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/ModbusPDUError.py b/plc4py/plc4py/protocols/umas/readwrite/ModbusPDUError.py
index 9a4139d4e2..98931e8671 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/ModbusPDUError.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/ModbusPDUError.py
@@ -68,6 +68,11 @@ class ModbusPDUError(ModbusPDU):
     ):
         read_buffer.push_context("ModbusPDUError")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         exception_code: ModbusErrorCode = read_buffer.read_enum(
             read_function=ModbusErrorCode,
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasInitCommsRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasInitCommsRequest.py
index c24cc49fb3..68a8b212ff 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasInitCommsRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasInitCommsRequest.py
@@ -67,6 +67,11 @@ class UmasInitCommsRequest(UmasPDUItem):
     ):
         read_buffer.push_context("UmasInitCommsRequest")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         unknown_object: int = read_buffer.read_unsigned_byte(
             logical_name="unknown_object",
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasInitCommsResponse.py b/plc4py/plc4py/protocols/umas/readwrite/UmasInitCommsResponse.py
index e48701a44b..45de329de1 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasInitCommsResponse.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasInitCommsResponse.py
@@ -110,6 +110,11 @@ class UmasInitCommsResponse(UmasPDUItem):
     ):
         read_buffer.push_context("UmasInitCommsResponse")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         max_frame_size: int = read_buffer.read_unsigned_short(
             logical_name="max_frame_size",
             bit_length=16,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasMemoryBlock.py b/plc4py/plc4py/protocols/umas/readwrite/UmasMemoryBlock.py
index ac133ba69a..194c8b24a4 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasMemoryBlock.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasMemoryBlock.py
@@ -101,6 +101,11 @@ class UmasMemoryBlock(ABC, PlcMessage):
     def static_parse_context(read_buffer: ReadBuffer, block_number: int, offset: int):
         read_buffer.push_context("UmasMemoryBlock")
 
+        if isinstance(block_number, str):
+            block_number = int(block_number)
+        if isinstance(offset, str):
+            offset = int(offset)
+
         # Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
         builder: UmasMemoryBlockBuilder = None
         from plc4py.protocols.umas.readwrite.UmasMemoryBlockBasicInfo import (
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasMemoryBlockBasicInfo.py b/plc4py/plc4py/protocols/umas/readwrite/UmasMemoryBlockBasicInfo.py
index d3af178d51..6fd5ef975c 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasMemoryBlockBasicInfo.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasMemoryBlockBasicInfo.py
@@ -87,6 +87,11 @@ class UmasMemoryBlockBasicInfo(UmasMemoryBlock):
     def static_parse_builder(read_buffer: ReadBuffer, block_number: int, offset: int):
         read_buffer.push_context("UmasMemoryBlockBasicInfo")
 
+        if isinstance(block_number, str):
+            block_number = int(block_number)
+        if isinstance(offset, str):
+            offset = int(offset)
+
         range: int = read_buffer.read_unsigned_short(
             logical_name="range",
             bit_length=16,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDU.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDU.py
index 0d6f553079..94efa46d37 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDU.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDU.py
@@ -66,6 +66,11 @@ class UmasPDU(ModbusPDU):
     ):
         read_buffer.push_context("UmasPDU")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         item: UmasPDUItem = read_buffer.read_complex(
             read_function=UmasPDUItem.static_parse,
             logical_name="item",
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUItem.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUItem.py
index 6f2fe3f3e5..d5963a04ff 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUItem.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUItem.py
@@ -130,6 +130,11 @@ class UmasPDUItem(ABC, PlcMessage):
     ):
         read_buffer.push_context("UmasPDUItem")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         pairing_key: int = read_buffer.read_unsigned_byte(
             logical_name="pairing_key",
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcIdentRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcIdentRequest.py
index 5d6c8946ad..cd9b720f98 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcIdentRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcIdentRequest.py
@@ -57,6 +57,11 @@ class UmasPDUPlcIdentRequest(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUPlcIdentRequest")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         read_buffer.pop_context("UmasPDUPlcIdentRequest")
         # Create the instance
         return UmasPDUPlcIdentRequestBuilder()
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcIdentResponse.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcIdentResponse.py
index a1ad198f73..89fe46ff02 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcIdentResponse.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcIdentResponse.py
@@ -178,6 +178,11 @@ class UmasPDUPlcIdentResponse(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUPlcIdentResponse")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         range: int = read_buffer.read_unsigned_short(
             logical_name="range",
             bit_length=16,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcStatusRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcStatusRequest.py
index 5b09bdf00c..3a44595476 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcStatusRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcStatusRequest.py
@@ -57,6 +57,11 @@ class UmasPDUPlcStatusRequest(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUPlcStatusRequest")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         read_buffer.pop_context("UmasPDUPlcStatusRequest")
         # Create the instance
         return UmasPDUPlcStatusRequestBuilder()
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcStatusResponse.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcStatusResponse.py
index fe826510d6..388b8639cc 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcStatusResponse.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUPlcStatusResponse.py
@@ -97,6 +97,11 @@ class UmasPDUPlcStatusResponse(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUPlcStatusResponse")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         not_used1: int = read_buffer.read_unsigned_byte(
             logical_name="not_used1",
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUProjectInfoRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUProjectInfoRequest.py
index dd98353137..825ed3516c 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUProjectInfoRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUProjectInfoRequest.py
@@ -67,6 +67,11 @@ class UmasPDUProjectInfoRequest(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUProjectInfoRequest")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         subcode: int = read_buffer.read_unsigned_byte(
             logical_name="subcode",
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadMemoryBlockRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadMemoryBlockRequest.py
index a40d872903..628fe6ff89 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadMemoryBlockRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadMemoryBlockRequest.py
@@ -101,6 +101,11 @@ class UmasPDUReadMemoryBlockRequest(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUReadMemoryBlockRequest")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         range: int = read_buffer.read_unsigned_byte(
             logical_name="range",
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadMemoryBlockResponse.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadMemoryBlockResponse.py
index c36f6d89e7..a80bd6b42b 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadMemoryBlockResponse.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadMemoryBlockResponse.py
@@ -86,6 +86,11 @@ class UmasPDUReadMemoryBlockResponse(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUReadMemoryBlockResponse")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         range: int = read_buffer.read_unsigned_byte(
             logical_name="range",
             bit_length=8,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNames.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNames.py
index 0db64fe612..3ab7e8882f 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNames.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNames.py
@@ -17,10 +17,14 @@
 # under the License.
 #
 
+import math
 from dataclasses import dataclass
+from typing import Any, ClassVar, List
 
-from plc4py.api.exceptions.exceptions import PlcRuntimeException
-from plc4py.api.exceptions.exceptions import SerializationException
+from plc4py.api.exceptions.exceptions import (
+    PlcRuntimeException,
+    SerializationException,
+)
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.umas.readwrite.UmasPDUItem import UmasPDUItem
 from plc4py.protocols.umas.readwrite.UmasUnlocatedVariableReference import (
@@ -29,10 +33,6 @@ from plc4py.protocols.umas.readwrite.UmasUnlocatedVariableReference import (
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from plc4py.utils.GenericTypes import ByteOrder
-from typing import Any
-from typing import ClassVar
-from typing import List
-import math
 
 
 @dataclass
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNamesRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNamesRequest.py
index c2f6c0055f..83f576672a 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNamesRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNamesRequest.py
@@ -108,6 +108,11 @@ class UmasPDUReadUnlocatedVariableNamesRequest(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUReadUnlocatedVariableNamesRequest")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         record_type: int = read_buffer.read_unsigned_short(
             logical_name="record_type",
             bit_length=16,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableResponse.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableResponse.py
index ec3806ddc4..489ae66068 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableResponse.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableResponse.py
@@ -70,6 +70,11 @@ class UmasPDUReadUnlocatedVariableResponse(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUReadUnlocatedVariableResponse")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         block: List[Any] = read_buffer.read_array_field(
             logical_name="block",
             read_function=read_buffer.read_unsigned_byte,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py
index 0884ccd019..62e6134d94 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py
@@ -88,6 +88,11 @@ class UmasPDUReadVariableRequest(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUReadVariableRequest")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         crc: int = read_buffer.read_unsigned_int(
             logical_name="crc",
             bit_length=32,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableResponse.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableResponse.py
index 3bb995b4f4..d5a71040da 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableResponse.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableResponse.py
@@ -70,6 +70,11 @@ class UmasPDUReadVariableResponse(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUReadVariableResponse")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         block: List[Any] = read_buffer.read_array_field(
             logical_name="block",
             read_function=read_buffer.read_unsigned_byte,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableRequest.py
index 1620150f89..cd4cb87930 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableRequest.py
@@ -88,6 +88,11 @@ class UmasPDUWriteVariableRequest(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUWriteVariableRequest")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         crc: int = read_buffer.read_unsigned_int(
             logical_name="crc",
             bit_length=32,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableResponse.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableResponse.py
index 9ee159efc0..fa0fcdaf03 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableResponse.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableResponse.py
@@ -70,6 +70,11 @@ class UmasPDUWriteVariableResponse(UmasPDUItem):
     ):
         read_buffer.push_context("UmasPDUWriteVariableResponse")
 
+        if isinstance(umas_request_function_key, str):
+            umas_request_function_key = int(umas_request_function_key)
+        if isinstance(byte_length, str):
+            byte_length = int(byte_length)
+
         block: List[Any] = read_buffer.read_array_field(
             logical_name="block",
             read_function=read_buffer.read_unsigned_byte,
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasVariableBlock.py b/plc4py/plc4py/protocols/umas/readwrite/UmasVariableBlock.py
index 24b9a2d005..5a314a823d 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasVariableBlock.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasVariableBlock.py
@@ -17,17 +17,18 @@
 # under the License.
 #
 
+import math
+from abc import ABC, abstractmethod
 from dataclasses import dataclass
 
-from abc import ABC
-from abc import abstractmethod
-from plc4py.api.exceptions.exceptions import ParseException
-from plc4py.api.exceptions.exceptions import PlcRuntimeException
-from plc4py.api.exceptions.exceptions import SerializationException
+from plc4py.api.exceptions.exceptions import (
+    ParseException,
+    PlcRuntimeException,
+    SerializationException,
+)
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
-import math
 
 
 @dataclass
diff --git a/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py b/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py
index 5826fc3bee..7c43a744b8 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py
@@ -17,14 +17,16 @@
 # under the License.
 #
 
+import math
 from dataclasses import dataclass
 
-from plc4py.api.exceptions.exceptions import PlcRuntimeException
-from plc4py.api.exceptions.exceptions import SerializationException
+from plc4py.api.exceptions.exceptions import (
+    PlcRuntimeException,
+    SerializationException,
+)
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
-import math
 
 
 @dataclass
@@ -141,7 +143,12 @@ class VariableRequestReference:
         # Create the instance
         _variable_request_reference: VariableRequestReference = (
             VariableRequestReference(
-                is_array, data_size_index, block, base_offset, offset, array_length
+                is_array,
+                data_size_index,
+                block,
+                base_offset,
+                offset,
+                array_length,
             )
         )
         return _variable_request_reference
diff --git a/plc4py/plc4py/spi/Plc4xBaseProtocol.py b/plc4py/plc4py/spi/Plc4xBaseProtocol.py
index 69d04180bd..a6c04ccb81 100644
--- a/plc4py/plc4py/spi/Plc4xBaseProtocol.py
+++ b/plc4py/plc4py/spi/Plc4xBaseProtocol.py
@@ -17,7 +17,7 @@
 # under the License.
 #
 
-from asyncio import Protocol, Future, BaseProtocol
+from asyncio import BaseProtocol, Future, Protocol
 from dataclasses import dataclass
 from typing import Union
 
diff --git a/plc4py/plc4py/spi/PlcDriverClassLoader.py b/plc4py/plc4py/spi/PlcDriverClassLoader.py
index 0bb58f78c2..b676b7086b 100644
--- a/plc4py/plc4py/spi/PlcDriverClassLoader.py
+++ b/plc4py/plc4py/spi/PlcDriverClassLoader.py
@@ -21,12 +21,13 @@ from typing import Type
 import pluggy
 
 from plc4py.api.PlcDriver import PlcDriver
+from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
 
 
 class PlcDriverClassLoader:
     """Hook spec for PLC4PY Driver Loaders"""
 
-    hookspec = pluggy.HookspecMarker("plc4py")
+    hookspec = pluggy.HookspecMarker("plc4py.drivers")
 
     @staticmethod
     @hookspec
@@ -37,3 +38,19 @@ class PlcDriverClassLoader:
     @hookspec
     def key() -> str:
         """Unique key to identify the driver"""
+
+
+class PlcTransportClassLoader:
+    """Hook spec for PLC4PY Transport Loaders"""
+
+    hookspec = pluggy.HookspecMarker("plc4py.transports")
+
+    @staticmethod
+    @hookspec
+    def get_transport() -> Type[Plc4xBaseTransport]:
+        """Returns the PlcConnection class that is used to instantiate the transport"""
+
+    @staticmethod
+    @hookspec
+    def key() -> str:
+        """Unique key to identify the transport"""
diff --git a/plc4py/plc4py/spi/configuration/PlcConfiguration.py b/plc4py/plc4py/spi/configuration/PlcConfiguration.py
index 9c18a4e4d3..e67fd84952 100644
--- a/plc4py/plc4py/spi/configuration/PlcConfiguration.py
+++ b/plc4py/plc4py/spi/configuration/PlcConfiguration.py
@@ -18,7 +18,7 @@
 #
 import re
 from dataclasses import InitVar, dataclass, field
-from typing import Optional, Dict
+from typing import Dict, Optional
 
 
 @dataclass
diff --git a/plc4py/plc4py/spi/connection/ProtocolStack.py b/plc4py/plc4py/spi/connection/ProtocolStack.py
index 8529df5e3b..d4add816d7 100644
--- a/plc4py/plc4py/spi/connection/ProtocolStack.py
+++ b/plc4py/plc4py/spi/connection/ProtocolStack.py
@@ -18,12 +18,12 @@
 #
 from abc import ABC, abstractmethod
 from dataclasses import dataclass
-from typing import TypeVar, Generic, Callable, Any, List
+from typing import Any, Callable, Generic, List, TypeVar
 
 from plc4py.api.listener import EventListener
-from plc4py.spi.Plc4xBaseProtocol import Plc4xBaseProtocol
 from plc4py.spi.context.DriverContext import DriverContext
 from plc4py.spi.messages.ChannelMessage import ChannelMessage
+from plc4py.spi.Plc4xBaseProtocol import Plc4xBaseProtocol
 from plc4py.utils.GenericTypes import ByteOrder
 
 
diff --git a/plc4py/plc4py/spi/generation/ReadBuffer.py b/plc4py/plc4py/spi/generation/ReadBuffer.py
index 3bdc07020d..62b110243d 100644
--- a/plc4py/plc4py/spi/generation/ReadBuffer.py
+++ b/plc4py/plc4py/spi/generation/ReadBuffer.py
@@ -16,13 +16,13 @@
 #  under the License.
 import struct
 import types
-from abc import abstractmethod, ABC
+from abc import ABC, abstractmethod
 from dataclasses import dataclass
-from typing import List, Union, Any
+from typing import Any, List, Union
 
 import aenum
 from bitarray import bitarray
-from bitarray.util import zeros, ba2int, ba2base
+from bitarray.util import ba2base, ba2int, zeros
 
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
@@ -132,7 +132,11 @@ class ReadBuffer(ByteOrderAware, PositionAware, ABC):
 
     @abstractmethod
     def read_enum(
-        self, bit_length: int = -1, logical_name: str = "", read_function=None, **kwargs
+        self,
+        bit_length: int = -1,
+        logical_name: str = "",
+        read_function=None,
+        **kwargs,
     ) -> Any:
         raise NotImplementedError
 
@@ -144,7 +148,7 @@ class ReadBuffer(ByteOrderAware, PositionAware, ABC):
         count: int = None,
         length: int = None,
         terminated=None,
-        **kwargs
+        **kwargs,
     ) -> List[Any]:
         raise NotImplementedError
 
@@ -206,7 +210,8 @@ class ReadBufferByteBased(ReadBuffer):
             raise SerializationException("unsigned byte can only contain max 8 bits")
         else:
             result: int = ba2int(
-                self.bb[self.position : self.position + bit_length], signed=False
+                self.bb[self.position : self.position + bit_length],
+                signed=False,
             )
             self.position += bit_length
             return result
@@ -281,7 +286,8 @@ class ReadBufferByteBased(ReadBuffer):
             raise SerializationException("signed byte can only contain max 8 bits")
         else:
             result: int = ba2int(
-                self.bb[self.position : self.position + bit_length], signed=False
+                self.bb[self.position : self.position + bit_length],
+                signed=False,
             )
             self.position += bit_length
             return result
@@ -351,7 +357,8 @@ class ReadBufferByteBased(ReadBuffer):
             if byte_order == ByteOrder.LITTLE_ENDIAN:
                 endianness = "<"
             result: float = struct.unpack(
-                endianness + "f", self.bb[self.position : self.position + bit_length]
+                endianness + "f",
+                self.bb[self.position : self.position + bit_length],
             )[0]
             self.position += bit_length
             return result
@@ -367,7 +374,8 @@ class ReadBufferByteBased(ReadBuffer):
             if byte_order == ByteOrder.LITTLE_ENDIAN:
                 endianness = "<"
             result: float = struct.unpack(
-                endianness + "d", self.bb[self.position : self.position + bit_length]
+                endianness + "d",
+                self.bb[self.position : self.position + bit_length],
             )[0]
             self.position += bit_length
             return result
@@ -381,12 +389,17 @@ class ReadBufferByteBased(ReadBuffer):
             return read_function()
 
     def read_enum(
-        self, bit_length: int = -1, logical_name: str = "", read_function=None, **kwargs
+        self,
+        bit_length: int = -1,
+        logical_name: str = "",
+        read_function=None,
+        **kwargs,
     ) -> Any:
         if isinstance(read_function, aenum._enum.EnumType):
             enum_return_value = read_function(
                 ba2int(
-                    self.bb[self.position : self.position + bit_length], signed=False
+                    self.bb[self.position : self.position + bit_length],
+                    signed=False,
                 )
             )
             return enum_return_value
@@ -412,7 +425,7 @@ class ReadBufferByteBased(ReadBuffer):
         count: int = None,
         length: int = None,
         terminated=None,
-        **kwargs
+        **kwargs,
     ) -> List[Any]:
         if count is not None:
             parsed_array = []
@@ -421,5 +434,13 @@ class ReadBufferByteBased(ReadBuffer):
                     read_function(logical_name=logical_name, read_buffer=self, **kwargs)
                 )
             return parsed_array
+        elif length is not None:
+            parsed_array = []
+            end_pos = self.get_pos() + (length * 8)
+            while self.get_pos() < end_pos:
+                parsed_array.append(
+                    read_function(logical_name=logical_name, read_buffer=self, **kwargs)
+                )
+            return parsed_array
         else:
             raise NotImplementedError
diff --git a/plc4py/plc4py/spi/generation/WriteBuffer.py b/plc4py/plc4py/spi/generation/WriteBuffer.py
index 348ddc8584..6f0321a40b 100644
--- a/plc4py/plc4py/spi/generation/WriteBuffer.py
+++ b/plc4py/plc4py/spi/generation/WriteBuffer.py
@@ -19,17 +19,17 @@ import types
 from abc import ABCMeta
 from ctypes import (
     c_byte,
-    c_ubyte,
-    c_uint16,
-    c_uint32,
-    c_uint64,
+    c_double,
+    c_float,
+    c_int8,
     c_int16,
     c_int32,
     c_int64,
-    c_float,
-    c_double,
-    c_int8,
+    c_ubyte,
     c_uint8,
+    c_uint16,
+    c_uint32,
+    c_uint64,
 )
 from dataclasses import dataclass
 from typing import List, Union
@@ -37,10 +37,12 @@ from typing import List, Union
 from bitarray import bitarray
 from bitarray.util import zeros
 from typing_extensions import override
+import xml.etree.ElementTree as ET
 
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.utils.GenericTypes import ByteOrder, ByteOrderAware
+from xsdata.utils.text import camel_case
 
 
 class PositionAware:
@@ -130,7 +132,7 @@ class WriteBuffer(ByteOrderAware, PositionAware):
         bit_length: int = -1,
         logical_name: str = "",
         encoding: str = "UTF-8",
-        **kwargs
+        **kwargs,
     ) -> None:
         raise NotImplementedError
 
@@ -211,11 +213,15 @@ class WriteBufferByteBased(WriteBuffer, metaclass=ABCMeta):
             raise SerializationException("unsigned byte can only contain max 8 bits")
         else:
             self._handle_numeric_encoding(
-                value, bit_length, numeric_format="B", **kwargs
+                int(value), bit_length, numeric_format="B", **kwargs
             )
 
     def write_unsigned_short(
-        self, value: int, bit_length: int = 16, logical_name: str = "", **kwargs
+        self,
+        value: int,
+        bit_length: int = 16,
+        logical_name: str = "",
+        **kwargs,
     ) -> None:
         if bit_length <= 0:
             raise SerializationException("unsigned short must contain at least 1 bit")
@@ -223,11 +229,15 @@ class WriteBufferByteBased(WriteBuffer, metaclass=ABCMeta):
             raise SerializationException("unsigned short can only contain max 16 bits")
         else:
             self._handle_numeric_encoding(
-                value, bit_length, numeric_format="H", **kwargs
+                int(value), bit_length, numeric_format="H", **kwargs
             )
 
     def write_unsigned_int(
-        self, value: int, bit_length: int = 32, logical_name: str = "", **kwargs
+        self,
+        value: int,
+        bit_length: int = 32,
+        logical_name: str = "",
+        **kwargs,
     ) -> None:
         if bit_length <= 0:
             raise SerializationException("unsigned int must contain at least 1 bit")
@@ -235,11 +245,15 @@ class WriteBufferByteBased(WriteBuffer, metaclass=ABCMeta):
             raise SerializationException("unsigned int can only contain max 32 bits")
         else:
             self._handle_numeric_encoding(
-                value, bit_length, numeric_format="I", **kwargs
+                int(value), bit_length, numeric_format="I", **kwargs
             )
 
     def write_unsigned_long(
-        self, value: int, bit_length: int = 64, logical_name: str = "", **kwargs
+        self,
+        value: int,
+        bit_length: int = 64,
+        logical_name: str = "",
+        **kwargs,
     ) -> None:
         if bit_length <= 0:
             raise SerializationException("unsigned long must contain at least 1 bit")
@@ -247,7 +261,7 @@ class WriteBufferByteBased(WriteBuffer, metaclass=ABCMeta):
             raise SerializationException("unsigned long can only contain max 16 bits")
         else:
             self._handle_numeric_encoding(
-                value, bit_length, numeric_format="Q", **kwargs
+                int(value), bit_length, numeric_format="Q", **kwargs
             )
 
     def write_signed_byte(
@@ -257,37 +271,61 @@ class WriteBufferByteBased(WriteBuffer, metaclass=ABCMeta):
             raise SerializationException("Signed byte must contain at least 1 bit")
         elif bit_length > 8:
             raise SerializationException("Signed byte can only contain max 8 bits")
-        self._handle_numeric_encoding(value, bit_length, numeric_format="b", **kwargs)
+        self._handle_numeric_encoding(
+            int(value), bit_length, numeric_format="b", **kwargs
+        )
 
     def write_short(
-        self, value: int, bit_length: int = 16, logical_name: str = "", **kwargs
+        self,
+        value: int,
+        bit_length: int = 16,
+        logical_name: str = "",
+        **kwargs,
     ) -> None:
         if bit_length <= 0:
             raise SerializationException("Signed short must contain at least 1 bit")
         elif bit_length > 16:
             raise SerializationException("Signed short can only contain max 16 bits")
-        self._handle_numeric_encoding(value, bit_length, numeric_format="h", **kwargs)
+        self._handle_numeric_encoding(
+            int(value), bit_length, numeric_format="h", **kwargs
+        )
 
     def write_int(
-        self, value: int, bit_length: int = 32, logical_name: str = "", **kwargs
+        self,
+        value: int,
+        bit_length: int = 32,
+        logical_name: str = "",
+        **kwargs,
     ) -> None:
         if bit_length <= 0:
             raise SerializationException("Signed int must contain at least 1 bit")
         elif bit_length > 32:
             raise SerializationException("Signed int can only contain max 32 bits")
-        self._handle_numeric_encoding(value, bit_length, numeric_format="i", **kwargs)
+        self._handle_numeric_encoding(
+            int(value), bit_length, numeric_format="i", **kwargs
+        )
 
     def write_long(
-        self, value: int, bit_length: int = 64, logical_name: str = "", **kwargs
+        self,
+        value: int,
+        bit_length: int = 64,
+        logical_name: str = "",
+        **kwargs,
     ) -> None:
         if bit_length <= 0:
             raise SerializationException("Signed long must contain at least 1 bit")
         elif bit_length > 64:
             raise SerializationException("Signed long can only contain max 64 bits")
-        self._handle_numeric_encoding(value, bit_length, numeric_format="q", **kwargs)
+        self._handle_numeric_encoding(
+            int(value), bit_length, numeric_format="q", **kwargs
+        )
 
     def write_float(
-        self, value: float, bit_length: int = 32, logical_name: str = "", **kwargs
+        self,
+        value: float,
+        bit_length: int = 32,
+        logical_name: str = "",
+        **kwargs,
     ) -> None:
         if bit_length <= 0:
             raise SerializationException("Float must contain at least 1 bit")
@@ -296,7 +334,11 @@ class WriteBufferByteBased(WriteBuffer, metaclass=ABCMeta):
         self._handle_numeric_encoding(value, bit_length, numeric_format="f", **kwargs)
 
     def write_double(
-        self, value: float, bit_length: int = 64, logical_name: str = "", **kwargs
+        self,
+        value: float,
+        bit_length: int = 64,
+        logical_name: str = "",
+        **kwargs,
     ) -> None:
         if bit_length <= 0:
             raise SerializationException("Double must contain at least 1 bit")
@@ -332,6 +374,8 @@ class WriteBufferByteBased(WriteBuffer, metaclass=ABCMeta):
             endianness: str = ">"
             if byte_order == ByteOrder.LITTLE_ENDIAN:
                 endianness = "<"
+            if not isinstance(value, int):
+                pass
             result: bytes = struct.pack(
                 endianness + numeric_format,
                 value,
@@ -344,234 +388,226 @@ class WriteBufferByteBased(WriteBuffer, metaclass=ABCMeta):
             self.position += bit_length
 
 
-# class WriteBufferBoxBased(WriteBuffer):
-#     def __init__(self, ascii_box_writer: AsciiBoxWriter = AsciiBoxWriter.DEFAULT, ascii_box_writer_light: AsciiBoxWriter = AsciiBoxWriter.LIGHT, merge_single_boxes: bool = False, omit_empty_boxes: bool = False):
-#         self.ascii_box_writer: AsciiBoxWriter = ascii_box_writer
-#         self.ascii_box_writer_light = ascii_box_writer_light
-#         self.merge_single_boxes = merge_single_boxes
-#         self.omit_empty_boxes = omit_empty_boxes
-#         self.boxes: List[Union[AsciiBox, List[AsciiBox]]] = []
-#         self.desired_width: int = 120
-#         self.current_width: int = self.desired_width - 2
-#         self.pos: int = 1
-#
-#
-#     @property
-#     def get_byte_order(self) -> ByteOrder:
-#         # NO OP
-#         return ByteOrder.BIG_ENDIAN
-#
-#     @property
-#     def pos(self) -> int:
-#         return int(self.pos / 8)
-#
-#     @override
-#     def push_context(self, logical_name: str, **kargs):
-#         self.current_width -= Hex.box_line_overheat
-#         self.boxes.offer_last([])
-#
-#     @Override
-#     public void writeBit(String logicalName, boolean value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("b%d %b%s", value ? 1 : 0, value, additionalStringRepresentation), 0)));
-#         move(1);
-#     }
-#
-#     @Override
-#     public void writeByte(String logicalName, byte value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%02x '%c'%s", value, value < 32 || value > 126 ? '.' : value, additionalStringRepresentation), 0)));
-#         move(8);
-#     }
-#
-#     @Override
-#     public void writeByteArray(String logicalName, byte[] bytes, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         if (StringUtils.isNotBlank(additionalStringRepresentation)) {
-#             additionalStringRepresentation += "\n";
-#         }
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("%s%s", Hex.dump(bytes), additionalStringRepresentation), 0)));
-#         move(8 * bytes.length);
-#     }
-#
-#     @Override
-#     public void writeUnsignedByte(String logicalName, int bitLength, byte value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeUnsignedShort(String logicalName, int bitLength, short value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeUnsignedInt(String logicalName, int bitLength, int value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeUnsignedLong(String logicalName, int bitLength, long value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeUnsignedBigInteger(String logicalName, int bitLength, BigInteger value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeSignedByte(String logicalName, int bitLength, byte value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeShort(String logicalName, int bitLength, short value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeInt(String logicalName, int bitLength, int value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeLong(String logicalName, int bitLength, long value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeBigInteger(String logicalName, int bitLength, BigInteger value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeFloat(String logicalName, int bitLength, float value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %f%s", Float.valueOf(value).longValue(), value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeDouble(String logicalName, int bitLength, double value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %f%s", Double.valueOf(value).longValue(), value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeBigDecimal(String logicalName, int bitLength, BigDecimal value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("0x%0" + Math.max(bitLength / 4, 1) + "x %d%s", value, value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeString(String logicalName, int bitLength, String value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         boxes.offerLast(Either.left(asciiBoxWriter.boxString(logicalName, String.format("%s%s", value, additionalStringRepresentation), 0)));
-#         move(bitLength);
-#     }
-#
-#     @Override
-#     public void writeVirtual(String logicalName, Object value, WithWriterArgs... writerArgs) throws SerializationException {
-#         String additionalStringRepresentation = extractAdditionalStringRepresentation(writerArgs).map(s -> " " + s).orElse("");
-#         AsciiBox virtualBox;
-#         if (value instanceof String) {
-#             virtualBox = asciiBoxWriterLight.boxString(logicalName, String.format("%s%s", value, additionalStringRepresentation), 0);
-#         } else if (value instanceof Float) {
-#             Float number = (Float) value;
-#             virtualBox = asciiBoxWriterLight.boxString(logicalName, String.format("%f%s", number, additionalStringRepresentation), 0);
-#         } else if (value instanceof Double) {
-#             Double number = (Double) value;
-#             virtualBox = asciiBoxWriterLight.boxString(logicalName, String.format("%f%s", number, additionalStringRepresentation), 0);
-#         } else if (value instanceof Number) {
-#             // TODO: adjust rendering
-#             Number number = (Number) value;
-#             virtualBox = asciiBoxWriterLight.boxString(logicalName, String.format("0x%x %d%s", number, number, additionalStringRepresentation), 0);
-#         } else if (value instanceof Boolean) {
-#             virtualBox = asciiBoxWriterLight.boxString(logicalName, String.format("b%d %b%s", (Boolean) value ? 1 : 0, value, additionalStringRepresentation), 0);
-#         } else if (value instanceof Enum) {
-#             Enum<?> enumValue = (Enum<?>) value;
-#             virtualBox = asciiBoxWriterLight.boxString(logicalName, String.format("%s%s", enumValue.name(), additionalStringRepresentation), 0);
-#         } else if (value instanceof Serializable) {
-#             Serializable serializable = (Serializable) value;
-#             try {
-#                 WriteBufferBoxBased writeBuffer = new WriteBufferBoxBased(true, true);
-#                 serializable.serialize(writeBuffer);
-#                 virtualBox = asciiBoxWriterLight.boxBox(logicalName, writeBuffer.getBox(), 0);
-#             } catch (SerializationException e) {
-#                 virtualBox = asciiBoxWriterLight.boxString(logicalName, e.getMessage(), 0);
-#             }
-#         } else {
-#             virtualBox = asciiBoxWriterLight.boxString(logicalName, "un-renderable", 0);
-#         }
-#         boxes.offerLast(Either.left(virtualBox));
-#     }
-#
-#     @Override
-#     public void popContext(String logicalName, WithWriterArgs... writerArgs) {
-#         currentWidth += Hex.boxLineOverheat;
-#         Deque<AsciiBox> finalBoxes = new LinkedList<>();
-#         findTheBox:
-#         for (Either<AsciiBox, Deque<AsciiBox>> back = boxes.pollLast(); back != null; back = boxes.pollLast()) {
-#             if (back.isLeft()) {
-#                 AsciiBox asciiBox = back.getLeft();
-#                 if (omitEmptyBoxes && asciiBox.isEmpty()) {
-#                     continue;
-#                 }
-#                 finalBoxes.offerFirst(asciiBox);
-#             } else {
-#                 Deque<AsciiBox> asciiBoxes = back.get();
-#                 LinkedList<AsciiBox> reversedList = new LinkedList<>(asciiBoxes);
-#                 Collections.reverse(reversedList);
-#                 for (AsciiBox box : asciiBoxes) {
-#                     finalBoxes.offerFirst(box);
-#                 }
-#                 break findTheBox;
-#             }
-#         }
-#         if (mergeSingleBoxes && finalBoxes.size() == 1) {
-#             AsciiBox onlyChild = finalBoxes.remove();
-#             String childName = onlyChild.getBoxName();
-#             onlyChild = onlyChild.changeBoxName(logicalName + "/" + childName);
-#             if (omitEmptyBoxes && onlyChild.isEmpty()) {
-#                 return;
-#             }
-#             boxes.offerLast(Either.left(onlyChild));
-#             return;
-#         }
-#         AsciiBox asciiBox = asciiBoxWriter.boxBox(logicalName, asciiBoxWriter.alignBoxes(finalBoxes, currentWidth), 0);
-#         if (omitEmptyBoxes && asciiBox.isEmpty()) {
-#             return;
-#         }
-#         boxes.offerLast(Either.left(asciiBox));
-#     }
-#
-#     public AsciiBox getBox() {
-#         return boxes.peek().getLeft();
-#     }
-#
-#     private void move(int bits) {
-#         pos += bits;
-#     }
-# }
+class WriteBufferXmlBased(WriteBuffer, metaclass=ABCMeta):
+    NUMERIC_UNION = Union[
+        c_ubyte,
+        c_byte,
+        c_uint8,
+        c_uint16,
+        c_uint32,
+        c_uint64,
+        c_int8,
+        c_int16,
+        c_int32,
+        c_int64,
+        c_float,
+        c_double,
+    ]
+
+    def __init__(self, byte_order: ByteOrder = ByteOrder.BIG_ENDIAN):
+        # This refers to the bit alignment, which we always use big bit endianess
+        self.byte_order = byte_order
+        self.position = 0
+        self.stack = []
+
+    def get_bytes(self) -> memoryview:
+        return memoryview(bytearray([]))
+
+    def get_pos(self) -> int:
+        return self.position
+
+    def push_context(self, logical_name: str, **kwargs) -> None:
+        new_element: ET.Element = ET.Element(logical_name)
+        if len(self.stack) > 0:
+            self.stack[-1].append(new_element)
+        else:
+            self.stack.append(new_element)
+        self.stack.append(new_element)
+
+    def pop_context(self, logical_name: str, **kwargs) -> None:
+        self.stack.pop()
+
+    def write_bit(self, value: bool, logical_name: str = "", **kwargs) -> None:
+        data_type: str = "bit"
+        data: str = str(value).lower()
+        if "bit_length" in kwargs:
+            kwargs["bit_length"] = str(kwargs["bit_length"])
+        else:
+            kwargs["bit_length"] = str(1)
+        self._create_and_append(camel_case(logical_name), data_type, data, **kwargs)
+
+    def write_byte(self, value: int, logical_name: str = "", **kwargs) -> None:
+        data_type: str = "byte"
+        data: str = str(value)
+        if "bit_length" in kwargs:
+            kwargs["bit_length"] = str(kwargs["bit_length"])
+        else:
+            kwargs["bit_length"] = str(8)
+        self._create_and_append(camel_case(logical_name), data_type, data, **kwargs)
+
+    def write_byte_array(
+        self, value: List[int], logical_name: str = "", **kwargs
+    ) -> None:
+        data_type: str = "byte"
+        data: str = str(value)
+        if "bit_length" in kwargs:
+            kwargs["bit_length"] = str(kwargs["bit_length"])
+        else:
+            kwargs["bit_length"] = str(len(value) * 8)
+        self._create_and_append(camel_case(logical_name), data_type, data, **kwargs)
+
+    def write_unsigned_byte(
+        self, value: int, bit_length: int = 8, logical_name: str = "", **kwargs
+    ) -> None:
+        data_type: str = "uint"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_unsigned_short(
+        self,
+        value: int,
+        bit_length: int = 16,
+        logical_name: str = "",
+        **kwargs,
+    ) -> None:
+        data_type: str = "uint"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_unsigned_int(
+        self,
+        value: int,
+        bit_length: int = 32,
+        logical_name: str = "",
+        **kwargs,
+    ) -> None:
+        data_type: str = "udint"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_unsigned_long(
+        self,
+        value: int,
+        bit_length: int = 64,
+        logical_name: str = "",
+        **kwargs,
+    ) -> None:
+        data_type: str = "ulint"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_signed_byte(
+        self, value: int, bit_length: int = 8, logical_name: str = "", **kwargs
+    ) -> None:
+        data_type: str = "byte"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_short(
+        self,
+        value: int,
+        bit_length: int = 16,
+        logical_name: str = "",
+        **kwargs,
+    ) -> None:
+        data_type: str = "int"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_int(
+        self,
+        value: int,
+        bit_length: int = 32,
+        logical_name: str = "",
+        **kwargs,
+    ) -> None:
+        data_type: str = "dint"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_long(
+        self,
+        value: int,
+        bit_length: int = 64,
+        logical_name: str = "",
+        **kwargs,
+    ) -> None:
+        data_type: str = "lint"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_float(
+        self,
+        value: float,
+        bit_length: int = 32,
+        logical_name: str = "",
+        **kwargs,
+    ) -> None:
+        data_type: str = "real"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_double(
+        self,
+        value: float,
+        bit_length: int = 64,
+        logical_name: str = "",
+        **kwargs,
+    ) -> None:
+        data_type: str = "lreal"
+        data: str = str(value)
+        bit_length: str = str(bit_length)
+        self._create_and_append(
+            camel_case(logical_name), data_type, data, bit_length, **kwargs
+        )
+
+    def write_complex_array(
+        self, value: List[PlcMessage], logical_name: str = "", **kwargs
+    ) -> None:
+        for _ in value:
+            new_element: ET.Element = ET.Element(logical_name)
+            self.stack[-1].append(new_element)
+            self.stack.append(new_element)
+
+    def _create_and_append(
+        self, logical_name: str, data_type: str, data: str, bit_length: str, **kwargs
+    ) -> None:
+        new_element: ET.Element = ET.Element(logical_name)
+        new_element.set("dataType", data_type)
+        new_element.set("bitlength", bit_length)
+        new_element.text = data
+        if len(self.stack) > 0:
+            self.stack[-1].append(new_element)
+        else:
+            self.stack.append(new_element)
+
+    def to_xml_string(self) -> str:
+        ET.indent(self.stack[0], space="\t", level=0)
+        return ET.tostring(self.stack[0]).decode("utf-8")
diff --git a/plc4py/plc4py/spi/messages/PlcRequest.py b/plc4py/plc4py/spi/messages/PlcRequest.py
index f2eb5a48db..73769d7299 100644
--- a/plc4py/plc4py/spi/messages/PlcRequest.py
+++ b/plc4py/plc4py/spi/messages/PlcRequest.py
@@ -18,12 +18,12 @@
 #
 from plc4py.api.messages.PlcField import PlcTag
 from plc4py.api.messages.PlcRequest import (
-    PlcReadRequest,
-    ReadRequestBuilder,
     BrowseRequestBuilder,
     PlcBrowseRequest,
-    WriteRequestBuilder,
+    PlcReadRequest,
     PlcWriteRequest,
+    ReadRequestBuilder,
+    WriteRequestBuilder,
 )
 from plc4py.api.value.PlcValue import PlcValue
 
diff --git a/plc4py/plc4py/spi/transport/MockTransport.py b/plc4py/plc4py/spi/transport/MockTransport.py
index e0a740e866..05c4c78c55 100644
--- a/plc4py/plc4py/spi/transport/MockTransport.py
+++ b/plc4py/plc4py/spi/transport/MockTransport.py
@@ -20,9 +20,13 @@ import asyncio
 import logging
 from asyncio import Protocol
 from dataclasses import dataclass
-from typing import Callable
+from typing import Callable, Type
 
 from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
+import plc4py
+from plc4py.spi.transport.PlcTransportLoader import PlcTransportLoader
+
+from plc4py.spi.transport.TCPTransport import TCPTransport
 
 
 @dataclass
@@ -45,3 +49,19 @@ class MockTransport(Plc4xBaseTransport):
         protocol_factory: Callable[[], Protocol], host: str, port: int
     ) -> Plc4xBaseTransport:
         return MockTransport(None, None, host, port)
+
+
+class MockTransportLoader(PlcTransportLoader):
+    """
+    Umas Driver Pluggy Hook Implementation, lets pluggy find the driver by name
+    """
+
+    @staticmethod
+    @plc4py.spi.transport.hookimpl
+    def get_transport() -> Type[MockTransport]:
+        return MockTransport
+
+    @staticmethod
+    @plc4py.spi.transport.hookimpl
+    def key() -> str:
+        return "mock"
diff --git a/plc4py/plc4py/spi/transport/Plc4xBaseTransport.py b/plc4py/plc4py/spi/transport/Plc4xBaseTransport.py
index 71b649b165..10b9060540 100644
--- a/plc4py/plc4py/spi/transport/Plc4xBaseTransport.py
+++ b/plc4py/plc4py/spi/transport/Plc4xBaseTransport.py
@@ -19,7 +19,7 @@
 
 from __future__ import annotations
 
-from asyncio import Transport, BaseTransport, BaseProtocol
+from asyncio import BaseProtocol, BaseTransport, Transport
 from dataclasses import dataclass
 
 
diff --git a/plc4py/plc4py/spi/transport/PlcTransportLoader.py b/plc4py/plc4py/spi/transport/PlcTransportLoader.py
new file mode 100644
index 0000000000..2149b492ef
--- /dev/null
+++ b/plc4py/plc4py/spi/transport/PlcTransportLoader.py
@@ -0,0 +1,36 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+from abc import abstractmethod
+from typing import Type
+
+from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
+
+
+class PlcTransportLoader:
+    """Hook spec for PLC4PY Transport Loaders"""
+
+    @staticmethod
+    @abstractmethod
+    def get_transport() -> Type[Plc4xBaseTransport]:
+        """Returns the PlcConnection class that is used to instantiate the transport"""
+        pass
+
+    @staticmethod
+    @abstractmethod
+    def key() -> str:
+        """Unique key to identify the transport"""
+        pass
diff --git a/plc4py/plc4py/spi/transport/TCPTransport.py b/plc4py/plc4py/spi/transport/TCPTransport.py
index 62422ec213..fbb275098b 100644
--- a/plc4py/plc4py/spi/transport/TCPTransport.py
+++ b/plc4py/plc4py/spi/transport/TCPTransport.py
@@ -19,9 +19,11 @@
 import asyncio
 from asyncio import Protocol
 from dataclasses import dataclass
-from typing import Callable
+from typing import Callable, Type
 
+import plc4py
 from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
+from plc4py.spi.transport.PlcTransportLoader import PlcTransportLoader
 
 
 @dataclass
@@ -44,3 +46,19 @@ class TCPTransport(Plc4xBaseTransport):
         coro = loop.create_connection(protocol_factory, host, port)
         _transport, _protocol = await coro
         return TCPTransport(_transport, _protocol, host, port)
+
+
+class TCPTransportLoader(PlcTransportLoader):
+    """
+    Umas Driver Pluggy Hook Implementation, lets pluggy find the driver by name
+    """
+
+    @staticmethod
+    @plc4py.spi.transport.hookimpl
+    def get_transport() -> Type[TCPTransport]:
+        return TCPTransport
+
+    @staticmethod
+    @plc4py.spi.transport.hookimpl
+    def key() -> str:
+        return "tcp"
diff --git a/plc4py/plc4py/spi/transport/__init__.py b/plc4py/plc4py/spi/transport/__init__.py
index 342be71799..6919c7a9c1 100644
--- a/plc4py/plc4py/spi/transport/__init__.py
+++ b/plc4py/plc4py/spi/transport/__init__.py
@@ -16,3 +16,7 @@
 # specific language governing permissions and limitations
 # under the License.
 #
+
+import pluggy  # type: ignore
+
+hookimpl = pluggy.HookimplMarker("plc4py.transports")
diff --git a/plc4py/plc4py/spi/values/Common.py b/plc4py/plc4py/spi/values/Common.py
index ee3d6324a1..6cc1ad0d3c 100644
--- a/plc4py/plc4py/spi/values/Common.py
+++ b/plc4py/plc4py/spi/values/Common.py
@@ -20,7 +20,6 @@ from abc import abstractmethod
 
 
 class Serializable:
-
     @abstractmethod
     def serialize(self, write_buffer):
         """Serialize an object to the WriteBuffer provided.
@@ -28,3 +27,10 @@ class Serializable:
         :param write_buffer: The WriteBuffer to serialize to
         """
         pass
+
+
+def get_size_of_array(items) -> int:
+    result = 0
+    for i in items:
+        result += i.length_in_bytes()
+    return result
diff --git a/plc4py/plc4py/spi/values/PlcValues.py b/plc4py/plc4py/spi/values/PlcValues.py
index 3744b805a6..d2c44e78c2 100644
--- a/plc4py/plc4py/spi/values/PlcValues.py
+++ b/plc4py/plc4py/spi/values/PlcValues.py
@@ -17,7 +17,7 @@
 # under the License.
 #
 from dataclasses import dataclass
-from typing import List, Any, Dict
+from typing import Any, Dict, List
 
 from plc4py.api.value.PlcValue import PlcValue
 
diff --git a/plc4py/setup.py b/plc4py/setup.py
index 82bf257669..f245afe23f 100644
--- a/plc4py/setup.py
+++ b/plc4py/setup.py
@@ -56,6 +56,7 @@ setup(
             "mypy>=0.942",
             "flake8>=4.0.1",
             "pytest-asyncio",
+            "xsdata",
         ]
     },
     entry_points={
@@ -63,6 +64,10 @@ setup(
             "mock = plc4py.drivers.mock.MockConnection:MockDriverLoader",
             "modbus = plc4py.drivers.modbus.ModbusConnection:ModbusDriverLoader",
             "umas = plc4py.drivers.umas.UmasConnection:UmasDriverLoader",
-        ]
+        ],
+        "plc4py.transports": [
+            "tcp = plc4py.spi.transport.TCPTransport:TCPTransportLoader",
+            "mock = plc4py.spi.transport.MockTransport:MockTransportLoader",
+        ],
     },
 )
diff --git a/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_connection.py b/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_connection.py
index 328f699a77..1fd9c49e6c 100644
--- a/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_connection.py
+++ b/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_connection.py
@@ -67,6 +67,6 @@ async def test_plc_driver_modbus_read():
 
             response = await future
             value = response.tags["Random Tag"].value
-            log.error("Read tag 4x00001[10] - %s", value)
+            log.info("Read tag 4x00001[10] - %s", value)
 
     pass
diff --git a/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_parser_serializer.py b/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_parser_serializer.py
new file mode 100644
index 0000000000..6ae3d7f1ec
--- /dev/null
+++ b/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_parser_serializer.py
@@ -0,0 +1,54 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+import os
+
+import pytest
+
+from ...utils.ParserSerializerTestSuiteRunner import ParserSerializerTestsuiteRunner
+
+
+def pytest_generate_tests(metafunc):
+    path: str = os.path.join(
+        os.path.dirname(__file__),
+        "..",
+        "..",
+        "..",
+        "..",
+        "..",
+        "..",
+        "protocols",
+        "modbus",
+        "src",
+        "test",
+        "resources",
+        "protocols",
+        "modbus",
+        "tcp",
+        "ParserSerializerTestsuite.xml",
+    )
+    xml_loader = ParserSerializerTestsuiteRunner(path)
+
+    test_suites = xml_loader.test_suite_tests
+
+    metafunc.parametrize(
+        "test_case", test_suites, ids=[test_case.name for test_case in test_suites]
+    )
+
+
+@pytest.mark.asyncio
+async def test_parse_serializer_parse_xml_test(test_case) -> None:
+    test_case.runTest()
diff --git a/plc4py/tests/unit/plc4py/utils/ParserSerializerTestSuiteRunner.py b/plc4py/tests/unit/plc4py/utils/ParserSerializerTestSuiteRunner.py
new file mode 100644
index 0000000000..1f1599dc92
--- /dev/null
+++ b/plc4py/tests/unit/plc4py/utils/ParserSerializerTestSuiteRunner.py
@@ -0,0 +1,87 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+import logging
+import unittest
+from abc import ABC, abstractmethod
+from dataclasses import dataclass, field
+from typing import List, Iterator, Any
+from xml.etree import ElementTree
+
+from xsdata.formats.dataclass.parsers import XmlParser
+
+from .XmlTestSuiteLoader import (
+    ParserSerializerTestCase,
+)
+from .generated.parser_serializer_testsuite import Testsuite
+
+logger = logging.getLogger(__name__)
+
+
+@dataclass
+class XmlTestSuiteLoader(unittest.TestLoader, ABC):
+    # Parent class for test suites utilizing XML as representation mechanism.
+    # <p>
+    # It adds handling of resource loading and helps in navigating test framework to suite source files.
+    #
+
+    test_suite_document: str
+    test_suite_document_xml: Iterator[tuple[str, Any]] = field(init=False)
+
+    def __post_init__(self) -> None:
+        # ElementTree.register_namespace('test', 'https://plc4x.apache.org/schemas/driver-testsuite.xsd')
+        self.test_suite_document_xml = ElementTree.iterparse(
+            self.test_suite_document, events=(["start"])
+        )
+
+    @abstractmethod
+    def test_suite_tests(self) -> List[unittest.TestCase]:
+        # Get a list of test cases
+        pass
+
+
+@dataclass
+class ParserSerializerTestsuiteRunner(XmlTestSuiteLoader):
+    test_suite_document: str
+    auto_migrate: bool = (
+        False  # if set to true if will automigrate and on the next run test should be green
+    )
+    ignored_test_cases: List[str] = field(default_factory=list)
+
+    @property
+    def test_suite_tests(self) -> List[unittest.TestCase]:
+        parser = XmlParser()
+        test_suite_xml = parser.parse(self.test_suite_document, Testsuite)
+
+        dynamic_tests: List[unittest.TestCase] = []
+        for test_case in test_suite_xml.testcase:
+            if not test_case.name in self.ignored_test_cases:
+                test_suite = ParserSerializerTestCase()
+                test_suite.add_test_case(test_case)
+                test_suite.add_test_suite(test_suite_xml)
+                test_suite.add_migrate(self.auto_migrate)
+                dynamic_tests.append(test_suite)
+        logger.info("Found %s testcases.", len(test_suite_xml.testcase))
+        return dynamic_tests
diff --git a/plc4py/tests/unit/plc4py/utils/XmlTestSuiteLoader.py b/plc4py/tests/unit/plc4py/utils/XmlTestSuiteLoader.py
new file mode 100644
index 0000000000..345418fb25
--- /dev/null
+++ b/plc4py/tests/unit/plc4py/utils/XmlTestSuiteLoader.py
@@ -0,0 +1,146 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+import importlib
+import logging
+import unittest
+from abc import ABC, abstractmethod
+from dataclasses import dataclass, field
+from typing import Any, Iterator, List
+from unittest import TestCase
+from xml.etree import ElementTree
+
+from bitarray.util import ba2hex
+from xsdata.formats.dataclass.serializers import XmlSerializer
+from xsdata.formats.dataclass.serializers.config import SerializerConfig
+from xsdata.utils.text import snake_case
+
+from plc4py.api.exceptions.exceptions import SerializationException
+from plc4py.spi.generation.ReadBuffer import ReadBufferByteBased
+from plc4py.spi.generation.WriteBuffer import WriteBufferXmlBased, WriteBufferByteBased
+
+logger = logging.getLogger(__name__)
+
+
+class ParserSerializerTestCase(TestCase):
+
+    def __init__(self, methodName="runTest"):
+        super().__init__(methodName)
+        self.name = None
+        self.test_case = None
+        self.test_suite = None
+        self.migrate = False
+
+    def add_test_case(self, test_case):
+        self.test_case = test_case
+        self.name = test_case.name
+
+    def add_test_suite(self, test_suite):
+        self.test_suite = test_suite
+
+    def add_migrate(self, migrate: bool):
+        self.migrate = migrate
+
+    def runTest(self):
+        logger.info("Running testcases %s", self.test_case.name)
+        test_case_raw = self.test_case.raw
+        logger.debug(test_case_raw.hex())
+
+        """ 
+            Parse the raw bytes and generate to plc4py class 
+        """
+        read_buffer = ReadBufferByteBased(test_case_raw, self.test_suite.byte_order)
+        try:
+            protocol_name = self.test_suite.protocol_name
+            output_flavor = self.test_suite.output_flavor.replace("-", "")
+            root_type = self.test_case.root_type
+            imported_module = importlib.import_module(
+                f"plc4py.protocols.{protocol_name}.{output_flavor}.{root_type}",
+                package="plc4py",
+            )
+        except ModuleNotFoundError as e:
+            logging.exception(
+                "Failed to find plc4py class for %s %s",
+                self.test_suite.protocol_name,
+                e,
+            )
+            raise e
+
+        logger.debug("Parsing message")
+        uninstantiated_class = getattr(imported_module, root_type)
+        kwargs = {
+            snake_case(element.qname): element.text
+            for element in self.test_case.parser_arguments.local_element
+        }
+        modbus_adu = uninstantiated_class.static_parse_context(read_buffer, **kwargs)
+
+        """ 
+            Serialize the Model back to the raw bytes for comparison 
+        """
+        byte_buffer: WriteBufferByteBased = WriteBufferByteBased(
+            size=len(self.test_case.raw), byte_order=self.test_suite.byte_order
+        )
+        modbus_adu.serialize(byte_buffer)
+
+        comparison = self.test_case.raw == byte_buffer.get_bytes()
+        if not comparison:
+
+            """
+            Serialize generate class to xml
+            """
+            exception: SerializationException = SerializationException()
+            exception.add_note(
+                "---------------------Failed Assertion------------------"
+            )
+            xml_buffer: WriteBufferXmlBased = WriteBufferXmlBased()
+            modbus_adu.serialize(xml_buffer)
+            result = xml_buffer.to_xml_string()
+
+            exception.add_note("")
+            exception.add_note(
+                "---------------------Initial Raw Bytes-----------------"
+            )
+            exception.add_note(self.test_case.raw.hex())
+            exception.add_note("")
+            exception.add_note(
+                "---------------------Serialized Raw Bytes from Model---"
+            )
+            exception.add_note(ba2hex(byte_buffer.bb))
+            exception.add_note("")
+            exception.add_note(
+                "---------------------Initial XML Case------------------"
+            )
+            """
+                Serialize the model back to xml for user comparison
+            """
+            factory = SerializerConfig(xml_declaration=False, pretty_print=True)
+            serializer = XmlSerializer(config=factory)
+            ss = serializer.render(self.test_case.xml)
+            exception.add_note(ss)
+            exception.add_note("")
+
+            exception.add_note("---------------------Serialized XML case--------------")
+            exception.add_note(result)
+            raise exception
diff --git a/plc4py/tests/unit/plc4py/utils/__init__.py b/plc4py/tests/unit/plc4py/utils/__init__.py
new file mode 100644
index 0000000000..a67d5ea255
--- /dev/null
+++ b/plc4py/tests/unit/plc4py/utils/__init__.py
@@ -0,0 +1,16 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
diff --git a/plc4py/tests/unit/plc4py/utils/generated/__init__.py b/plc4py/tests/unit/plc4py/utils/generated/__init__.py
new file mode 100644
index 0000000000..a67d5ea255
--- /dev/null
+++ b/plc4py/tests/unit/plc4py/utils/generated/__init__.py
@@ -0,0 +1,16 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
diff --git a/plc4py/tests/unit/plc4py/utils/generated/driver_testsuite.py b/plc4py/tests/unit/plc4py/utils/generated/driver_testsuite.py
new file mode 100644
index 0000000000..7ab4992180
--- /dev/null
+++ b/plc4py/tests/unit/plc4py/utils/generated/driver_testsuite.py
@@ -0,0 +1,447 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+from dataclasses import dataclass, field
+from enum import Enum
+from typing import List, Optional
+
+__NAMESPACE__ = "https://plc4x.apache.org/schemas/driver-testsuite.xsd"
+
+
+class ByteOrder(Enum):
+    BIG_ENDIAN = "BIG_ENDIAN"
+    LITTLE_ENDIAN = "LITTLE_ENDIAN"
+
+
+@dataclass
+class BytesStep:
+    class Meta:
+        name = "bytesStep"
+
+    value: Optional[bytes] = field(
+        default=None,
+        metadata={
+            "required": True,
+            "format": "base16",
+        },
+    )
+    name: Optional[str] = field(
+        default=None,
+        metadata={
+            "type": "Attribute",
+        },
+    )
+
+
+@dataclass
+class MessageStep:
+    class Meta:
+        name = "messageStep"
+
+    any_element: Optional[object] = field(
+        default=None,
+        metadata={
+            "type": "Wildcard",
+            "namespace": "##any",
+        },
+    )
+    name: Optional[str] = field(
+        default=None,
+        metadata={
+            "type": "Attribute",
+        },
+    )
+
+
+@dataclass
+class ParameterList:
+    class Meta:
+        name = "parameterList"
+
+    parameter: List["ParameterList.Parameter"] = field(
+        default_factory=list,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+            "min_occurs": 1,
+        },
+    )
+
+    @dataclass
+    class Parameter:
+        name: Optional[str] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "required": True,
+            },
+        )
+        value: Optional[str] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+            },
+        )
+
+
+@dataclass
+class DriverTestsuite:
+    """
+    :ivar name:
+    :ivar protocol_name:
+    :ivar output_flavor:
+    :ivar options: List of options which are specific to execution of
+        test or environment. This might be used ie. to influence test
+        framework lookup strategies.
+    :ivar driver_name:
+    :ivar driver_parameters:
+    :ivar setup:
+    :ivar teardown:
+    :ivar testcase:
+    :ivar byte_order:
+    """
+
+    class Meta:
+        name = "driver-testsuite"
+        namespace = "https://plc4x.apache.org/schemas/driver-testsuite.xsd"
+
+    name: Optional[str] = field(
+        default=None,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+            "required": True,
+        },
+    )
+    protocol_name: Optional[str] = field(
+        default=None,
+        metadata={
+            "name": "protocolName",
+            "type": "Element",
+            "namespace": "",
+            "required": True,
+        },
+    )
+    output_flavor: Optional[str] = field(
+        default=None,
+        metadata={
+            "name": "outputFlavor",
+            "type": "Element",
+            "namespace": "",
+            "required": True,
+        },
+    )
+    options: Optional[ParameterList] = field(
+        default=None,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+        },
+    )
+    driver_name: Optional[str] = field(
+        default=None,
+        metadata={
+            "name": "driver-name",
+            "type": "Element",
+            "namespace": "",
+            "required": True,
+        },
+    )
+    driver_parameters: Optional[ParameterList] = field(
+        default=None,
+        metadata={
+            "name": "driver-parameters",
+            "type": "Element",
+            "namespace": "",
+        },
+    )
+    setup: Optional["DriverTestsuite.Setup"] = field(
+        default=None,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+        },
+    )
+    teardown: Optional["DriverTestsuite.Teardown"] = field(
+        default=None,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+        },
+    )
+    testcase: List["DriverTestsuite.Testcase"] = field(
+        default_factory=list,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+            "min_occurs": 1,
+        },
+    )
+    byte_order: Optional[ByteOrder] = field(
+        default=None,
+        metadata={
+            "name": "byteOrder",
+            "type": "Attribute",
+        },
+    )
+
+    @dataclass
+    class Setup:
+        outgoing_plc_message: List[MessageStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "outgoing-plc-message",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        outgoing_plc_bytes: List[BytesStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "outgoing-plc-bytes",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        incoming_plc_message: List[MessageStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "incoming-plc-message",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        incoming_plc_bytes: List[BytesStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "incoming-plc-bytes",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        api_request: List[MessageStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "api-request",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        api_response: List[MessageStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "api-response",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        delay: List[int] = field(
+            default_factory=list,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        terminate: List[object] = field(
+            default_factory=list,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+
+    @dataclass
+    class Teardown:
+        outgoing_plc_message: List[MessageStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "outgoing-plc-message",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        outgoing_plc_bytes: List[BytesStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "outgoing-plc-bytes",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        incoming_plc_message: List[MessageStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "incoming-plc-message",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        incoming_plc_bytes: List[BytesStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "incoming-plc-bytes",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        api_request: List[MessageStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "api-request",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        api_response: List[MessageStep] = field(
+            default_factory=list,
+            metadata={
+                "name": "api-response",
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        delay: List[int] = field(
+            default_factory=list,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+        terminate: List[object] = field(
+            default_factory=list,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "sequence": 1,
+            },
+        )
+
+    @dataclass
+    class Testcase:
+        name: Optional[str] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "required": True,
+            },
+        )
+        description: Optional[str] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+            },
+        )
+        steps: Optional["DriverTestsuite.Testcase.Steps"] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "required": True,
+            },
+        )
+
+        @dataclass
+        class Steps:
+            outgoing_plc_message: List[MessageStep] = field(
+                default_factory=list,
+                metadata={
+                    "name": "outgoing-plc-message",
+                    "type": "Element",
+                    "namespace": "",
+                    "sequence": 1,
+                },
+            )
+            outgoing_plc_bytes: List[BytesStep] = field(
+                default_factory=list,
+                metadata={
+                    "name": "outgoing-plc-bytes",
+                    "type": "Element",
+                    "namespace": "",
+                    "sequence": 1,
+                },
+            )
+            incoming_plc_message: List[MessageStep] = field(
+                default_factory=list,
+                metadata={
+                    "name": "incoming-plc-message",
+                    "type": "Element",
+                    "namespace": "",
+                    "sequence": 1,
+                },
+            )
+            incoming_plc_bytes: List[BytesStep] = field(
+                default_factory=list,
+                metadata={
+                    "name": "incoming-plc-bytes",
+                    "type": "Element",
+                    "namespace": "",
+                    "sequence": 1,
+                },
+            )
+            api_request: List[MessageStep] = field(
+                default_factory=list,
+                metadata={
+                    "name": "api-request",
+                    "type": "Element",
+                    "namespace": "",
+                    "sequence": 1,
+                },
+            )
+            api_response: List[MessageStep] = field(
+                default_factory=list,
+                metadata={
+                    "name": "api-response",
+                    "type": "Element",
+                    "namespace": "",
+                    "sequence": 1,
+                },
+            )
+            delay: List[int] = field(
+                default_factory=list,
+                metadata={
+                    "type": "Element",
+                    "namespace": "",
+                    "sequence": 1,
+                },
+            )
+            terminate: List[object] = field(
+                default_factory=list,
+                metadata={
+                    "type": "Element",
+                    "namespace": "",
+                    "sequence": 1,
+                },
+            )
diff --git a/plc4py/tests/unit/plc4py/utils/generated/parser_serializer_testsuite.py b/plc4py/tests/unit/plc4py/utils/generated/parser_serializer_testsuite.py
new file mode 100644
index 0000000000..0164b30b9c
--- /dev/null
+++ b/plc4py/tests/unit/plc4py/utils/generated/parser_serializer_testsuite.py
@@ -0,0 +1,188 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+from dataclasses import dataclass, field
+from enum import Enum
+from typing import List, Optional
+
+__NAMESPACE__ = "https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd"
+
+
+class ByteOrder(Enum):
+    BIG_ENDIAN = "BIG_ENDIAN"
+    LITTLE_ENDIAN = "LITTLE_ENDIAN"
+
+
+@dataclass
+class ParameterList:
+    class Meta:
+        name = "parameterList"
+
+    parameter: List["ParameterList.Parameter"] = field(
+        default_factory=list,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+            "min_occurs": 1,
+        },
+    )
+
+    @dataclass
+    class Parameter:
+        name: Optional[str] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "required": True,
+            },
+        )
+        value: Optional[str] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+            },
+        )
+
+
+@dataclass
+class Testsuite:
+    """
+    :ivar name:
+    :ivar protocol_name:
+    :ivar output_flavor:
+    :ivar options: List of options which are specific to execution of
+        test or environment. This might be used ie. to influence test
+        framework lookup strategies.
+    :ivar testcase:
+    :ivar byte_order:
+    """
+
+    class Meta:
+        name = "testsuite"
+        namespace = "https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd"
+
+    name: Optional[str] = field(
+        default=None,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+            "required": True,
+        },
+    )
+    protocol_name: Optional[str] = field(
+        default=None,
+        metadata={
+            "name": "protocolName",
+            "type": "Element",
+            "namespace": "",
+            "required": True,
+        },
+    )
+    output_flavor: Optional[str] = field(
+        default=None,
+        metadata={
+            "name": "outputFlavor",
+            "type": "Element",
+            "namespace": "",
+            "required": True,
+        },
+    )
+    options: Optional[ParameterList] = field(
+        default=None,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+        },
+    )
+    testcase: List["Testsuite.Testcase"] = field(
+        default_factory=list,
+        metadata={
+            "type": "Element",
+            "namespace": "",
+            "min_occurs": 1,
+        },
+    )
+    byte_order: Optional[ByteOrder] = field(
+        default=None,
+        metadata={
+            "name": "byteOrder",
+            "type": "Attribute",
+        },
+    )
+
+    @dataclass
+    class Testcase:
+        name: Optional[str] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "required": True,
+            },
+        )
+        description: Optional[str] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+            },
+        )
+        raw: Optional[bytes] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+                "required": True,
+                "format": "base16",
+            },
+        )
+        root_type: Optional[str] = field(
+            default=None,
+            metadata={
+                "name": "root-type",
+                "type": "Element",
+                "namespace": "",
+                "required": True,
+            },
+        )
+        parser_arguments: Optional["Testsuite.Testcase.ParserArguments"] = field(
+            default=None,
+            metadata={
+                "name": "parser-arguments",
+                "type": "Element",
+                "namespace": "",
+            },
+        )
+        xml: Optional[object] = field(
+            default=None,
+            metadata={
+                "type": "Element",
+                "namespace": "",
+            },
+        )
+
+        @dataclass
+        class ParserArguments:
+            local_element: List[object] = field(
+                default_factory=list,
+                metadata={
+                    "type": "Wildcard",
+                    "namespace": "##local",
+                },
+            )