You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2023/06/13 14:56:26 UTC

[plc4x] 03/03: refactor(plc4go): use generated Stringers instead of hand written ones

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

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

commit 3aa66052aa5bfd401ca8bfa103da828bd8aee380
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Tue Jun 13 16:56:13 2023 +0200

    refactor(plc4go): use generated Stringers instead of hand written ones
---
 plc4go/internal/ads/Connection.go                  |   4 +-
 plc4go/internal/bacnetip/Connection.go             |   4 +-
 plc4go/internal/cbus/AlphaGenerator_plc4xgen.go    |  61 ++++
 plc4go/internal/cbus/Configuration.go              |   6 +-
 plc4go/internal/cbus/Configuration_plc4xgen.go     | 105 ++++++
 plc4go/internal/cbus/Configuration_test.go         |  10 +-
 plc4go/internal/cbus/Connection.go                 |  44 +--
 plc4go/internal/cbus/Connection_plc4xgen.go        | 149 +++++++++
 plc4go/internal/cbus/Connection_test.go            |  89 +++--
 plc4go/internal/cbus/DriverContext.go              |   7 +-
 plc4go/internal/cbus/DriverContext_plc4xgen.go     |  65 ++++
 plc4go/internal/cbus/MessageCodec.go               |  24 +-
 plc4go/internal/cbus/MessageCodec_plc4xgen.go      | 126 +++++++
 plc4go/internal/cbus/MessageCodec_test.go          |  38 ++-
 plc4go/internal/cbus/Subscriber.go                 |   9 +-
 plc4go/internal/cbus/Subscriber_plc4xgen.go        |  61 ++++
 plc4go/internal/eip/Connection.go                  |   4 +-
 plc4go/internal/knxnetip/Connection.go             |   4 +-
 plc4go/internal/modbus/Connection.go               |   4 +-
 plc4go/internal/s7/Connection.go                   |   4 +-
 plc4go/internal/simulated/Connection.go            |   4 +-
 plc4go/internal/simulated/Reader.go                |   4 +-
 plc4go/internal/simulated/Subscriber.go            |   4 +-
 plc4go/internal/simulated/Writer.go                |   4 +-
 plc4go/pkg/api/cache/PlcConnectionCache.go         |   4 +-
 .../pkg/api/cache/mock_tracedPlcConnection_test.go |  12 +-
 plc4go/pkg/api/cache/plcConnectionLease.go         |   2 +-
 plc4go/pkg/api/cache/tracedPlcConnection.go        |   2 +-
 plc4go/spi/default/DefaultCodec.go                 |  22 +-
 plc4go/spi/default/DefaultCodec_test.go            |  39 ++-
 plc4go/spi/default/DefaultConnection.go            |  24 +-
 plc4go/spi/default/DefaultConnection_test.go       |  17 +-
 .../defaultCodec_plc4xgen.go}                      |  50 +--
 .../defaultConnection_plc4xgen.go}                 |  52 +--
 plc4go/spi/default/mock_DefaultCodec_test.go       |  98 ++++++
 plc4go/spi/default/mock_DefaultConnection_test.go  |  98 ++++++
 plc4go/spi/default/mock_Expectation_test.go        | 313 ++++++++++++++++++
 plc4go/spi/default/mock_requirements.go            |   5 +
 .../DefaultPlcBrowseRequestResult_plc4xgen.go      |   3 +-
 .../DefaultPlcConsumerRegistration_plc4xgen.go     |   3 +-
 .../model/DefaultPlcReadRequestResult_plc4xgen.go  |   3 +-
 .../DefaultPlcSubscriptionEventItem_plc4xgen.go    |   8 +-
 ...DefaultPlcSubscriptionRequestResult_plc4xgen.go |   3 +-
 ...faultPlcUnsubscriptionRequestResult_plc4xgen.go |   3 +-
 .../model/DefaultPlcWriteRequestResult_plc4xgen.go |   3 +-
 plc4go/spi/pool/WorkerPool.go                      |   5 +
 plc4go/spi/pool/dynamicExecutor.go                 |  14 +-
 plc4go/spi/pool/dynamicExecutor_plc4xgen.go        |  73 +++++
 plc4go/spi/pool/dynamicExecutor_test.go            |  38 ++-
 plc4go/spi/pool/executor.go                        |  22 +-
 .../executor_plc4xgen.go}                          |  55 ++--
 plc4go/spi/pool/executor_test.go                   |  29 +-
 plc4go/spi/pool/{CompletionFuture.go => future.go} |  23 +-
 .../future_plc4xgen.go}                            |  63 ++--
 .../{CompletionFuture_test.go => future_test.go}   |   7 +-
 plc4go/spi/pool/workItem.go                        |  17 +-
 plc4go/spi/pool/workItem_plc4xgen.go               |  68 ++++
 plc4go/spi/pool/workItem_test.go                   |  18 +-
 plc4go/spi/pool/worker.go                          |  22 +-
 plc4go/spi/pool/worker_plc4xgen.go                 |  82 +++++
 plc4go/spi/pool/worker_test.go                     |   7 +-
 plc4go/spi/tracer/Tracer.go                        |  43 ++-
 plc4go/spi/tracer/Tracer_test.go                   |  36 +-
 plc4go/spi/tracer/mock_Tracer_test.go              | 361 +++++++++++++++++++++
 plc4go/spi/transactions/RequestTransaction.go      |  11 +-
 .../spi/transactions/RequestTransactionManager.go  |  28 +-
 .../transactions/RequestTransactionManager_test.go |  47 +--
 plc4go/spi/transactions/RequestTransaction_test.go |   9 +-
 plc4go/spi/transactions/completedFuture.go         |  10 +-
 .../spi/transactions/completedFuture_plc4xgen.go   |  64 ++++
 plc4go/spi/transactions/completedFuture_test.go    |  15 +-
 .../requestTransactionManager_plc4xgen.go}         |  79 +++--
 .../requestTransaction_plc4xgen.go}                |  51 +--
 plc4go/tools/plc4xgenerator/gen.go                 |   3 +-
 74 files changed, 2285 insertions(+), 613 deletions(-)

diff --git a/plc4go/internal/ads/Connection.go b/plc4go/internal/ads/Connection.go
index f48364f943..ef02522567 100644
--- a/plc4go/internal/ads/Connection.go
+++ b/plc4go/internal/ads/Connection.go
@@ -52,7 +52,7 @@ type Connection struct {
 	requestInterceptor interceptors.RequestInterceptor
 	configuration      model.Configuration
 	driverContext      *DriverContext
-	tracer             *tracer.Tracer
+	tracer             tracer.Tracer
 
 	subscriptions map[uint32]apiModel.PlcSubscriptionHandle
 
@@ -96,7 +96,7 @@ func (m *Connection) IsTraceEnabled() bool {
 	return m.tracer != nil
 }
 
-func (m *Connection) GetTracer() *tracer.Tracer {
+func (m *Connection) GetTracer() tracer.Tracer {
 	return m.tracer
 }
 
diff --git a/plc4go/internal/bacnetip/Connection.go b/plc4go/internal/bacnetip/Connection.go
index 049a5c9bb4..7d74e45101 100644
--- a/plc4go/internal/bacnetip/Connection.go
+++ b/plc4go/internal/bacnetip/Connection.go
@@ -48,7 +48,7 @@ type Connection struct {
 	tm                transactions.RequestTransactionManager
 
 	connectionId string
-	tracer       *tracer.Tracer
+	tracer       tracer.Tracer
 
 	log zerolog.Logger
 }
@@ -80,7 +80,7 @@ func (c *Connection) IsTraceEnabled() bool {
 	return c.tracer != nil
 }
 
-func (c *Connection) GetTracer() *tracer.Tracer {
+func (c *Connection) GetTracer() tracer.Tracer {
 	return c.tracer
 }
 
diff --git a/plc4go/internal/cbus/AlphaGenerator_plc4xgen.go b/plc4go/internal/cbus/AlphaGenerator_plc4xgen.go
new file mode 100644
index 0000000000..23c5ee03a6
--- /dev/null
+++ b/plc4go/internal/cbus/AlphaGenerator_plc4xgen.go
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=AlphaGenerator"; DO NOT EDIT.
+
+package cbus
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *AlphaGenerator) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *AlphaGenerator) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("AlphaGenerator"); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteByte("currentAlpha", d.currentAlpha); err != nil {
+		return err
+	}
+	if err := writeBuffer.PopContext("AlphaGenerator"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *AlphaGenerator) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/internal/cbus/Configuration.go b/plc4go/internal/cbus/Configuration.go
index bd02271184..10dc280f6c 100644
--- a/plc4go/internal/cbus/Configuration.go
+++ b/plc4go/internal/cbus/Configuration.go
@@ -20,7 +20,6 @@
 package cbus
 
 import (
-	"fmt"
 	"github.com/rs/zerolog"
 	"reflect"
 	"strconv"
@@ -28,6 +27,7 @@ import (
 	"github.com/pkg/errors"
 )
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=Configuration
 type Configuration struct {
 	Srchk    bool
 	Exstat   bool
@@ -99,7 +99,3 @@ func getFromOptions(localLog zerolog.Logger, options map[string][]string, key st
 	}
 	return ""
 }
-
-func (c Configuration) String() string {
-	return fmt.Sprintf("%#v", c)
-}
diff --git a/plc4go/internal/cbus/Configuration_plc4xgen.go b/plc4go/internal/cbus/Configuration_plc4xgen.go
new file mode 100644
index 0000000000..9bbb4658e5
--- /dev/null
+++ b/plc4go/internal/cbus/Configuration_plc4xgen.go
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=Configuration"; DO NOT EDIT.
+
+package cbus
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *Configuration) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *Configuration) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("Configuration"); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("srchk", d.Srchk); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("exstat", d.Exstat); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("pun", d.Pun); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("localSal", d.LocalSal); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("pcn", d.Pcn); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("idmon", d.Idmon); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("monitor", d.Monitor); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("smart", d.Smart); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("xonXoff", d.XonXoff); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("connect", d.Connect); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteByte("monitoredApplication1", d.MonitoredApplication1); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteByte("monitoredApplication2", d.MonitoredApplication2); err != nil {
+		return err
+	}
+	if err := writeBuffer.PopContext("Configuration"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *Configuration) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/internal/cbus/Configuration_test.go b/plc4go/internal/cbus/Configuration_test.go
index 17779239a8..9160600426 100644
--- a/plc4go/internal/cbus/Configuration_test.go
+++ b/plc4go/internal/cbus/Configuration_test.go
@@ -238,7 +238,15 @@ func TestConfiguration_String(t *testing.T) {
 				MonitoredApplication1: 2,
 				MonitoredApplication2: 3,
 			},
-			want: "cbus.Configuration{Srchk:true, Exstat:true, Pun:true, LocalSal:true, Pcn:true, Idmon:true, Monitor:true, Smart:true, XonXoff:true, Connect:true, MonitoredApplication1:0x2, MonitoredApplication2:0x3}",
+			want: `
+╔═Configuration═════════════════════════════════════════════════════════════════════════════════╗
+║╔═srchk═╗╔═exstat╗╔═pun═══╗╔═localSal╗╔═pcn═══╗╔═idmon═╗╔═monitor╗╔═smart═╗╔═xonXoff╗╔═connect╗║
+║║b1 true║║b1 true║║b1 true║║ b1 true ║║b1 true║║b1 true║║b1 true ║║b1 true║║b1 true ║║b1 true ║║
+║╚═══════╝╚═══════╝╚═══════╝╚═════════╝╚═══════╝╚═══════╝╚════════╝╚═══════╝╚════════╝╚════════╝║
+║╔═monitoredApplication1╗╔═monitoredApplication2╗                                               ║
+║║       0x02 '.'       ║║       0x03 '.'       ║                                               ║
+║╚══════════════════════╝╚══════════════════════╝                                               ║
+╚═══════════════════════════════════════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/internal/cbus/Connection.go b/plc4go/internal/cbus/Connection.go
index 393007d21c..d8c0e872c1 100644
--- a/plc4go/internal/cbus/Connection.go
+++ b/plc4go/internal/cbus/Connection.go
@@ -21,7 +21,6 @@ package cbus
 
 import (
 	"context"
-	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/options"
 	"github.com/apache/plc4x/plc4go/spi/tracer"
 	"github.com/apache/plc4x/plc4go/spi/transactions"
@@ -41,6 +40,7 @@ import (
 	"github.com/pkg/errors"
 )
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=AlphaGenerator
 type AlphaGenerator struct {
 	currentAlpha byte
 	lock         sync.Mutex
@@ -58,24 +58,21 @@ func (t *AlphaGenerator) getAndIncrement() byte {
 	return result
 }
 
-func (t *AlphaGenerator) String() string {
-	return fmt.Sprintf("AlphaGenerator(currentAlpha: %c)", t.currentAlpha)
-}
-
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=Connection
 type Connection struct {
 	_default.DefaultConnection
-	alphaGenerator AlphaGenerator
+	alphaGenerator AlphaGenerator `stringer:"true"`
 	messageCodec   *MessageCodec
 	subscribers    []*Subscriber
 	tm             transactions.RequestTransactionManager
 
-	configuration Configuration
-	driverContext DriverContext
+	configuration Configuration `stringer:"true"`
+	driverContext DriverContext `stringer:"true"`
 
 	connectionId string
-	tracer       *tracer.Tracer
+	tracer       tracer.Tracer
 
-	log zerolog.Logger
+	log zerolog.Logger `ignore:"true"`
 }
 
 func NewConnection(messageCodec *MessageCodec, configuration Configuration, driverContext DriverContext, tagHandler spi.PlcTagHandler, tm transactions.RequestTransactionManager, connectionOptions map[string][]string, _options ...options.WithOption) *Connection {
@@ -111,7 +108,7 @@ func (c *Connection) IsTraceEnabled() bool {
 	return c.tracer != nil
 }
 
-func (c *Connection) GetTracer() *tracer.Tracer {
+func (c *Connection) GetTracer() tracer.Tracer {
 	return c.tracer
 }
 
@@ -197,31 +194,6 @@ func (c *Connection) addSubscriber(subscriber *Subscriber) {
 	c.subscribers = append(c.subscribers, subscriber)
 }
 
-func (c *Connection) String() string {
-	return fmt.Sprintf(
-		"cbus.Connection{\n"+
-			"\tDefaultConnection: %s,\n"+
-			"\tAlphaGenerator: %s\n"+
-			"\tMessageCodec: %s\n"+
-			"\tsubscribers: %s\n"+
-			"\ttm: %s\n"+
-			"\tconfiguration: %s\n"+
-			"\tdriverContext: %s\n"+
-			"\tconnectionId: %s\n"+
-			"\ttracer: %s\n"+
-			"}",
-		c.DefaultConnection,
-		&c.alphaGenerator,
-		c.messageCodec,
-		c.subscribers,
-		c.tm,
-		c.configuration,
-		c.driverContext,
-		c.connectionId,
-		c.tracer,
-	)
-}
-
 func (c *Connection) setupConnection(ctx context.Context, ch chan plc4go.PlcConnectionConnectResult) {
 	cbusOptions := &c.messageCodec.cbusOptions
 	requestContext := &c.messageCodec.requestContext
diff --git a/plc4go/internal/cbus/Connection_plc4xgen.go b/plc4go/internal/cbus/Connection_plc4xgen.go
new file mode 100644
index 0000000000..cd7908c00f
--- /dev/null
+++ b/plc4go/internal/cbus/Connection_plc4xgen.go
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=Connection"; DO NOT EDIT.
+
+package cbus
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *Connection) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *Connection) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("Connection"); err != nil {
+		return err
+	}
+	if err := d.DefaultConnection.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteString("alphaGenerator", uint32(len(d.alphaGenerator.String())*8), "UTF-8", d.alphaGenerator.String()); err != nil {
+		return err
+	}
+	{
+		_value := fmt.Sprintf("%v", d.messageCodec)
+
+		if err := writeBuffer.WriteString("messageCodec", uint32(len(_value)*8), "UTF-8", _value); err != nil {
+			return err
+		}
+	}
+	if err := writeBuffer.PushContext("subscribers", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+	for _, elem := range d.subscribers {
+		var elem any = elem
+
+		if elem != nil {
+			if serializableField, ok := elem.(utils.Serializable); ok {
+				if err := writeBuffer.PushContext("value"); err != nil {
+					return err
+				}
+				if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+					return err
+				}
+				if err := writeBuffer.PopContext("value"); err != nil {
+					return err
+				}
+			} else {
+				stringValue := fmt.Sprintf("%v", elem)
+				if err := writeBuffer.WriteString("value", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+					return err
+				}
+			}
+		}
+	}
+	if err := writeBuffer.PopContext("subscribers", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+
+	if d.tm != nil {
+		if serializableField, ok := d.tm.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("tm"); err != nil {
+				return err
+			}
+			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+				return err
+			}
+			if err := writeBuffer.PopContext("tm"); err != nil {
+				return err
+			}
+		} else {
+			stringValue := fmt.Sprintf("%v", d.tm)
+			if err := writeBuffer.WriteString("tm", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+				return err
+			}
+		}
+	}
+
+	if err := writeBuffer.WriteString("configuration", uint32(len(d.configuration.String())*8), "UTF-8", d.configuration.String()); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteString("driverContext", uint32(len(d.driverContext.String())*8), "UTF-8", d.driverContext.String()); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteString("connectionId", uint32(len(d.connectionId)*8), "UTF-8", d.connectionId); err != nil {
+		return err
+	}
+
+	if d.tracer != nil {
+		if serializableField, ok := d.tracer.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("tracer"); err != nil {
+				return err
+			}
+			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+				return err
+			}
+			if err := writeBuffer.PopContext("tracer"); err != nil {
+				return err
+			}
+		} else {
+			stringValue := fmt.Sprintf("%v", d.tracer)
+			if err := writeBuffer.WriteString("tracer", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+				return err
+			}
+		}
+	}
+	if err := writeBuffer.PopContext("Connection"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *Connection) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/internal/cbus/Connection_test.go b/plc4go/internal/cbus/Connection_test.go
index b96d950f00..991ef458d2 100644
--- a/plc4go/internal/cbus/Connection_test.go
+++ b/plc4go/internal/cbus/Connection_test.go
@@ -94,7 +94,7 @@ func TestConnection_BrowseRequestBuilder(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -139,7 +139,7 @@ func TestConnection_ConnectWithContext(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -236,7 +236,7 @@ func TestConnection_GetConnection(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -278,7 +278,7 @@ func TestConnection_GetConnectionId(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -317,7 +317,7 @@ func TestConnection_GetMessageCodec(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -360,7 +360,7 @@ func TestConnection_GetMetadata(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -406,13 +406,13 @@ func TestConnection_GetTracer(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
 		name   string
 		fields fields
-		want   *tracer.Tracer
+		want   tracer.Tracer
 	}{
 		{
 			name: "just nil",
@@ -445,7 +445,7 @@ func TestConnection_IsTraceEnabled(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -484,7 +484,7 @@ func TestConnection_ReadRequestBuilder(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -529,7 +529,7 @@ func TestConnection_String(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -539,22 +539,41 @@ func TestConnection_String(t *testing.T) {
 	}{
 		{
 			name: "a string",
-			want: "cbus.Connection{\n" +
-				"\tDefaultConnection: %!s(<nil>),\n" +
-				"\tAlphaGenerator: AlphaGenerator(currentAlpha: \x00)\n" +
-				"\tMessageCodec: <nil>\n" +
-				"\tsubscribers: []\n" +
-				"\ttm: %!s(<nil>)\n" +
-				"\tconfiguration: cbus.Configuration{Srchk:false, Exstat:false, Pun:false, LocalSal:false, Pcn:false, Idmon:false, Monitor:false, Smart:false, XonXoff:false, Connect:false, MonitoredApplication1:0x0, MonitoredApplication2:0x0}\n\tdriverContext: cbus.DriverContext{awaitSetupComplete:false, awaitDisconnectComplete:false}\n" +
-				"\tconnectionId: \n" +
-				"\ttracer: <nil>\n" +
-				"}",
+			fields: fields{
+				DefaultConnection: _default.NewDefaultConnection(nil),
+			},
+			want: `
+╔═Connection══════════════════════════════════════════════════════════════════════════════════════════════╗
+║╔═defaultConnection═══════╗╔═alphaGenerator════════════════════╗╔═messageCodec╗                          ║
+║║╔═defaultTtl╗╔═connected╗║║╔═AlphaGenerator/currentAlpha═════╗║║    <nil>    ║                          ║
+║║║    10s    ║║ b0 false ║║║║            0x67 'g'             ║║╚═════════════╝                          ║
+║║╚═══════════╝╚══════════╝║║╚═════════════════════════════════╝║                                         ║
+║╚═════════════════════════╝╚═══════════════════════════════════╝                                         ║
+║╔═configuration═════════════════════════════════════════════════════════════════════════════════════════╗║
+║║╔═Configuration═══════════════════════════════════════════════════════════════════════════════════════╗║║
+║║║╔═srchk══╗╔═exstat═╗╔═pun════╗╔═localSal╗╔═pcn════╗╔═idmon══╗╔═monitor╗╔═smart══╗╔═xonXoff╗╔═connect╗║║║
+║║║║b0 false║║b0 false║║b0 false║║b0 false ║║b0 false║║b0 false║║b0 false║║b0 false║║b0 false║║b0 false║║║║
+║║║╚════════╝╚════════╝╚════════╝╚═════════╝╚════════╝╚════════╝╚════════╝╚════════╝╚════════╝╚════════╝║║║
+║║║╔═monitoredApplication1╗╔═monitoredApplication2╗                                                     ║║║
+║║║║       0x00 '.'       ║║       0x00 '.'       ║                                                     ║║║
+║║║╚══════════════════════╝╚══════════════════════╝                                                     ║║║
+║║╚═════════════════════════════════════════════════════════════════════════════════════════════════════╝║║
+║╚═══════════════════════════════════════════════════════════════════════════════════════════════════════╝║
+║╔═driverContext═══════════════════════════════════╗                                                      ║
+║║╔═DriverContext═════════════════════════════════╗║                                                      ║
+║║║╔═awaitSetupComplete╗╔═awaitDisconnectComplete╗║║                                                      ║
+║║║║     b0 false      ║║        b0 false        ║║║                                                      ║
+║║║╚═══════════════════╝╚════════════════════════╝║║                                                      ║
+║║╚═══════════════════════════════════════════════╝║                                                      ║
+║╚═════════════════════════════════════════════════╝                                                      ║
+╚═════════════════════════════════════════════════════════════════════════════════════════════════════════╝`[1:], // TODO: configuration is not redered right now
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			c := &Connection{
 				DefaultConnection: tt.fields.DefaultConnection,
+				alphaGenerator:    AlphaGenerator{currentAlpha: 'g'},
 				messageCodec:      tt.fields.messageCodec,
 				subscribers:       tt.fields.subscribers,
 				tm:                tt.fields.tm,
@@ -578,7 +597,7 @@ func TestConnection_SubscriptionRequestBuilder(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -623,7 +642,7 @@ func TestConnection_UnsubscriptionRequestBuilder(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -662,7 +681,7 @@ func TestConnection_WriteRequestBuilder(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
@@ -707,7 +726,7 @@ func TestConnection_addSubscriber(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -764,7 +783,7 @@ func TestConnection_fireConnected(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -828,7 +847,7 @@ func TestConnection_fireConnectionError(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -931,7 +950,7 @@ func TestConnection_sendCalDataWrite(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -1018,7 +1037,7 @@ func TestConnection_sendReset(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -1102,7 +1121,7 @@ func TestConnection_setApplicationFilter(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -1186,7 +1205,7 @@ func TestConnection_setInterface1PowerUpSettings(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -1270,7 +1289,7 @@ func TestConnection_setInterfaceOptions1(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -1354,7 +1373,7 @@ func TestConnection_setInterfaceOptions3(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -1438,7 +1457,7 @@ func TestConnection_setupConnection(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	type args struct {
@@ -1877,7 +1896,7 @@ func TestConnection_startSubscriptionHandler(t *testing.T) {
 		configuration     Configuration
 		driverContext     DriverContext
 		connectionId      string
-		tracer            *tracer.Tracer
+		tracer            tracer.Tracer
 		log               zerolog.Logger
 	}
 	tests := []struct {
diff --git a/plc4go/internal/cbus/DriverContext.go b/plc4go/internal/cbus/DriverContext.go
index 7c4307c960..a53f2fa8b5 100644
--- a/plc4go/internal/cbus/DriverContext.go
+++ b/plc4go/internal/cbus/DriverContext.go
@@ -19,8 +19,7 @@
 
 package cbus
 
-import "fmt"
-
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=DriverContext
 type DriverContext struct {
 	awaitSetupComplete      bool
 	awaitDisconnectComplete bool
@@ -29,7 +28,3 @@ type DriverContext struct {
 func NewDriverContext(_ Configuration) DriverContext {
 	return DriverContext{}
 }
-
-func (d DriverContext) String() string {
-	return fmt.Sprintf("%#v", d)
-}
diff --git a/plc4go/internal/cbus/DriverContext_plc4xgen.go b/plc4go/internal/cbus/DriverContext_plc4xgen.go
new file mode 100644
index 0000000000..5e80de0112
--- /dev/null
+++ b/plc4go/internal/cbus/DriverContext_plc4xgen.go
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=DriverContext"; DO NOT EDIT.
+
+package cbus
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *DriverContext) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *DriverContext) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("DriverContext"); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("awaitSetupComplete", d.awaitSetupComplete); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("awaitDisconnectComplete", d.awaitDisconnectComplete); err != nil {
+		return err
+	}
+	if err := writeBuffer.PopContext("DriverContext"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *DriverContext) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/internal/cbus/MessageCodec.go b/plc4go/internal/cbus/MessageCodec.go
index b8119c7d8f..f4239c1fc8 100644
--- a/plc4go/internal/cbus/MessageCodec.go
+++ b/plc4go/internal/cbus/MessageCodec.go
@@ -21,7 +21,6 @@ package cbus
 
 import (
 	"bufio"
-	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/options"
 	"github.com/rs/zerolog"
 	"hash/crc32"
@@ -33,6 +32,7 @@ import (
 	"github.com/pkg/errors"
 )
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=MessageCodec
 type MessageCodec struct {
 	_default.DefaultCodec
 
@@ -46,7 +46,7 @@ type MessageCodec struct {
 
 	currentlyReportedServerErrors uint
 
-	log zerolog.Logger
+	log zerolog.Logger `ignore:"true"`
 }
 
 func NewMessageCodec(transportInstance transports.TransportInstance, _options ...options.WithOption) *MessageCodec {
@@ -323,26 +323,6 @@ lookingForTheEnd:
 	return cBusMessage, nil
 }
 
-func (m *MessageCodec) String() string {
-	return fmt.Sprintf("MessageCodec{\n"+
-		"\tDefaultCodec: %s,\n"+
-		"\trequestContext: %s,\n"+
-		"\tcbusOptions: %s,\n"+
-		"\tmonitoredMMIs: %d elements,\n"+
-		"\tmonitoredSALs: %d elements,\n"+
-		"\tlastPackageHash: %d,\n"+
-		"\thashEncountered: %d,\n"+
-		"}",
-		m.DefaultCodec,
-		m.requestContext,
-		m.cbusOptions,
-		len(m.monitoredSALs),
-		len(m.monitoredSALs),
-		m.lastPackageHash,
-		m.hashEncountered,
-	)
-}
-
 func extractMMIAndSAL(log zerolog.Logger) _default.CustomMessageHandler {
 	return func(codec _default.DefaultCodecRequirements, message spi.Message) bool {
 		log.Trace().Msgf("Custom handling message:\n%s", message)
diff --git a/plc4go/internal/cbus/MessageCodec_plc4xgen.go b/plc4go/internal/cbus/MessageCodec_plc4xgen.go
new file mode 100644
index 0000000000..bbf188cc29
--- /dev/null
+++ b/plc4go/internal/cbus/MessageCodec_plc4xgen.go
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=MessageCodec"; DO NOT EDIT.
+
+package cbus
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *MessageCodec) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *MessageCodec) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("MessageCodec"); err != nil {
+		return err
+	}
+	if err := d.DefaultCodec.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+		return err
+	}
+
+	if d.requestContext != nil {
+		if serializableField, ok := d.requestContext.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("requestContext"); err != nil {
+				return err
+			}
+			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+				return err
+			}
+			if err := writeBuffer.PopContext("requestContext"); err != nil {
+				return err
+			}
+		} else {
+			stringValue := fmt.Sprintf("%v", d.requestContext)
+			if err := writeBuffer.WriteString("requestContext", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+				return err
+			}
+		}
+	}
+
+	if d.cbusOptions != nil {
+		if serializableField, ok := d.cbusOptions.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("cbusOptions"); err != nil {
+				return err
+			}
+			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+				return err
+			}
+			if err := writeBuffer.PopContext("cbusOptions"); err != nil {
+				return err
+			}
+		} else {
+			stringValue := fmt.Sprintf("%v", d.cbusOptions)
+			if err := writeBuffer.WriteString("cbusOptions", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+				return err
+			}
+		}
+	}
+
+	_monitoredMMIs_plx4gen_description := fmt.Sprintf("%d element(s)", len(d.monitoredMMIs))
+	if err := writeBuffer.WriteString("monitoredMMIs", uint32(len(_monitoredMMIs_plx4gen_description)*8), "UTF-8", _monitoredMMIs_plx4gen_description); err != nil {
+		return err
+	}
+
+	_monitoredSALs_plx4gen_description := fmt.Sprintf("%d element(s)", len(d.monitoredSALs))
+	if err := writeBuffer.WriteString("monitoredSALs", uint32(len(_monitoredSALs_plx4gen_description)*8), "UTF-8", _monitoredSALs_plx4gen_description); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteUint32("lastPackageHash", 32, d.lastPackageHash); err != nil {
+		return err
+	}
+	{
+		_value := fmt.Sprintf("%v", d.hashEncountered)
+
+		if err := writeBuffer.WriteString("hashEncountered", uint32(len(_value)*8), "UTF-8", _value); err != nil {
+			return err
+		}
+	}
+	{
+		_value := fmt.Sprintf("%v", d.currentlyReportedServerErrors)
+
+		if err := writeBuffer.WriteString("currentlyReportedServerErrors", uint32(len(_value)*8), "UTF-8", _value); err != nil {
+			return err
+		}
+	}
+	if err := writeBuffer.PopContext("MessageCodec"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *MessageCodec) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/internal/cbus/MessageCodec_test.go b/plc4go/internal/cbus/MessageCodec_test.go
index 68abdb02e0..fd9e32eee6 100644
--- a/plc4go/internal/cbus/MessageCodec_test.go
+++ b/plc4go/internal/cbus/MessageCodec_test.go
@@ -899,15 +899,35 @@ func TestMessageCodec_String(t *testing.T) {
 	}{
 		{
 			name: "string it",
-			want: "MessageCodec{\n" +
-				"\tDefaultCodec: %!s(<nil>),\n" +
-				"\trequestContext: %!s(<nil>),\n" +
-				"\tcbusOptions: %!s(<nil>),\n" +
-				"\tmonitoredMMIs: 0 elements,\n" +
-				"\tmonitoredSALs: 0 elements,\n" +
-				"\tlastPackageHash: 0,\n" +
-				"\thashEncountered: 0,\n" +
-				"}",
+			fields: fields{
+				DefaultCodec:                  _default.NewDefaultCodec(nil, test.NewTransportInstance(test.NewTransport())),
+				requestContext:                readWriteModel.NewRequestContext(true),
+				cbusOptions:                   readWriteModel.NewCBusOptions(true, true, true, true, true, true, true, true, true),
+				monitoredMMIs:                 nil,
+				monitoredSALs:                 nil,
+				lastPackageHash:               2,
+				hashEncountered:               3,
+				currentlyReportedServerErrors: 4,
+			},
+			want: `
+╔═MessageCodec════════════════════════════════════════════════════════════════════════════════════════════════════════╗
+║╔═defaultCodec═════════════════════════════════════════════════════════════════════════╗                             ║
+║║╔═transportInstance╗╔═defaultIncomingMessageChannel╗╔═running╗╔═customMessageHandling╗║                             ║
+║║║       test       ║║         0 element(s)         ║║b0 false║║       b0 false       ║║                             ║
+║║╚══════════════════╝╚══════════════════════════════╝╚════════╝╚══════════════════════╝║                             ║
+║╚══════════════════════════════════════════════════════════════════════════════════════╝                             ║
+║╔═requestContext/RequestContext/sendIdentifyRequestBefore═════════════════════════════════════════════════════╗      ║
+║║                                                   b1 true                                                   ║      ║
+║╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════╝      ║
+║╔═cbusOptions/CBusOptions═══════════════════════════════════════════════════════════╗╔═monitoredMMIs╗╔═monitoredSALs╗║
+║║╔═connect╗╔═smart═╗╔═idmon═╗╔═exstat╗╔═monitor╗╔═monall╗╔═pun═══╗╔═pcn═══╗╔═srchk═╗║║ 0 element(s) ║║ 0 element(s) ║║
+║║║b1 true ║║b1 true║║b1 true║║b1 true║║b1 true ║║b1 true║║b1 true║║b1 true║║b1 true║║╚══════════════╝╚══════════════╝║
+║║╚════════╝╚═══════╝╚═══════╝╚═══════╝╚════════╝╚═══════╝╚═══════╝╚═══════╝╚═══════╝║                                ║
+║╚═══════════════════════════════════════════════════════════════════════════════════╝                                ║
+║╔═lastPackageHash╗╔═hashEncountered╗╔═currentlyReportedServerErrors╗                                                 ║
+║║  0x00000002 2  ║║       3        ║║              4               ║                                                 ║
+║╚════════════════╝╚════════════════╝╚══════════════════════════════╝                                                 ║
+╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/internal/cbus/Subscriber.go b/plc4go/internal/cbus/Subscriber.go
index 0454ac9ebb..04ba4bc154 100644
--- a/plc4go/internal/cbus/Subscriber.go
+++ b/plc4go/internal/cbus/Subscriber.go
@@ -36,11 +36,12 @@ import (
 	spiValues "github.com/apache/plc4x/plc4go/spi/values"
 )
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=Subscriber
 type Subscriber struct {
-	consumers     map[*spiModel.DefaultPlcConsumerRegistration]apiModel.PlcSubscriptionEventConsumer
+	consumers     map[*spiModel.DefaultPlcConsumerRegistration]apiModel.PlcSubscriptionEventConsumer `ignore:"true"`
 	addSubscriber func(subscriber *Subscriber)
 
-	log zerolog.Logger
+	log zerolog.Logger `ignore:"true"`
 }
 
 func NewSubscriber(addSubscriber func(subscriber *Subscriber), _options ...options.WithOption) *Subscriber {
@@ -406,7 +407,3 @@ func (s *Subscriber) Register(consumer apiModel.PlcSubscriptionEventConsumer, ha
 func (s *Subscriber) Unregister(registration apiModel.PlcConsumerRegistration) {
 	delete(s.consumers, registration.(*spiModel.DefaultPlcConsumerRegistration))
 }
-
-func (s *Subscriber) String() string {
-	return fmt.Sprintf("cbus.Subcriber{\n\tconsumers: %d elements\n}", len(s.consumers))
-}
diff --git a/plc4go/internal/cbus/Subscriber_plc4xgen.go b/plc4go/internal/cbus/Subscriber_plc4xgen.go
new file mode 100644
index 0000000000..53bc4edefb
--- /dev/null
+++ b/plc4go/internal/cbus/Subscriber_plc4xgen.go
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=Subscriber"; DO NOT EDIT.
+
+package cbus
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *Subscriber) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *Subscriber) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("Subscriber"); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("addSubscriber", d.addSubscriber != nil); err != nil {
+		return err
+	}
+	if err := writeBuffer.PopContext("Subscriber"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *Subscriber) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/internal/eip/Connection.go b/plc4go/internal/eip/Connection.go
index 9ef70ea2cd..e88ec1aac1 100644
--- a/plc4go/internal/eip/Connection.go
+++ b/plc4go/internal/eip/Connection.go
@@ -60,7 +60,7 @@ type Connection struct {
 	useMessageRouter          bool
 	useConnectionManager      bool
 	routingAddress            []readWriteModel.PathSegment
-	tracer                    *tracer.Tracer
+	tracer                    tracer.Tracer
 
 	log zerolog.Logger
 }
@@ -108,7 +108,7 @@ func (m *Connection) IsTraceEnabled() bool {
 	return m.tracer != nil
 }
 
-func (m *Connection) GetTracer() *tracer.Tracer {
+func (m *Connection) GetTracer() tracer.Tracer {
 	return m.tracer
 }
 
diff --git a/plc4go/internal/knxnetip/Connection.go b/plc4go/internal/knxnetip/Connection.go
index 26f5ae8ba8..15b35c6913 100644
--- a/plc4go/internal/knxnetip/Connection.go
+++ b/plc4go/internal/knxnetip/Connection.go
@@ -136,7 +136,7 @@ type Connection struct {
 	handleTunnelingRequests bool
 
 	connectionId string
-	tracer       *tracer.Tracer
+	tracer       tracer.Tracer
 
 	log zerolog.Logger
 }
@@ -217,7 +217,7 @@ func (m *Connection) IsTraceEnabled() bool {
 	return m.tracer != nil
 }
 
-func (m *Connection) GetTracer() *tracer.Tracer {
+func (m *Connection) GetTracer() tracer.Tracer {
 	return m.tracer
 }
 
diff --git a/plc4go/internal/modbus/Connection.go b/plc4go/internal/modbus/Connection.go
index f6e1236913..7d322d2122 100644
--- a/plc4go/internal/modbus/Connection.go
+++ b/plc4go/internal/modbus/Connection.go
@@ -47,7 +47,7 @@ type Connection struct {
 	requestInterceptor interceptors.RequestInterceptor
 
 	connectionId string
-	tracer       *tracer.Tracer
+	tracer       tracer.Tracer
 
 	log zerolog.Logger
 }
@@ -87,7 +87,7 @@ func (m *Connection) IsTraceEnabled() bool {
 	return m.tracer != nil
 }
 
-func (m *Connection) GetTracer() *tracer.Tracer {
+func (m *Connection) GetTracer() tracer.Tracer {
 	return m.tracer
 }
 
diff --git a/plc4go/internal/s7/Connection.go b/plc4go/internal/s7/Connection.go
index 40933db93d..f77a1ed934 100644
--- a/plc4go/internal/s7/Connection.go
+++ b/plc4go/internal/s7/Connection.go
@@ -67,7 +67,7 @@ type Connection struct {
 	tm            transactions.RequestTransactionManager
 
 	connectionId string
-	tracer       *tracer.Tracer
+	tracer       tracer.Tracer
 
 	log zerolog.Logger
 }
@@ -101,7 +101,7 @@ func (m *Connection) IsTraceEnabled() bool {
 	return m.tracer != nil
 }
 
-func (m *Connection) GetTracer() *tracer.Tracer {
+func (m *Connection) GetTracer() tracer.Tracer {
 	return m.tracer
 }
 
diff --git a/plc4go/internal/simulated/Connection.go b/plc4go/internal/simulated/Connection.go
index 6659f76318..cb16105add 100644
--- a/plc4go/internal/simulated/Connection.go
+++ b/plc4go/internal/simulated/Connection.go
@@ -45,7 +45,7 @@ type Connection struct {
 	options      map[string][]string
 	connected    bool
 	connectionId string
-	tracer       *tracer.Tracer
+	tracer       tracer.Tracer
 
 	log zerolog.Logger
 }
@@ -78,7 +78,7 @@ func (c *Connection) IsTraceEnabled() bool {
 	return c.tracer != nil
 }
 
-func (c *Connection) GetTracer() *tracer.Tracer {
+func (c *Connection) GetTracer() tracer.Tracer {
 	return c.tracer
 }
 
diff --git a/plc4go/internal/simulated/Reader.go b/plc4go/internal/simulated/Reader.go
index 41e14052a8..4de5d3b6be 100644
--- a/plc4go/internal/simulated/Reader.go
+++ b/plc4go/internal/simulated/Reader.go
@@ -37,12 +37,12 @@ import (
 type Reader struct {
 	device  *Device
 	options map[string][]string
-	tracer  *tracer.Tracer
+	tracer  tracer.Tracer
 
 	log zerolog.Logger
 }
 
-func NewReader(device *Device, readerOptions map[string][]string, tracer *tracer.Tracer, _options ...options.WithOption) *Reader {
+func NewReader(device *Device, readerOptions map[string][]string, tracer tracer.Tracer, _options ...options.WithOption) *Reader {
 	return &Reader{
 		device:  device,
 		options: readerOptions,
diff --git a/plc4go/internal/simulated/Subscriber.go b/plc4go/internal/simulated/Subscriber.go
index 30f7b6a196..4494202b54 100644
--- a/plc4go/internal/simulated/Subscriber.go
+++ b/plc4go/internal/simulated/Subscriber.go
@@ -30,10 +30,10 @@ import (
 type Subscriber struct {
 	device  *Device
 	options map[string][]string
-	tracer  *tracer.Tracer
+	tracer  tracer.Tracer
 }
 
-func NewSubscriber(device *Device, options map[string][]string, tracer *tracer.Tracer) *Subscriber {
+func NewSubscriber(device *Device, options map[string][]string, tracer tracer.Tracer) *Subscriber {
 	return &Subscriber{
 		device:  device,
 		options: options,
diff --git a/plc4go/internal/simulated/Writer.go b/plc4go/internal/simulated/Writer.go
index 616c8ace31..69c6f38a04 100644
--- a/plc4go/internal/simulated/Writer.go
+++ b/plc4go/internal/simulated/Writer.go
@@ -36,12 +36,12 @@ import (
 type Writer struct {
 	device  *Device
 	options map[string][]string
-	tracer  *tracer.Tracer
+	tracer  tracer.Tracer
 
 	log zerolog.Logger
 }
 
-func NewWriter(device *Device, writerOptions map[string][]string, tracer *tracer.Tracer, _options ...options.WithOption) *Writer {
+func NewWriter(device *Device, writerOptions map[string][]string, tracer tracer.Tracer, _options ...options.WithOption) *Writer {
 	return &Writer{
 		device:  device,
 		options: writerOptions,
diff --git a/plc4go/pkg/api/cache/PlcConnectionCache.go b/plc4go/pkg/api/cache/PlcConnectionCache.go
index ec17b955b7..4e2e91188e 100644
--- a/plc4go/pkg/api/cache/PlcConnectionCache.go
+++ b/plc4go/pkg/api/cache/PlcConnectionCache.go
@@ -106,7 +106,7 @@ type plcConnectionCache struct {
 
 	cacheLock   lock.RWMutex
 	connections map[string]*connectionContainer
-	tracer      *tracer.Tracer
+	tracer      tracer.Tracer
 
 	log zerolog.Logger
 }
@@ -131,7 +131,7 @@ func (t *plcConnectionCache) EnableTracer() {
 	t.tracer = tracer.NewTracer("cache", options.WithCustomLogger(t.log))
 }
 
-func (t *plcConnectionCache) GetTracer() *tracer.Tracer {
+func (t *plcConnectionCache) GetTracer() tracer.Tracer {
 	return t.tracer
 }
 
diff --git a/plc4go/pkg/api/cache/mock_tracedPlcConnection_test.go b/plc4go/pkg/api/cache/mock_tracedPlcConnection_test.go
index 3be240562f..dc686b90f7 100644
--- a/plc4go/pkg/api/cache/mock_tracedPlcConnection_test.go
+++ b/plc4go/pkg/api/cache/mock_tracedPlcConnection_test.go
@@ -335,15 +335,15 @@ func (_c *mockTracedPlcConnection_GetMetadata_Call) RunAndReturn(run func() mode
 }
 
 // GetTracer provides a mock function with given fields:
-func (_m *mockTracedPlcConnection) GetTracer() *tracer.Tracer {
+func (_m *mockTracedPlcConnection) GetTracer() tracer.Tracer {
 	ret := _m.Called()
 
-	var r0 *tracer.Tracer
-	if rf, ok := ret.Get(0).(func() *tracer.Tracer); ok {
+	var r0 tracer.Tracer
+	if rf, ok := ret.Get(0).(func() tracer.Tracer); ok {
 		r0 = rf()
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*tracer.Tracer)
+			r0 = ret.Get(0).(tracer.Tracer)
 		}
 	}
 
@@ -367,12 +367,12 @@ func (_c *mockTracedPlcConnection_GetTracer_Call) Run(run func()) *mockTracedPlc
 	return _c
 }
 
-func (_c *mockTracedPlcConnection_GetTracer_Call) Return(_a0 *tracer.Tracer) *mockTracedPlcConnection_GetTracer_Call {
+func (_c *mockTracedPlcConnection_GetTracer_Call) Return(_a0 tracer.Tracer) *mockTracedPlcConnection_GetTracer_Call {
 	_c.Call.Return(_a0)
 	return _c
 }
 
-func (_c *mockTracedPlcConnection_GetTracer_Call) RunAndReturn(run func() *tracer.Tracer) *mockTracedPlcConnection_GetTracer_Call {
+func (_c *mockTracedPlcConnection_GetTracer_Call) RunAndReturn(run func() tracer.Tracer) *mockTracedPlcConnection_GetTracer_Call {
 	_c.Call.Return(run)
 	return _c
 }
diff --git a/plc4go/pkg/api/cache/plcConnectionLease.go b/plc4go/pkg/api/cache/plcConnectionLease.go
index 34c2b6817b..28c5f2436e 100644
--- a/plc4go/pkg/api/cache/plcConnectionLease.go
+++ b/plc4go/pkg/api/cache/plcConnectionLease.go
@@ -58,7 +58,7 @@ func (t *plcConnectionLease) IsTraceEnabled() bool {
 	return t.connection.IsTraceEnabled()
 }
 
-func (t *plcConnectionLease) GetTracer() *tracer.Tracer {
+func (t *plcConnectionLease) GetTracer() tracer.Tracer {
 	if t.connection == nil {
 		panic("Called 'GetTracer' on a closed cached connection")
 	}
diff --git a/plc4go/pkg/api/cache/tracedPlcConnection.go b/plc4go/pkg/api/cache/tracedPlcConnection.go
index 7b10061169..80c82bd433 100644
--- a/plc4go/pkg/api/cache/tracedPlcConnection.go
+++ b/plc4go/pkg/api/cache/tracedPlcConnection.go
@@ -29,5 +29,5 @@ type tracedPlcConnection interface {
 
 	GetConnectionId() string
 	IsTraceEnabled() bool
-	GetTracer() *tracer.Tracer
+	GetTracer() tracer.Tracer
 }
diff --git a/plc4go/spi/default/DefaultCodec.go b/plc4go/spi/default/DefaultCodec.go
index afd3052c9c..e47f6f30f1 100644
--- a/plc4go/spi/default/DefaultCodec.go
+++ b/plc4go/spi/default/DefaultCodec.go
@@ -44,6 +44,7 @@ type DefaultCodecRequirements interface {
 
 // DefaultCodec is a default codec implementation which has so sensitive defaults for message handling and a built-in worker
 type DefaultCodec interface {
+	utils.Serializable
 	spi.MessageCodec
 	spi.TransportInstanceExposer
 }
@@ -78,15 +79,16 @@ type withCustomMessageHandler struct {
 	customMessageHandler func(codec DefaultCodecRequirements, message spi.Message) bool
 }
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=defaultCodec
 type defaultCodec struct {
-	DefaultCodecRequirements
+	DefaultCodecRequirements      `ignore:"true"`
 	transportInstance             transports.TransportInstance
 	defaultIncomingMessageChannel chan spi.Message
 	expectations                  []spi.Expectation
 	running                       bool
 	customMessageHandling         func(codec DefaultCodecRequirements, message spi.Message) bool
 
-	log zerolog.Logger
+	log zerolog.Logger `ignore:"true"`
 }
 
 func buildDefaultCodec(defaultCodecRequirements DefaultCodecRequirements, transportInstance transports.TransportInstance, _options ...options.WithOption) DefaultCodec {
@@ -355,19 +357,3 @@ func (m *defaultCodec) passToDefaultIncomingMessageChannel(workerLog zerolog.Log
 		workerLog.Warn().Msgf("Message discarded\n%s", message)
 	}
 }
-
-func (m *defaultCodec) String() string {
-	return fmt.Sprintf("DefaultCodec{\n"+
-		"\tTransportInstance: %s,\n"+
-		"\tDefaultIncomingMessageChannel: %d elements,\n"+
-		"\tExpectations: %s,\n"+
-		"\trunning: %t,\n"+
-		"\tcustomMessageHandling: %t,\n"+
-		"}",
-		m.transportInstance,
-		len(m.defaultIncomingMessageChannel),
-		m.expectations,
-		m.running,
-		m.customMessageHandling != nil,
-	)
-}
diff --git a/plc4go/spi/default/DefaultCodec_test.go b/plc4go/spi/default/DefaultCodec_test.go
index a186912b71..407e564e55 100644
--- a/plc4go/spi/default/DefaultCodec_test.go
+++ b/plc4go/spi/default/DefaultCodec_test.go
@@ -25,6 +25,7 @@ import (
 	"github.com/apache/plc4x/plc4go/spi"
 	"github.com/apache/plc4x/plc4go/spi/options"
 	"github.com/apache/plc4x/plc4go/spi/transports"
+	"github.com/apache/plc4x/plc4go/spi/transports/test"
 	"github.com/pkg/errors"
 	"github.com/rs/zerolog"
 	"github.com/stretchr/testify/assert"
@@ -1213,13 +1214,37 @@ func Test_defaultCodec_String(t *testing.T) {
 	}{
 		{
 			name: "string it",
-			want: "DefaultCodec{\n" +
-				"\tTransportInstance: %!s(<nil>),\n" +
-				"\tDefaultIncomingMessageChannel: 0 elements,\n" +
-				"\tExpectations: [],\n" +
-				"\trunning: false,\n" +
-				"\tcustomMessageHandling: false,\n" +
-				"}",
+			fields: fields{
+				transportInstance: test.NewTransportInstance(test.NewTransport()),
+				defaultIncomingMessageChannel: func() chan spi.Message {
+					messages := make(chan spi.Message, 1)
+					messages <- NewMockMessage(t)
+					return messages
+				}(),
+				expectations: []spi.Expectation{
+					func() spi.Expectation {
+						expectation := NewMockExpectation(t)
+						expectation.EXPECT().String().Return("yoink1")
+						return expectation
+					}(),
+					func() spi.Expectation {
+						expectation := NewMockExpectation(t)
+						expectation.EXPECT().String().Return("yoink2")
+						return expectation
+					}(),
+				},
+				running:               false,
+				customMessageHandling: nil,
+				log:                   zerolog.Logger{},
+			},
+			want: `
+╔═defaultCodec═══════════════════════════════════════════════════════════════════════════════════════════╗
+║╔═transportInstance╗╔═defaultIncomingMessageChannel╗╔═expectations═══╗╔═running╗╔═customMessageHandling╗║
+║║       test       ║║         1 element(s)         ║║╔═value╗╔═value╗║║b0 false║║       b0 false       ║║
+║╚══════════════════╝╚══════════════════════════════╝║║yoink1║║yoink2║║╚════════╝╚══════════════════════╝║
+║                                                    ║╚══════╝╚══════╝║                                  ║
+║                                                    ╚════════════════╝                                  ║
+╚════════════════════════════════════════════════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/default/DefaultConnection.go b/plc4go/spi/default/DefaultConnection.go
index 67caedf5cd..fd0b42c121 100644
--- a/plc4go/spi/default/DefaultConnection.go
+++ b/plc4go/spi/default/DefaultConnection.go
@@ -21,8 +21,8 @@ package _default
 
 import (
 	"context"
-	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/tracer"
+	"github.com/apache/plc4x/plc4go/spi/utils"
 	"github.com/rs/zerolog"
 	"runtime/debug"
 	"time"
@@ -48,6 +48,7 @@ type DefaultConnectionRequirements interface {
 
 // DefaultConnection should be used as an embedded struct. All defined methods here have default implementations
 type DefaultConnection interface {
+	utils.Serializable
 	plc4go.PlcConnection
 	spi.TransportInstanceExposer
 	spi.HandlerExposer
@@ -146,16 +147,17 @@ type withPlcValueHandler struct {
 	plcValueHandler spi.PlcValueHandler
 }
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=defaultConnection
 type defaultConnection struct {
-	DefaultConnectionRequirements
+	DefaultConnectionRequirements `ignore:"true"`
 	// defaultTtl the time to live after a close
-	defaultTtl time.Duration
+	defaultTtl time.Duration `stringer:"true"`
 	// connected indicates if a connection is connected
 	connected    bool
 	tagHandler   spi.PlcTagHandler
 	valueHandler spi.PlcValueHandler
 
-	log zerolog.Logger
+	log zerolog.Logger `ignore:"true"`
 }
 
 func buildDefaultConnection(requirements DefaultConnectionRequirements, _options ...options.WithOption) DefaultConnection {
@@ -360,20 +362,6 @@ func (d *defaultConnection) GetPlcValueHandler() spi.PlcValueHandler {
 	return d.valueHandler
 }
 
-func (d *defaultConnection) String() string {
-	return fmt.Sprintf("DefaultConnection{\n"+
-		"\tttl: %s,\n"+
-		"\tconnected: %t,\n"+
-		"\ttagHandler: %s,\n"+
-		"\tvalueHandler: %s,\n"+
-		"}",
-		d.defaultTtl,
-		d.connected,
-		d.tagHandler,
-		d.valueHandler,
-	)
-}
-
 func (m DefaultConnectionMetadata) GetConnectionAttributes() map[string]string {
 	return m.ConnectionAttributes
 }
diff --git a/plc4go/spi/default/DefaultConnection_test.go b/plc4go/spi/default/DefaultConnection_test.go
index 2e26883a1c..de4b836b88 100644
--- a/plc4go/spi/default/DefaultConnection_test.go
+++ b/plc4go/spi/default/DefaultConnection_test.go
@@ -1337,12 +1337,17 @@ func Test_defaultConnection_String(t *testing.T) {
 	}{
 		{
 			name: "string it",
-			want: "DefaultConnection{\n" +
-				"\tttl: 0s,\n" +
-				"\tconnected: false,\n" +
-				"\ttagHandler: %!s(<nil>),\n" +
-				"\tvalueHandler: %!s(<nil>),\n" +
-				"}",
+			fields: fields{
+				defaultTtl: 20 * time.Hour,
+				connected:  true,
+				log:        zerolog.Logger{},
+			},
+			want: `
+╔═defaultConnection═══════╗
+║╔═defaultTtl╗╔═connected╗║
+║║  20h0m0s  ║║ b1 true  ║║
+║╚═══════════╝╚══════════╝║
+╚═════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go b/plc4go/spi/default/defaultCodec_plc4xgen.go
similarity index 58%
copy from plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
copy to plc4go/spi/default/defaultCodec_plc4xgen.go
index 1a22d3e0dd..1b6a4ec881 100644
--- a/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
+++ b/plc4go/spi/default/defaultCodec_plc4xgen.go
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-// Code generated by "plc4xgenerator -type=DefaultPlcConsumerRegistration"; DO NOT EDIT.
+// Code generated by "plc4xgenerator -type=defaultCodec"; DO NOT EDIT.
 
-package model
+package _default
 
 import (
 	"context"
@@ -30,7 +30,7 @@ import (
 
 var _ = fmt.Printf
 
-func (d *DefaultPlcConsumerRegistration) Serialize() ([]byte, error) {
+func (d *defaultCodec) Serialize() ([]byte, error) {
 	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
 	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
 		return nil, err
@@ -38,38 +38,38 @@ func (d *DefaultPlcConsumerRegistration) Serialize() ([]byte, error) {
 	return wb.GetBytes(), nil
 }
 
-func (d *DefaultPlcConsumerRegistration) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
-	if err := writeBuffer.PushContext("PlcConsumerRegistration"); err != nil {
+func (d *defaultCodec) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("defaultCodec"); err != nil {
 		return err
 	}
-	_value := fmt.Sprintf("%v", d.consumerId)
 
-	if err := writeBuffer.WriteString("consumerId", uint32(len(_value)*8), "UTF-8", _value); err != nil {
-		return err
-	}
-
-	if d.plcSubscriber != nil {
-		if serializableField, ok := d.plcSubscriber.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("plcSubscriber"); err != nil {
+	if d.transportInstance != nil {
+		if serializableField, ok := d.transportInstance.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("transportInstance"); err != nil {
 				return err
 			}
 			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
 				return err
 			}
-			if err := writeBuffer.PopContext("plcSubscriber"); err != nil {
+			if err := writeBuffer.PopContext("transportInstance"); err != nil {
 				return err
 			}
 		} else {
-			stringValue := fmt.Sprintf("%v", d.plcSubscriber)
-			if err := writeBuffer.WriteString("plcSubscriber", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+			stringValue := fmt.Sprintf("%v", d.transportInstance)
+			if err := writeBuffer.WriteString("transportInstance", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
 				return err
 			}
 		}
 	}
-	if err := writeBuffer.PushContext("handles", utils.WithRenderAsList(true)); err != nil {
+
+	_defaultIncomingMessageChannel_plx4gen_description := fmt.Sprintf("%d element(s)", len(d.defaultIncomingMessageChannel))
+	if err := writeBuffer.WriteString("defaultIncomingMessageChannel", uint32(len(_defaultIncomingMessageChannel_plx4gen_description)*8), "UTF-8", _defaultIncomingMessageChannel_plx4gen_description); err != nil {
+		return err
+	}
+	if err := writeBuffer.PushContext("expectations", utils.WithRenderAsList(true)); err != nil {
 		return err
 	}
-	for _, elem := range d.handles {
+	for _, elem := range d.expectations {
 		var elem any = elem
 
 		if elem != nil {
@@ -91,16 +91,24 @@ func (d *DefaultPlcConsumerRegistration) SerializeWithWriteBuffer(ctx context.Co
 			}
 		}
 	}
-	if err := writeBuffer.PopContext("handles", utils.WithRenderAsList(true)); err != nil {
+	if err := writeBuffer.PopContext("expectations", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("running", d.running); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("customMessageHandling", d.customMessageHandling != nil); err != nil {
 		return err
 	}
-	if err := writeBuffer.PopContext("PlcConsumerRegistration"); err != nil {
+	if err := writeBuffer.PopContext("defaultCodec"); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (d *DefaultPlcConsumerRegistration) String() string {
+func (d *defaultCodec) String() string {
 	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
 	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
 		return err.Error()
diff --git a/plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go b/plc4go/spi/default/defaultConnection_plc4xgen.go
similarity index 55%
copy from plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go
copy to plc4go/spi/default/defaultConnection_plc4xgen.go
index 7169484d20..b4a6666d24 100644
--- a/plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go
+++ b/plc4go/spi/default/defaultConnection_plc4xgen.go
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-// Code generated by "plc4xgenerator -type=DefaultPlcReadRequestResult"; DO NOT EDIT.
+// Code generated by "plc4xgenerator -type=defaultConnection"; DO NOT EDIT.
 
-package model
+package _default
 
 import (
 	"context"
@@ -30,7 +30,7 @@ import (
 
 var _ = fmt.Printf
 
-func (d *DefaultPlcReadRequestResult) Serialize() ([]byte, error) {
+func (d *defaultConnection) Serialize() ([]byte, error) {
 	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
 	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
 		return nil, err
@@ -38,61 +38,63 @@ func (d *DefaultPlcReadRequestResult) Serialize() ([]byte, error) {
 	return wb.GetBytes(), nil
 }
 
-func (d *DefaultPlcReadRequestResult) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
-	if err := writeBuffer.PushContext("PlcReadRequestResult"); err != nil {
+func (d *defaultConnection) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("defaultConnection"); err != nil {
 		return err
 	}
 
-	if d.Request != nil {
-		if serializableField, ok := d.Request.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("request"); err != nil {
+	if err := writeBuffer.WriteString("defaultTtl", uint32(len(d.defaultTtl.String())*8), "UTF-8", d.defaultTtl.String()); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("connected", d.connected); err != nil {
+		return err
+	}
+
+	if d.tagHandler != nil {
+		if serializableField, ok := d.tagHandler.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("tagHandler"); err != nil {
 				return err
 			}
 			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
 				return err
 			}
-			if err := writeBuffer.PopContext("request"); err != nil {
+			if err := writeBuffer.PopContext("tagHandler"); err != nil {
 				return err
 			}
 		} else {
-			stringValue := fmt.Sprintf("%v", d.Request)
-			if err := writeBuffer.WriteString("request", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+			stringValue := fmt.Sprintf("%v", d.tagHandler)
+			if err := writeBuffer.WriteString("tagHandler", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
 				return err
 			}
 		}
 	}
 
-	if d.Response != nil {
-		if serializableField, ok := d.Response.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("response"); err != nil {
+	if d.valueHandler != nil {
+		if serializableField, ok := d.valueHandler.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("valueHandler"); err != nil {
 				return err
 			}
 			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
 				return err
 			}
-			if err := writeBuffer.PopContext("response"); err != nil {
+			if err := writeBuffer.PopContext("valueHandler"); err != nil {
 				return err
 			}
 		} else {
-			stringValue := fmt.Sprintf("%v", d.Response)
-			if err := writeBuffer.WriteString("response", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+			stringValue := fmt.Sprintf("%v", d.valueHandler)
+			if err := writeBuffer.WriteString("valueHandler", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
 				return err
 			}
 		}
 	}
-
-	if d.Err != nil {
-		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
-			return err
-		}
-	}
-	if err := writeBuffer.PopContext("PlcReadRequestResult"); err != nil {
+	if err := writeBuffer.PopContext("defaultConnection"); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (d *DefaultPlcReadRequestResult) String() string {
+func (d *defaultConnection) String() string {
 	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
 	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
 		return err.Error()
diff --git a/plc4go/spi/default/mock_DefaultCodec_test.go b/plc4go/spi/default/mock_DefaultCodec_test.go
index d5ead2b9f4..d704943d45 100644
--- a/plc4go/spi/default/mock_DefaultCodec_test.go
+++ b/plc4go/spi/default/mock_DefaultCodec_test.go
@@ -30,6 +30,8 @@ import (
 	time "time"
 
 	transports "github.com/apache/plc4x/plc4go/spi/transports"
+
+	utils "github.com/apache/plc4x/plc4go/spi/utils"
 )
 
 // MockDefaultCodec is an autogenerated mock type for the DefaultCodec type
@@ -431,6 +433,102 @@ func (_c *MockDefaultCodec_SendRequest_Call) RunAndReturn(run func(context.Conte
 	return _c
 }
 
+// Serialize provides a mock function with given fields:
+func (_m *MockDefaultCodec) Serialize() ([]byte, error) {
+	ret := _m.Called()
+
+	var r0 []byte
+	var r1 error
+	if rf, ok := ret.Get(0).(func() ([]byte, error)); ok {
+		return rf()
+	}
+	if rf, ok := ret.Get(0).(func() []byte); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]byte)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func() error); ok {
+		r1 = rf()
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// MockDefaultCodec_Serialize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Serialize'
+type MockDefaultCodec_Serialize_Call struct {
+	*mock.Call
+}
+
+// Serialize is a helper method to define mock.On call
+func (_e *MockDefaultCodec_Expecter) Serialize() *MockDefaultCodec_Serialize_Call {
+	return &MockDefaultCodec_Serialize_Call{Call: _e.mock.On("Serialize")}
+}
+
+func (_c *MockDefaultCodec_Serialize_Call) Run(run func()) *MockDefaultCodec_Serialize_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockDefaultCodec_Serialize_Call) Return(_a0 []byte, _a1 error) *MockDefaultCodec_Serialize_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *MockDefaultCodec_Serialize_Call) RunAndReturn(run func() ([]byte, error)) *MockDefaultCodec_Serialize_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// SerializeWithWriteBuffer provides a mock function with given fields: ctx, writeBuffer
+func (_m *MockDefaultCodec) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	ret := _m.Called(ctx, writeBuffer)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, utils.WriteBuffer) error); ok {
+		r0 = rf(ctx, writeBuffer)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// MockDefaultCodec_SerializeWithWriteBuffer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SerializeWithWriteBuffer'
+type MockDefaultCodec_SerializeWithWriteBuffer_Call struct {
+	*mock.Call
+}
+
+// SerializeWithWriteBuffer is a helper method to define mock.On call
+//   - ctx context.Context
+//   - writeBuffer utils.WriteBuffer
+func (_e *MockDefaultCodec_Expecter) SerializeWithWriteBuffer(ctx interface{}, writeBuffer interface{}) *MockDefaultCodec_SerializeWithWriteBuffer_Call {
+	return &MockDefaultCodec_SerializeWithWriteBuffer_Call{Call: _e.mock.On("SerializeWithWriteBuffer", ctx, writeBuffer)}
+}
+
+func (_c *MockDefaultCodec_SerializeWithWriteBuffer_Call) Run(run func(ctx context.Context, writeBuffer utils.WriteBuffer)) *MockDefaultCodec_SerializeWithWriteBuffer_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(context.Context), args[1].(utils.WriteBuffer))
+	})
+	return _c
+}
+
+func (_c *MockDefaultCodec_SerializeWithWriteBuffer_Call) Return(_a0 error) *MockDefaultCodec_SerializeWithWriteBuffer_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockDefaultCodec_SerializeWithWriteBuffer_Call) RunAndReturn(run func(context.Context, utils.WriteBuffer) error) *MockDefaultCodec_SerializeWithWriteBuffer_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
 type mockConstructorTestingTNewMockDefaultCodec interface {
 	mock.TestingT
 	Cleanup(func())
diff --git a/plc4go/spi/default/mock_DefaultConnection_test.go b/plc4go/spi/default/mock_DefaultConnection_test.go
index 4ec2658d6b..7687824900 100644
--- a/plc4go/spi/default/mock_DefaultConnection_test.go
+++ b/plc4go/spi/default/mock_DefaultConnection_test.go
@@ -34,6 +34,8 @@ import (
 	time "time"
 
 	transports "github.com/apache/plc4x/plc4go/spi/transports"
+
+	utils "github.com/apache/plc4x/plc4go/spi/utils"
 )
 
 // MockDefaultConnection is an autogenerated mock type for the DefaultConnection type
@@ -594,6 +596,102 @@ func (_c *MockDefaultConnection_ReadRequestBuilder_Call) RunAndReturn(run func()
 	return _c
 }
 
+// Serialize provides a mock function with given fields:
+func (_m *MockDefaultConnection) Serialize() ([]byte, error) {
+	ret := _m.Called()
+
+	var r0 []byte
+	var r1 error
+	if rf, ok := ret.Get(0).(func() ([]byte, error)); ok {
+		return rf()
+	}
+	if rf, ok := ret.Get(0).(func() []byte); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]byte)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func() error); ok {
+		r1 = rf()
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// MockDefaultConnection_Serialize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Serialize'
+type MockDefaultConnection_Serialize_Call struct {
+	*mock.Call
+}
+
+// Serialize is a helper method to define mock.On call
+func (_e *MockDefaultConnection_Expecter) Serialize() *MockDefaultConnection_Serialize_Call {
+	return &MockDefaultConnection_Serialize_Call{Call: _e.mock.On("Serialize")}
+}
+
+func (_c *MockDefaultConnection_Serialize_Call) Run(run func()) *MockDefaultConnection_Serialize_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockDefaultConnection_Serialize_Call) Return(_a0 []byte, _a1 error) *MockDefaultConnection_Serialize_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *MockDefaultConnection_Serialize_Call) RunAndReturn(run func() ([]byte, error)) *MockDefaultConnection_Serialize_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// SerializeWithWriteBuffer provides a mock function with given fields: ctx, writeBuffer
+func (_m *MockDefaultConnection) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	ret := _m.Called(ctx, writeBuffer)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, utils.WriteBuffer) error); ok {
+		r0 = rf(ctx, writeBuffer)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// MockDefaultConnection_SerializeWithWriteBuffer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SerializeWithWriteBuffer'
+type MockDefaultConnection_SerializeWithWriteBuffer_Call struct {
+	*mock.Call
+}
+
+// SerializeWithWriteBuffer is a helper method to define mock.On call
+//   - ctx context.Context
+//   - writeBuffer utils.WriteBuffer
+func (_e *MockDefaultConnection_Expecter) SerializeWithWriteBuffer(ctx interface{}, writeBuffer interface{}) *MockDefaultConnection_SerializeWithWriteBuffer_Call {
+	return &MockDefaultConnection_SerializeWithWriteBuffer_Call{Call: _e.mock.On("SerializeWithWriteBuffer", ctx, writeBuffer)}
+}
+
+func (_c *MockDefaultConnection_SerializeWithWriteBuffer_Call) Run(run func(ctx context.Context, writeBuffer utils.WriteBuffer)) *MockDefaultConnection_SerializeWithWriteBuffer_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(context.Context), args[1].(utils.WriteBuffer))
+	})
+	return _c
+}
+
+func (_c *MockDefaultConnection_SerializeWithWriteBuffer_Call) Return(_a0 error) *MockDefaultConnection_SerializeWithWriteBuffer_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockDefaultConnection_SerializeWithWriteBuffer_Call) RunAndReturn(run func(context.Context, utils.WriteBuffer) error) *MockDefaultConnection_SerializeWithWriteBuffer_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
 // SetConnected provides a mock function with given fields: connected
 func (_m *MockDefaultConnection) SetConnected(connected bool) {
 	_m.Called(connected)
diff --git a/plc4go/spi/default/mock_Expectation_test.go b/plc4go/spi/default/mock_Expectation_test.go
new file mode 100644
index 0000000000..e10a73fdaf
--- /dev/null
+++ b/plc4go/spi/default/mock_Expectation_test.go
@@ -0,0 +1,313 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by mockery v2.29.0. DO NOT EDIT.
+
+package _default
+
+import (
+	context "context"
+
+	spi "github.com/apache/plc4x/plc4go/spi"
+	mock "github.com/stretchr/testify/mock"
+
+	time "time"
+)
+
+// MockExpectation is an autogenerated mock type for the Expectation type
+type MockExpectation struct {
+	mock.Mock
+}
+
+type MockExpectation_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *MockExpectation) EXPECT() *MockExpectation_Expecter {
+	return &MockExpectation_Expecter{mock: &_m.Mock}
+}
+
+// GetAcceptsMessage provides a mock function with given fields:
+func (_m *MockExpectation) GetAcceptsMessage() spi.AcceptsMessage {
+	ret := _m.Called()
+
+	var r0 spi.AcceptsMessage
+	if rf, ok := ret.Get(0).(func() spi.AcceptsMessage); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(spi.AcceptsMessage)
+		}
+	}
+
+	return r0
+}
+
+// MockExpectation_GetAcceptsMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAcceptsMessage'
+type MockExpectation_GetAcceptsMessage_Call struct {
+	*mock.Call
+}
+
+// GetAcceptsMessage is a helper method to define mock.On call
+func (_e *MockExpectation_Expecter) GetAcceptsMessage() *MockExpectation_GetAcceptsMessage_Call {
+	return &MockExpectation_GetAcceptsMessage_Call{Call: _e.mock.On("GetAcceptsMessage")}
+}
+
+func (_c *MockExpectation_GetAcceptsMessage_Call) Run(run func()) *MockExpectation_GetAcceptsMessage_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockExpectation_GetAcceptsMessage_Call) Return(_a0 spi.AcceptsMessage) *MockExpectation_GetAcceptsMessage_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockExpectation_GetAcceptsMessage_Call) RunAndReturn(run func() spi.AcceptsMessage) *MockExpectation_GetAcceptsMessage_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// GetContext provides a mock function with given fields:
+func (_m *MockExpectation) GetContext() context.Context {
+	ret := _m.Called()
+
+	var r0 context.Context
+	if rf, ok := ret.Get(0).(func() context.Context); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(context.Context)
+		}
+	}
+
+	return r0
+}
+
+// MockExpectation_GetContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetContext'
+type MockExpectation_GetContext_Call struct {
+	*mock.Call
+}
+
+// GetContext is a helper method to define mock.On call
+func (_e *MockExpectation_Expecter) GetContext() *MockExpectation_GetContext_Call {
+	return &MockExpectation_GetContext_Call{Call: _e.mock.On("GetContext")}
+}
+
+func (_c *MockExpectation_GetContext_Call) Run(run func()) *MockExpectation_GetContext_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockExpectation_GetContext_Call) Return(_a0 context.Context) *MockExpectation_GetContext_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockExpectation_GetContext_Call) RunAndReturn(run func() context.Context) *MockExpectation_GetContext_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// GetExpiration provides a mock function with given fields:
+func (_m *MockExpectation) GetExpiration() time.Time {
+	ret := _m.Called()
+
+	var r0 time.Time
+	if rf, ok := ret.Get(0).(func() time.Time); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(time.Time)
+	}
+
+	return r0
+}
+
+// MockExpectation_GetExpiration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExpiration'
+type MockExpectation_GetExpiration_Call struct {
+	*mock.Call
+}
+
+// GetExpiration is a helper method to define mock.On call
+func (_e *MockExpectation_Expecter) GetExpiration() *MockExpectation_GetExpiration_Call {
+	return &MockExpectation_GetExpiration_Call{Call: _e.mock.On("GetExpiration")}
+}
+
+func (_c *MockExpectation_GetExpiration_Call) Run(run func()) *MockExpectation_GetExpiration_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockExpectation_GetExpiration_Call) Return(_a0 time.Time) *MockExpectation_GetExpiration_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockExpectation_GetExpiration_Call) RunAndReturn(run func() time.Time) *MockExpectation_GetExpiration_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// GetHandleError provides a mock function with given fields:
+func (_m *MockExpectation) GetHandleError() spi.HandleError {
+	ret := _m.Called()
+
+	var r0 spi.HandleError
+	if rf, ok := ret.Get(0).(func() spi.HandleError); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(spi.HandleError)
+		}
+	}
+
+	return r0
+}
+
+// MockExpectation_GetHandleError_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetHandleError'
+type MockExpectation_GetHandleError_Call struct {
+	*mock.Call
+}
+
+// GetHandleError is a helper method to define mock.On call
+func (_e *MockExpectation_Expecter) GetHandleError() *MockExpectation_GetHandleError_Call {
+	return &MockExpectation_GetHandleError_Call{Call: _e.mock.On("GetHandleError")}
+}
+
+func (_c *MockExpectation_GetHandleError_Call) Run(run func()) *MockExpectation_GetHandleError_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockExpectation_GetHandleError_Call) Return(_a0 spi.HandleError) *MockExpectation_GetHandleError_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockExpectation_GetHandleError_Call) RunAndReturn(run func() spi.HandleError) *MockExpectation_GetHandleError_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// GetHandleMessage provides a mock function with given fields:
+func (_m *MockExpectation) GetHandleMessage() spi.HandleMessage {
+	ret := _m.Called()
+
+	var r0 spi.HandleMessage
+	if rf, ok := ret.Get(0).(func() spi.HandleMessage); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(spi.HandleMessage)
+		}
+	}
+
+	return r0
+}
+
+// MockExpectation_GetHandleMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetHandleMessage'
+type MockExpectation_GetHandleMessage_Call struct {
+	*mock.Call
+}
+
+// GetHandleMessage is a helper method to define mock.On call
+func (_e *MockExpectation_Expecter) GetHandleMessage() *MockExpectation_GetHandleMessage_Call {
+	return &MockExpectation_GetHandleMessage_Call{Call: _e.mock.On("GetHandleMessage")}
+}
+
+func (_c *MockExpectation_GetHandleMessage_Call) Run(run func()) *MockExpectation_GetHandleMessage_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockExpectation_GetHandleMessage_Call) Return(_a0 spi.HandleMessage) *MockExpectation_GetHandleMessage_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockExpectation_GetHandleMessage_Call) RunAndReturn(run func() spi.HandleMessage) *MockExpectation_GetHandleMessage_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// String provides a mock function with given fields:
+func (_m *MockExpectation) String() string {
+	ret := _m.Called()
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// MockExpectation_String_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'String'
+type MockExpectation_String_Call struct {
+	*mock.Call
+}
+
+// String is a helper method to define mock.On call
+func (_e *MockExpectation_Expecter) String() *MockExpectation_String_Call {
+	return &MockExpectation_String_Call{Call: _e.mock.On("String")}
+}
+
+func (_c *MockExpectation_String_Call) Run(run func()) *MockExpectation_String_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockExpectation_String_Call) Return(_a0 string) *MockExpectation_String_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockExpectation_String_Call) RunAndReturn(run func() string) *MockExpectation_String_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+type mockConstructorTestingTNewMockExpectation interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMockExpectation creates a new instance of MockExpectation. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMockExpectation(t mockConstructorTestingTNewMockExpectation) *MockExpectation {
+	mock := &MockExpectation{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/plc4go/spi/default/mock_requirements.go b/plc4go/spi/default/mock_requirements.go
index 315be18e86..b0b07902c5 100644
--- a/plc4go/spi/default/mock_requirements.go
+++ b/plc4go/spi/default/mock_requirements.go
@@ -63,3 +63,8 @@ type TransportInstance interface {
 type PlcConnectionConnectResult interface {
 	plc4go.PlcConnectionConnectResult
 }
+
+// Deprecated: don't use it in productive code
+type Expectation interface {
+	spi.Expectation
+}
diff --git a/plc4go/spi/model/DefaultPlcBrowseRequestResult_plc4xgen.go b/plc4go/spi/model/DefaultPlcBrowseRequestResult_plc4xgen.go
index 8f6b1f3154..8adb4eb74d 100644
--- a/plc4go/spi/model/DefaultPlcBrowseRequestResult_plc4xgen.go
+++ b/plc4go/spi/model/DefaultPlcBrowseRequestResult_plc4xgen.go
@@ -82,7 +82,8 @@ func (d *DefaultPlcBrowseRequestResult) SerializeWithWriteBuffer(ctx context.Con
 	}
 
 	if d.Err != nil {
-		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
+		_errString := d.Err.Error()
+		if err := writeBuffer.WriteString("err", uint32(len(_errString)*8), "UTF-8", _errString); err != nil {
 			return err
 		}
 	}
diff --git a/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go b/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
index 1a22d3e0dd..03c72a1fe1 100644
--- a/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
+++ b/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
@@ -42,9 +42,8 @@ func (d *DefaultPlcConsumerRegistration) SerializeWithWriteBuffer(ctx context.Co
 	if err := writeBuffer.PushContext("PlcConsumerRegistration"); err != nil {
 		return err
 	}
-	_value := fmt.Sprintf("%v", d.consumerId)
 
-	if err := writeBuffer.WriteString("consumerId", uint32(len(_value)*8), "UTF-8", _value); err != nil {
+	if err := writeBuffer.WriteInt64("consumerId", 64, int64(d.consumerId)); err != nil {
 		return err
 	}
 
diff --git a/plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go b/plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go
index 7169484d20..b4904846e8 100644
--- a/plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go
+++ b/plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go
@@ -82,7 +82,8 @@ func (d *DefaultPlcReadRequestResult) SerializeWithWriteBuffer(ctx context.Conte
 	}
 
 	if d.Err != nil {
-		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
+		_errString := d.Err.Error()
+		if err := writeBuffer.WriteString("err", uint32(len(_errString)*8), "UTF-8", _errString); err != nil {
 			return err
 		}
 	}
diff --git a/plc4go/spi/model/DefaultPlcSubscriptionEventItem_plc4xgen.go b/plc4go/spi/model/DefaultPlcSubscriptionEventItem_plc4xgen.go
index 351a3d23dd..f45db3bcf7 100644
--- a/plc4go/spi/model/DefaultPlcSubscriptionEventItem_plc4xgen.go
+++ b/plc4go/spi/model/DefaultPlcSubscriptionEventItem_plc4xgen.go
@@ -65,10 +65,12 @@ func (d *DefaultPlcSubscriptionEventItem) SerializeWithWriteBuffer(ctx context.C
 			}
 		}
 	}
-	_value := fmt.Sprintf("%v", d.subscriptionType)
+	{
+		_value := fmt.Sprintf("%v", d.subscriptionType)
 
-	if err := writeBuffer.WriteString("subscriptionType", uint32(len(_value)*8), "UTF-8", _value); err != nil {
-		return err
+		if err := writeBuffer.WriteString("subscriptionType", uint32(len(_value)*8), "UTF-8", _value); err != nil {
+			return err
+		}
 	}
 
 	if err := writeBuffer.WriteString("interval", uint32(len(d.interval.String())*8), "UTF-8", d.interval.String()); err != nil {
diff --git a/plc4go/spi/model/DefaultPlcSubscriptionRequestResult_plc4xgen.go b/plc4go/spi/model/DefaultPlcSubscriptionRequestResult_plc4xgen.go
index dd04d7bb9f..958c29cc47 100644
--- a/plc4go/spi/model/DefaultPlcSubscriptionRequestResult_plc4xgen.go
+++ b/plc4go/spi/model/DefaultPlcSubscriptionRequestResult_plc4xgen.go
@@ -82,7 +82,8 @@ func (d *DefaultPlcSubscriptionRequestResult) SerializeWithWriteBuffer(ctx conte
 	}
 
 	if d.Err != nil {
-		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
+		_errString := d.Err.Error()
+		if err := writeBuffer.WriteString("err", uint32(len(_errString)*8), "UTF-8", _errString); err != nil {
 			return err
 		}
 	}
diff --git a/plc4go/spi/model/DefaultPlcUnsubscriptionRequestResult_plc4xgen.go b/plc4go/spi/model/DefaultPlcUnsubscriptionRequestResult_plc4xgen.go
index 2b5237bae3..66a2945b67 100644
--- a/plc4go/spi/model/DefaultPlcUnsubscriptionRequestResult_plc4xgen.go
+++ b/plc4go/spi/model/DefaultPlcUnsubscriptionRequestResult_plc4xgen.go
@@ -82,7 +82,8 @@ func (d *DefaultPlcUnsubscriptionRequestResult) SerializeWithWriteBuffer(ctx con
 	}
 
 	if d.Err != nil {
-		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
+		_errString := d.Err.Error()
+		if err := writeBuffer.WriteString("err", uint32(len(_errString)*8), "UTF-8", _errString); err != nil {
 			return err
 		}
 	}
diff --git a/plc4go/spi/model/DefaultPlcWriteRequestResult_plc4xgen.go b/plc4go/spi/model/DefaultPlcWriteRequestResult_plc4xgen.go
index 66cc2337c7..0a05980b46 100644
--- a/plc4go/spi/model/DefaultPlcWriteRequestResult_plc4xgen.go
+++ b/plc4go/spi/model/DefaultPlcWriteRequestResult_plc4xgen.go
@@ -82,7 +82,8 @@ func (d *DefaultPlcWriteRequestResult) SerializeWithWriteBuffer(ctx context.Cont
 	}
 
 	if d.Err != nil {
-		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
+		_errString := d.Err.Error()
+		if err := writeBuffer.WriteString("err", uint32(len(_errString)*8), "UTF-8", _errString); err != nil {
 			return err
 		}
 	}
diff --git a/plc4go/spi/pool/WorkerPool.go b/plc4go/spi/pool/WorkerPool.go
index d83e770dc9..52a0c4df2b 100644
--- a/plc4go/spi/pool/WorkerPool.go
+++ b/plc4go/spi/pool/WorkerPool.go
@@ -28,6 +28,11 @@ import (
 
 type Runnable func()
 
+type CompletionFuture interface {
+	AwaitCompletion(ctx context.Context) error
+	Cancel(interrupt bool, err error)
+}
+
 type Executor interface {
 	io.Closer
 	Start()
diff --git a/plc4go/spi/pool/dynamicExecutor.go b/plc4go/spi/pool/dynamicExecutor.go
index ae4135d60a..3af93a9244 100644
--- a/plc4go/spi/pool/dynamicExecutor.go
+++ b/plc4go/spi/pool/dynamicExecutor.go
@@ -20,7 +20,6 @@
 package pool
 
 import (
-	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/utils"
 	"github.com/rs/zerolog"
 	"runtime/debug"
@@ -33,6 +32,7 @@ var upScaleInterval = 100 * time.Millisecond
 var downScaleInterval = 5 * time.Second
 var timeToBecomeUnused = 5 * time.Second
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=dynamicExecutor
 type dynamicExecutor struct {
 	*executor
 
@@ -172,15 +172,3 @@ func (e *dynamicExecutor) Stop() {
 	e.dynamicWorkers.Wait()
 	e.log.Trace().Msg("stopped")
 }
-
-func (e *dynamicExecutor) String() string {
-	return fmt.Sprintf("dynamicExecutor{\n"+
-		"\texecutor: %s\n"+
-		"\tmaxNumberOfWorkers: %d\n"+
-		"\tcurrentNumberOfWorkers: %d\n"+
-		"}",
-		e.executor,
-		e.maxNumberOfWorkers,
-		e.currentNumberOfWorkers.Load(),
-	)
-}
diff --git a/plc4go/spi/pool/dynamicExecutor_plc4xgen.go b/plc4go/spi/pool/dynamicExecutor_plc4xgen.go
new file mode 100644
index 0000000000..6f7ce184ac
--- /dev/null
+++ b/plc4go/spi/pool/dynamicExecutor_plc4xgen.go
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=dynamicExecutor"; DO NOT EDIT.
+
+package pool
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *dynamicExecutor) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *dynamicExecutor) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("dynamicExecutor"); err != nil {
+		return err
+	}
+	if err := d.executor.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteInt64("maxNumberOfWorkers", 64, int64(d.maxNumberOfWorkers)); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteInt32("currentNumberOfWorkers", 32, d.currentNumberOfWorkers.Load()); err != nil {
+		return err
+	}
+
+	_interrupter_plx4gen_description := fmt.Sprintf("%d element(s)", len(d.interrupter))
+	if err := writeBuffer.WriteString("interrupter", uint32(len(_interrupter_plx4gen_description)*8), "UTF-8", _interrupter_plx4gen_description); err != nil {
+		return err
+	}
+	if err := writeBuffer.PopContext("dynamicExecutor"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *dynamicExecutor) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/spi/pool/dynamicExecutor_test.go b/plc4go/spi/pool/dynamicExecutor_test.go
index 190fceb41d..531867a71f 100644
--- a/plc4go/spi/pool/dynamicExecutor_test.go
+++ b/plc4go/spi/pool/dynamicExecutor_test.go
@@ -183,22 +183,32 @@ func Test_dynamicExecutor_String(t *testing.T) {
 		{
 			name: "string it",
 			fields: fields{
-				executor:           &executor{},
+				executor: &executor{
+					worker: []*worker{
+						{},
+					},
+				},
 				maxNumberOfWorkers: 3,
 			},
-			want: "dynamicExecutor{\n" +
-				"\texecutor: executor{\n" +
-				"\trunning: false,\n" +
-				"\tshutdown: false,\n" +
-				"\tworker: [],\n" +
-				"\tqueueDepth: 0,\n" +
-				"\tworkItems: 0 elements,\n" +
-				"\ttraceWorkers: false,\n" +
-				"\n" +
-				"}\n" +
-				"\tmaxNumberOfWorkers: 3\n" +
-				"\tcurrentNumberOfWorkers: 0\n" +
-				"}",
+			want: `
+╔═dynamicExecutor═══════════════════════════════════════════════════════════════════════════════════════════╗
+║╔═executor════════════════════════════════════════════════════════════════════════════════════════════════╗║
+║║╔═running╗╔═shutdown╗                                                                                    ║║
+║║║b0 false║║b0 false ║                                                                                    ║║
+║║╚════════╝╚═════════╝                                                                                    ║║
+║║╔═worker/value/worker═══════════════════════════════════════════════════════════════════════════════════╗║║
+║║║╔═id═════════════════╗╔═shutdown╗╔═interrupted╗╔═interrupter╗╔═hasEnded╗╔═lastReceived════════════════╗║║║
+║║║║0x0000000000000000 0║║b0 false ║║  b0 false  ║║0 element(s)║║b0 false ║║0001-01-01 00:00:00 +0000 UTC║║║║
+║║║╚════════════════════╝╚═════════╝╚════════════╝╚════════════╝╚═════════╝╚═════════════════════════════╝║║║
+║║╚═══════════════════════════════════════════════════════════════════════════════════════════════════════╝║║
+║║╔═queueDepth═════════╗╔═workItems══╗╔═traceWorkers╗                                                      ║║
+║║║0x0000000000000000 0║║0 element(s)║║  b0 false   ║                                                      ║║
+║║╚════════════════════╝╚════════════╝╚═════════════╝                                                      ║║
+║╚═════════════════════════════════════════════════════════════════════════════════════════════════════════╝║
+║╔═maxNumberOfWorkers═╗╔═currentNumberOfWorkers╗╔═interrupter╗                                              ║
+║║0x0000000000000003 3║║     0x00000000 0      ║║0 element(s)║                                              ║
+║╚════════════════════╝╚═══════════════════════╝╚════════════╝                                              ║
+╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/pool/executor.go b/plc4go/spi/pool/executor.go
index 0e8e458903..104c7feae6 100644
--- a/plc4go/spi/pool/executor.go
+++ b/plc4go/spi/pool/executor.go
@@ -21,7 +21,6 @@ package pool
 
 import (
 	"context"
-	"fmt"
 	"sync"
 	"sync/atomic"
 
@@ -29,6 +28,7 @@ import (
 	"github.com/rs/zerolog"
 )
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=executor
 type executor struct {
 	running      bool
 	shutdown     bool
@@ -40,7 +40,7 @@ type executor struct {
 
 	workerWaitGroup sync.WaitGroup
 
-	log zerolog.Logger
+	log zerolog.Logger `ignore:"true"`
 }
 
 func (e *executor) isTraceWorkers() bool {
@@ -128,21 +128,3 @@ func (e *executor) Close() error {
 func (e *executor) IsRunning() bool {
 	return e.running && !e.shutdown
 }
-
-func (e *executor) String() string {
-	return fmt.Sprintf("executor{\n"+
-		"\trunning: %t,\n"+
-		"\tshutdown: %t,\n"+
-		"\tworker: %s,\n"+
-		"\tqueueDepth: %d,\n"+
-		"\tworkItems: %d elements,\n"+
-		"\ttraceWorkers: %t,\n"+
-		"\n}",
-		e.running,
-		e.shutdown,
-		e.worker,
-		e.queueDepth,
-		len(e.workItems),
-		e.traceWorkers,
-	)
-}
diff --git a/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go b/plc4go/spi/pool/executor_plc4xgen.go
similarity index 59%
copy from plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
copy to plc4go/spi/pool/executor_plc4xgen.go
index 1a22d3e0dd..7278d348a0 100644
--- a/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
+++ b/plc4go/spi/pool/executor_plc4xgen.go
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-// Code generated by "plc4xgenerator -type=DefaultPlcConsumerRegistration"; DO NOT EDIT.
+// Code generated by "plc4xgenerator -type=executor"; DO NOT EDIT.
 
-package model
+package pool
 
 import (
 	"context"
@@ -30,7 +30,7 @@ import (
 
 var _ = fmt.Printf
 
-func (d *DefaultPlcConsumerRegistration) Serialize() ([]byte, error) {
+func (d *executor) Serialize() ([]byte, error) {
 	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
 	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
 		return nil, err
@@ -38,38 +38,22 @@ func (d *DefaultPlcConsumerRegistration) Serialize() ([]byte, error) {
 	return wb.GetBytes(), nil
 }
 
-func (d *DefaultPlcConsumerRegistration) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
-	if err := writeBuffer.PushContext("PlcConsumerRegistration"); err != nil {
+func (d *executor) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("executor"); err != nil {
 		return err
 	}
-	_value := fmt.Sprintf("%v", d.consumerId)
 
-	if err := writeBuffer.WriteString("consumerId", uint32(len(_value)*8), "UTF-8", _value); err != nil {
+	if err := writeBuffer.WriteBit("running", d.running); err != nil {
 		return err
 	}
 
-	if d.plcSubscriber != nil {
-		if serializableField, ok := d.plcSubscriber.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("plcSubscriber"); err != nil {
-				return err
-			}
-			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-				return err
-			}
-			if err := writeBuffer.PopContext("plcSubscriber"); err != nil {
-				return err
-			}
-		} else {
-			stringValue := fmt.Sprintf("%v", d.plcSubscriber)
-			if err := writeBuffer.WriteString("plcSubscriber", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
-				return err
-			}
-		}
+	if err := writeBuffer.WriteBit("shutdown", d.shutdown); err != nil {
+		return err
 	}
-	if err := writeBuffer.PushContext("handles", utils.WithRenderAsList(true)); err != nil {
+	if err := writeBuffer.PushContext("worker", utils.WithRenderAsList(true)); err != nil {
 		return err
 	}
-	for _, elem := range d.handles {
+	for _, elem := range d.worker {
 		var elem any = elem
 
 		if elem != nil {
@@ -91,16 +75,29 @@ func (d *DefaultPlcConsumerRegistration) SerializeWithWriteBuffer(ctx context.Co
 			}
 		}
 	}
-	if err := writeBuffer.PopContext("handles", utils.WithRenderAsList(true)); err != nil {
+	if err := writeBuffer.PopContext("worker", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteInt64("queueDepth", 64, int64(d.queueDepth)); err != nil {
+		return err
+	}
+
+	_workItems_plx4gen_description := fmt.Sprintf("%d element(s)", len(d.workItems))
+	if err := writeBuffer.WriteString("workItems", uint32(len(_workItems_plx4gen_description)*8), "UTF-8", _workItems_plx4gen_description); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("traceWorkers", d.traceWorkers); err != nil {
 		return err
 	}
-	if err := writeBuffer.PopContext("PlcConsumerRegistration"); err != nil {
+	if err := writeBuffer.PopContext("executor"); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (d *DefaultPlcConsumerRegistration) String() string {
+func (d *executor) String() string {
 	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
 	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
 		return err.Error()
diff --git a/plc4go/spi/pool/executor_test.go b/plc4go/spi/pool/executor_test.go
index 577ce986c0..229a7d9797 100644
--- a/plc4go/spi/pool/executor_test.go
+++ b/plc4go/spi/pool/executor_test.go
@@ -445,21 +445,20 @@ func Test_executor_String(t *testing.T) {
 				queueDepth:   2,
 				traceWorkers: true,
 			},
-			want: "executor{\n" +
-				"\trunning: true,\n" +
-				"\tshutdown: true,\n" +
-				"\tworker: [worker{\n" +
-				"\tid: 1,\n" +
-				"\tshutdown: false,\n" +
-				"\tinterrupted: false,\n" +
-				"\thasEnded: false,\n" +
-				"\tlastReceived: 0001-01-01 00:00:00 +0000 UTC,\n" +
-				"}],\n" +
-				"\tqueueDepth: 2,\n" +
-				"\tworkItems: 0 elements,\n" +
-				"\ttraceWorkers: true,\n" +
-				"\n" +
-				"}",
+			want: `
+╔═executor════════════════════════════════════════════════════════════════════════════════════════════════╗
+║╔═running╗╔═shutdown╗                                                                                    ║
+║║b1 true ║║ b1 true ║                                                                                    ║
+║╚════════╝╚═════════╝                                                                                    ║
+║╔═worker/value/worker═══════════════════════════════════════════════════════════════════════════════════╗║
+║║╔═id═════════════════╗╔═shutdown╗╔═interrupted╗╔═interrupter╗╔═hasEnded╗╔═lastReceived════════════════╗║║
+║║║0x0000000000000001 1║║b0 false ║║  b0 false  ║║0 element(s)║║b0 false ║║0001-01-01 00:00:00 +0000 UTC║║║
+║║╚════════════════════╝╚═════════╝╚════════════╝╚════════════╝╚═════════╝╚═════════════════════════════╝║║
+║╚═══════════════════════════════════════════════════════════════════════════════════════════════════════╝║
+║╔═queueDepth═════════╗╔═workItems══╗╔═traceWorkers╗                                                      ║
+║║0x0000000000000002 2║║0 element(s)║║   b1 true   ║                                                      ║
+║╚════════════════════╝╚════════════╝╚═════════════╝                                                      ║
+╚═════════════════════════════════════════════════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/pool/CompletionFuture.go b/plc4go/spi/pool/future.go
similarity index 80%
rename from plc4go/spi/pool/CompletionFuture.go
rename to plc4go/spi/pool/future.go
index 5d11002356..cc55be09e0 100644
--- a/plc4go/spi/pool/CompletionFuture.go
+++ b/plc4go/spi/pool/future.go
@@ -21,18 +21,13 @@ package pool
 
 import (
 	"context"
-	"fmt"
 	"sync/atomic"
 	"time"
 
 	"github.com/pkg/errors"
 )
 
-type CompletionFuture interface {
-	AwaitCompletion(ctx context.Context) error
-	Cancel(interrupt bool, err error)
-}
-
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=future
 type future struct {
 	cancelRequested    atomic.Bool
 	interruptRequested atomic.Bool
@@ -72,19 +67,3 @@ func (f *future) AwaitCompletion(ctx context.Context) error {
 	}
 	return nil
 }
-
-func (f *future) String() string {
-	return fmt.Sprintf("future{\n"+
-		"\tcancelRequested: %t,\n"+
-		"\tinterruptRequested: %t,\n"+
-		"\tcompleted: %t,\n"+
-		"\terrored: %t,\n"+
-		"\terr: %v,\n"+
-		"}",
-		f.cancelRequested.Load(),
-		f.interruptRequested.Load(),
-		f.completed.Load(),
-		f.errored.Load(),
-		f.err.Load(),
-	)
-}
diff --git a/plc4go/spi/model/DefaultPlcBrowseRequestResult_plc4xgen.go b/plc4go/spi/pool/future_plc4xgen.go
similarity index 50%
copy from plc4go/spi/model/DefaultPlcBrowseRequestResult_plc4xgen.go
copy to plc4go/spi/pool/future_plc4xgen.go
index 8f6b1f3154..65cb2c0622 100644
--- a/plc4go/spi/model/DefaultPlcBrowseRequestResult_plc4xgen.go
+++ b/plc4go/spi/pool/future_plc4xgen.go
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-// Code generated by "plc4xgenerator -type=DefaultPlcBrowseRequestResult"; DO NOT EDIT.
+// Code generated by "plc4xgenerator -type=future"; DO NOT EDIT.
 
-package model
+package pool
 
 import (
 	"context"
@@ -30,7 +30,7 @@ import (
 
 var _ = fmt.Printf
 
-func (d *DefaultPlcBrowseRequestResult) Serialize() ([]byte, error) {
+func (d *future) Serialize() ([]byte, error) {
 	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
 	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
 		return nil, err
@@ -38,61 +38,52 @@ func (d *DefaultPlcBrowseRequestResult) Serialize() ([]byte, error) {
 	return wb.GetBytes(), nil
 }
 
-func (d *DefaultPlcBrowseRequestResult) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
-	if err := writeBuffer.PushContext("PlcBrowseRequestResult"); err != nil {
+func (d *future) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("future"); err != nil {
 		return err
 	}
 
-	if d.Request != nil {
-		if serializableField, ok := d.Request.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("request"); err != nil {
-				return err
-			}
-			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-				return err
-			}
-			if err := writeBuffer.PopContext("request"); err != nil {
-				return err
-			}
-		} else {
-			stringValue := fmt.Sprintf("%v", d.Request)
-			if err := writeBuffer.WriteString("request", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
-				return err
-			}
-		}
+	if err := writeBuffer.WriteBit("cancelRequested", d.cancelRequested.Load()); err != nil {
+		return err
 	}
 
-	if d.Response != nil {
-		if serializableField, ok := d.Response.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("response"); err != nil {
+	if err := writeBuffer.WriteBit("interruptRequested", d.interruptRequested.Load()); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("completed", d.completed.Load()); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("errored", d.errored.Load()); err != nil {
+		return err
+	}
+
+	if d.err.Load() != nil {
+		if serializableField, ok := d.err.Load().(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("err"); err != nil {
 				return err
 			}
 			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
 				return err
 			}
-			if err := writeBuffer.PopContext("response"); err != nil {
+			if err := writeBuffer.PopContext("err"); err != nil {
 				return err
 			}
 		} else {
-			stringValue := fmt.Sprintf("%v", d.Response)
-			if err := writeBuffer.WriteString("response", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+			stringValue := fmt.Sprintf("%v", d.err.Load())
+			if err := writeBuffer.WriteString("err", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
 				return err
 			}
 		}
 	}
-
-	if d.Err != nil {
-		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
-			return err
-		}
-	}
-	if err := writeBuffer.PopContext("PlcBrowseRequestResult"); err != nil {
+	if err := writeBuffer.PopContext("future"); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (d *DefaultPlcBrowseRequestResult) String() string {
+func (d *future) String() string {
 	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
 	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
 		return err.Error()
diff --git a/plc4go/spi/pool/CompletionFuture_test.go b/plc4go/spi/pool/future_test.go
similarity index 85%
rename from plc4go/spi/pool/CompletionFuture_test.go
rename to plc4go/spi/pool/future_test.go
index 79fdaeace7..8d32051725 100644
--- a/plc4go/spi/pool/CompletionFuture_test.go
+++ b/plc4go/spi/pool/future_test.go
@@ -158,7 +158,12 @@ func Test_future_String(t *testing.T) {
 	}{
 		{
 			name: "string it",
-			want: "future{\n\tcancelRequested: false,\n\tinterruptRequested: false,\n\tcompleted: false,\n\terrored: false,\n\terr: <nil>,\n}",
+			want: `
+╔═future══════════════════════════════════════════════════════╗
+║╔═cancelRequested╗╔═interruptRequested╗╔═completed╗╔═errored╗║
+║║    b0 false    ║║     b0 false      ║║ b0 false ║║b0 false║║
+║╚════════════════╝╚═══════════════════╝╚══════════╝╚════════╝║
+╚═════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/pool/workItem.go b/plc4go/spi/pool/workItem.go
index 233df1315d..437355145e 100644
--- a/plc4go/spi/pool/workItem.go
+++ b/plc4go/spi/pool/workItem.go
@@ -19,22 +19,9 @@
 
 package pool
 
-import "fmt"
-
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=workItem
 type workItem struct {
 	workItemId       int32
-	runnable         Runnable
+	runnable         Runnable `ignore:"true"`
 	completionFuture *future
 }
-
-func (w workItem) String() string {
-	return fmt.Sprintf("workItem{\n"+
-		"\twid: %d,\n"+
-		"\trunnable: %t,\n"+
-		"\tcompletionFuture: %s,\n"+
-		"}",
-		w.workItemId,
-		w.runnable != nil,
-		w.completionFuture,
-	)
-}
diff --git a/plc4go/spi/pool/workItem_plc4xgen.go b/plc4go/spi/pool/workItem_plc4xgen.go
new file mode 100644
index 0000000000..d32f597b02
--- /dev/null
+++ b/plc4go/spi/pool/workItem_plc4xgen.go
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=workItem"; DO NOT EDIT.
+
+package pool
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *workItem) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *workItem) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("workItem"); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteInt32("workItemId", 32, int32(d.workItemId)); err != nil {
+		return err
+	}
+	{
+		_value := fmt.Sprintf("%v", d.completionFuture)
+
+		if err := writeBuffer.WriteString("completionFuture", uint32(len(_value)*8), "UTF-8", _value); err != nil {
+			return err
+		}
+	}
+	if err := writeBuffer.PopContext("workItem"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *workItem) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/spi/pool/workItem_test.go b/plc4go/spi/pool/workItem_test.go
index 1477f69012..8d92f3ee39 100644
--- a/plc4go/spi/pool/workItem_test.go
+++ b/plc4go/spi/pool/workItem_test.go
@@ -37,11 +37,19 @@ func Test_workItem_String(t *testing.T) {
 	}{
 		{
 			name: "Simple test",
-			want: "workItem{\n" +
-				"\twid: 0,\n" +
-				"\trunnable: false,\n" +
-				"\tcompletionFuture: <nil>,\n" +
-				"}",
+			fields: fields{
+				completionFuture: &future{},
+			},
+			want: `
+╔═workItem══════════════════════════════════════════════════════════════════════╗
+║╔═workItemId═╗╔═completionFuture══════════════════════════════════════════════╗║
+║║0x00000000 0║║╔═future══════════════════════════════════════════════════════╗║║
+║╚════════════╝║║╔═cancelRequested╗╔═interruptRequested╗╔═completed╗╔═errored╗║║║
+║              ║║║    b0 false    ║║     b0 false      ║║ b0 false ║║b0 false║║║║
+║              ║║╚════════════════╝╚═══════════════════╝╚══════════╝╚════════╝║║║
+║              ║╚═════════════════════════════════════════════════════════════╝║║
+║              ╚═══════════════════════════════════════════════════════════════╝║
+╚═══════════════════════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/pool/worker.go b/plc4go/spi/pool/worker.go
index 77909cd1b6..15313dd6ee 100644
--- a/plc4go/spi/pool/worker.go
+++ b/plc4go/spi/pool/worker.go
@@ -20,7 +20,6 @@
 package pool
 
 import (
-	"fmt"
 	"runtime/debug"
 	"sync"
 	"sync/atomic"
@@ -29,6 +28,7 @@ import (
 	"github.com/rs/zerolog"
 )
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=worker
 type worker struct {
 	id          int
 	shutdown    atomic.Bool
@@ -40,9 +40,9 @@ type worker struct {
 		getWorkerWaitGroup() *sync.WaitGroup
 	}
 	hasEnded     atomic.Bool
-	lastReceived time.Time
+	lastReceived time.Time `stringer:"true"`
 
-	log zerolog.Logger
+	log zerolog.Logger `ignore:"true"`
 }
 
 func (w *worker) initialize() {
@@ -95,19 +95,3 @@ func (w *worker) work() {
 	w.hasEnded.Store(true)
 	workerLog.Debug().Msg("setting to ended")
 }
-
-func (w *worker) String() string {
-	return fmt.Sprintf("worker{\n"+
-		"\tid: %d,\n"+
-		"\tshutdown: %v,\n"+
-		"\tinterrupted: %t,\n"+
-		"\thasEnded: %t,\n"+
-		"\tlastReceived: %s,\n"+
-		"}",
-		w.id,
-		w.shutdown.Load(),
-		w.interrupted.Load(),
-		w.hasEnded.Load(),
-		w.lastReceived,
-	)
-}
diff --git a/plc4go/spi/pool/worker_plc4xgen.go b/plc4go/spi/pool/worker_plc4xgen.go
new file mode 100644
index 0000000000..85a6f1767c
--- /dev/null
+++ b/plc4go/spi/pool/worker_plc4xgen.go
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=worker"; DO NOT EDIT.
+
+package pool
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *worker) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *worker) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("worker"); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteInt64("id", 64, int64(d.id)); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("shutdown", d.shutdown.Load()); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("interrupted", d.interrupted.Load()); err != nil {
+		return err
+	}
+
+	_interrupter_plx4gen_description := fmt.Sprintf("%d element(s)", len(d.interrupter))
+	if err := writeBuffer.WriteString("interrupter", uint32(len(_interrupter_plx4gen_description)*8), "UTF-8", _interrupter_plx4gen_description); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("hasEnded", d.hasEnded.Load()); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteString("lastReceived", uint32(len(d.lastReceived.String())*8), "UTF-8", d.lastReceived.String()); err != nil {
+		return err
+	}
+	if err := writeBuffer.PopContext("worker"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *worker) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/spi/pool/worker_test.go b/plc4go/spi/pool/worker_test.go
index 31c0ece2c0..446885028b 100644
--- a/plc4go/spi/pool/worker_test.go
+++ b/plc4go/spi/pool/worker_test.go
@@ -238,7 +238,12 @@ func Test_worker_String(t *testing.T) {
 	}{
 		{
 			name: "string it",
-			want: "worker{\n\tid: 0,\n\tshutdown: false,\n\tinterrupted: false,\n\thasEnded: false,\n\tlastReceived: 0001-01-01 00:00:00 +0000 UTC,\n}",
+			want: `
+╔═worker════════════════════════════════════════════════════════════════════════════════════════════════╗
+║╔═id═════════════════╗╔═shutdown╗╔═interrupted╗╔═interrupter╗╔═hasEnded╗╔═lastReceived════════════════╗║
+║║0x0000000000000000 0║║b0 false ║║  b0 false  ║║0 element(s)║║b0 false ║║0001-01-01 00:00:00 +0000 UTC║║
+║╚════════════════════╝╚═════════╝╚════════════╝╚════════════╝╚═════════╝╚═════════════════════════════╝║
+╚═══════════════════════════════════════════════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/tracer/Tracer.go b/plc4go/spi/tracer/Tracer.go
index 9d09de03cf..29009c9a66 100644
--- a/plc4go/spi/tracer/Tracer.go
+++ b/plc4go/spi/tracer/Tracer.go
@@ -42,38 +42,49 @@ type Provider interface {
 	GetTracer() *Tracer
 }
 
-type Tracer struct {
-	connectionId string
-	traceEntries []TraceEntry
-
-	log zerolog.Logger
+type Tracer interface {
+	GetConnectionId() string
+	SetConnectionId(connectionId string)
+	ResetTraces()
+	GetTraces() []TraceEntry
+	AddTrace(operation string, message string)
+	AddTransactionalStartTrace(operation string, message string) string
+	AddTransactionalTrace(transactionId string, operation string, message string)
+	FilterTraces(traces []TraceEntry, connectionIdFilter string, transactionIdFilter string, operationFilter string, messageFilter string) []TraceEntry
 }
 
-func NewTracer(connectionId string, _options ...options.WithOption) *Tracer {
-	return &Tracer{
+func NewTracer(connectionId string, _options ...options.WithOption) Tracer {
+	return &tracer{
 		connectionId: connectionId,
 		traceEntries: []TraceEntry{},
 		log:          options.ExtractCustomLogger(_options...),
 	}
 }
 
-func (t *Tracer) GetConnectionId() string {
+type tracer struct {
+	connectionId string
+	traceEntries []TraceEntry
+
+	log zerolog.Logger
+}
+
+func (t *tracer) GetConnectionId() string {
 	return t.connectionId
 }
 
-func (t *Tracer) SetConnectionId(connectionId string) {
+func (t *tracer) SetConnectionId(connectionId string) {
 	t.connectionId = connectionId
 }
 
-func (t *Tracer) ResetTraces() {
+func (t *tracer) ResetTraces() {
 	t.traceEntries = []TraceEntry{}
 }
 
-func (t *Tracer) GetTraces() []TraceEntry {
+func (t *tracer) GetTraces() []TraceEntry {
 	return t.traceEntries
 }
 
-func (t *Tracer) AddTrace(operation string, message string) {
+func (t *tracer) AddTrace(operation string, message string) {
 	t.traceEntries = append(t.traceEntries, TraceEntry{
 		Timestamp:     time.Now(),
 		ConnectionId:  t.connectionId,
@@ -83,7 +94,7 @@ func (t *Tracer) AddTrace(operation string, message string) {
 	})
 }
 
-func (t *Tracer) AddTransactionalStartTrace(operation string, message string) string {
+func (t *tracer) AddTransactionalStartTrace(operation string, message string) string {
 	transactionId := utils.GenerateId(t.log, 4)
 	t.traceEntries = append(t.traceEntries, TraceEntry{
 		Timestamp:     time.Now(),
@@ -95,7 +106,7 @@ func (t *Tracer) AddTransactionalStartTrace(operation string, message string) st
 	return transactionId
 }
 
-func (t *Tracer) AddTransactionalTrace(transactionId string, operation string, message string) {
+func (t *tracer) AddTransactionalTrace(transactionId string, operation string, message string) {
 	t.traceEntries = append(t.traceEntries, TraceEntry{
 		Timestamp:     time.Now(),
 		ConnectionId:  t.connectionId,
@@ -105,7 +116,7 @@ func (t *Tracer) AddTransactionalTrace(transactionId string, operation string, m
 	})
 }
 
-func (t *Tracer) FilterTraces(traces []TraceEntry, connectionIdFilter string, transactionIdFilter string, operationFilter string, messageFilter string) []TraceEntry {
+func (t *tracer) FilterTraces(traces []TraceEntry, connectionIdFilter string, transactionIdFilter string, operationFilter string, messageFilter string) []TraceEntry {
 	var result []TraceEntry
 traceFiltering:
 	for _, trace := range traces {
@@ -126,6 +137,6 @@ traceFiltering:
 	return result
 }
 
-func (t *Tracer) String() string {
+func (t *tracer) String() string {
 	return fmt.Sprintf("Tracer for %s", t.connectionId)
 }
diff --git a/plc4go/spi/tracer/Tracer_test.go b/plc4go/spi/tracer/Tracer_test.go
index 1c4008185b..fde1eb1b89 100644
--- a/plc4go/spi/tracer/Tracer_test.go
+++ b/plc4go/spi/tracer/Tracer_test.go
@@ -32,11 +32,11 @@ func TestNewTracer(t *testing.T) {
 	tests := []struct {
 		name string
 		args args
-		want *Tracer
+		want Tracer
 	}{
 		{
 			name: "create it",
-			want: &Tracer{
+			want: &tracer{
 				traceEntries: []TraceEntry{},
 			},
 		},
@@ -48,7 +48,7 @@ func TestNewTracer(t *testing.T) {
 	}
 }
 
-func TestTracer_AddTrace(t1 *testing.T) {
+func Test_tracer_AddTrace(t1 *testing.T) {
 	type fields struct {
 		connectionId string
 		traceEntries []TraceEntry
@@ -68,7 +68,7 @@ func TestTracer_AddTrace(t1 *testing.T) {
 	}
 	for _, tt := range tests {
 		t1.Run(tt.name, func(t1 *testing.T) {
-			t := &Tracer{
+			t := &tracer{
 				connectionId: tt.fields.connectionId,
 				traceEntries: tt.fields.traceEntries,
 			}
@@ -77,7 +77,7 @@ func TestTracer_AddTrace(t1 *testing.T) {
 	}
 }
 
-func TestTracer_AddTransactionalStartTrace(t1 *testing.T) {
+func Test_tracer_AddTransactionalStartTrace(t1 *testing.T) {
 	type fields struct {
 		connectionId string
 		traceEntries []TraceEntry
@@ -97,7 +97,7 @@ func TestTracer_AddTransactionalStartTrace(t1 *testing.T) {
 	}
 	for _, tt := range tests {
 		t1.Run(tt.name, func(t1 *testing.T) {
-			t := &Tracer{
+			t := &tracer{
 				connectionId: tt.fields.connectionId,
 				traceEntries: tt.fields.traceEntries,
 			}
@@ -107,7 +107,7 @@ func TestTracer_AddTransactionalStartTrace(t1 *testing.T) {
 	}
 }
 
-func TestTracer_AddTransactionalTrace(t1 *testing.T) {
+func Test_tracer_AddTransactionalTrace(t1 *testing.T) {
 	type fields struct {
 		connectionId string
 		traceEntries []TraceEntry
@@ -128,7 +128,7 @@ func TestTracer_AddTransactionalTrace(t1 *testing.T) {
 	}
 	for _, tt := range tests {
 		t1.Run(tt.name, func(t1 *testing.T) {
-			t := &Tracer{
+			t := &tracer{
 				connectionId: tt.fields.connectionId,
 				traceEntries: tt.fields.traceEntries,
 			}
@@ -137,7 +137,7 @@ func TestTracer_AddTransactionalTrace(t1 *testing.T) {
 	}
 }
 
-func TestTracer_FilterTraces(t1 *testing.T) {
+func Test_tracer_FilterTraces(t1 *testing.T) {
 	type fields struct {
 		connectionId string
 		traceEntries []TraceEntry
@@ -213,7 +213,7 @@ func TestTracer_FilterTraces(t1 *testing.T) {
 	}
 	for _, tt := range tests {
 		t1.Run(tt.name, func(t1 *testing.T) {
-			t := &Tracer{
+			t := &tracer{
 				connectionId: tt.fields.connectionId,
 				traceEntries: tt.fields.traceEntries,
 			}
@@ -222,7 +222,7 @@ func TestTracer_FilterTraces(t1 *testing.T) {
 	}
 }
 
-func TestTracer_GetConnectionId(t1 *testing.T) {
+func Test_tracer_GetConnectionId(t1 *testing.T) {
 	type fields struct {
 		connectionId string
 		traceEntries []TraceEntry
@@ -238,7 +238,7 @@ func TestTracer_GetConnectionId(t1 *testing.T) {
 	}
 	for _, tt := range tests {
 		t1.Run(tt.name, func(t1 *testing.T) {
-			t := &Tracer{
+			t := &tracer{
 				connectionId: tt.fields.connectionId,
 				traceEntries: tt.fields.traceEntries,
 			}
@@ -247,7 +247,7 @@ func TestTracer_GetConnectionId(t1 *testing.T) {
 	}
 }
 
-func TestTracer_GetTraces(t1 *testing.T) {
+func Test_tracer_GetTraces(t1 *testing.T) {
 	type fields struct {
 		connectionId string
 		traceEntries []TraceEntry
@@ -263,7 +263,7 @@ func TestTracer_GetTraces(t1 *testing.T) {
 	}
 	for _, tt := range tests {
 		t1.Run(tt.name, func(t1 *testing.T) {
-			t := &Tracer{
+			t := &tracer{
 				connectionId: tt.fields.connectionId,
 				traceEntries: tt.fields.traceEntries,
 			}
@@ -272,7 +272,7 @@ func TestTracer_GetTraces(t1 *testing.T) {
 	}
 }
 
-func TestTracer_ResetTraces(t1 *testing.T) {
+func Test_tracer_ResetTraces(t1 *testing.T) {
 	type fields struct {
 		connectionId string
 		traceEntries []TraceEntry
@@ -287,7 +287,7 @@ func TestTracer_ResetTraces(t1 *testing.T) {
 	}
 	for _, tt := range tests {
 		t1.Run(tt.name, func(t1 *testing.T) {
-			t := &Tracer{
+			t := &tracer{
 				connectionId: tt.fields.connectionId,
 				traceEntries: tt.fields.traceEntries,
 			}
@@ -296,7 +296,7 @@ func TestTracer_ResetTraces(t1 *testing.T) {
 	}
 }
 
-func TestTracer_SetConnectionId(t1 *testing.T) {
+func Test_tracer_SetConnectionId(t1 *testing.T) {
 	type fields struct {
 		connectionId string
 		traceEntries []TraceEntry
@@ -315,7 +315,7 @@ func TestTracer_SetConnectionId(t1 *testing.T) {
 	}
 	for _, tt := range tests {
 		t1.Run(tt.name, func(t1 *testing.T) {
-			t := &Tracer{
+			t := &tracer{
 				connectionId: tt.fields.connectionId,
 				traceEntries: tt.fields.traceEntries,
 			}
diff --git a/plc4go/spi/tracer/mock_Tracer_test.go b/plc4go/spi/tracer/mock_Tracer_test.go
new file mode 100644
index 0000000000..0aa7839ff3
--- /dev/null
+++ b/plc4go/spi/tracer/mock_Tracer_test.go
@@ -0,0 +1,361 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by mockery v2.29.0. DO NOT EDIT.
+
+package tracer
+
+import mock "github.com/stretchr/testify/mock"
+
+// MockTracer is an autogenerated mock type for the Tracer type
+type MockTracer struct {
+	mock.Mock
+}
+
+type MockTracer_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *MockTracer) EXPECT() *MockTracer_Expecter {
+	return &MockTracer_Expecter{mock: &_m.Mock}
+}
+
+// AddTrace provides a mock function with given fields: operation, message
+func (_m *MockTracer) AddTrace(operation string, message string) {
+	_m.Called(operation, message)
+}
+
+// MockTracer_AddTrace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddTrace'
+type MockTracer_AddTrace_Call struct {
+	*mock.Call
+}
+
+// AddTrace is a helper method to define mock.On call
+//   - operation string
+//   - message string
+func (_e *MockTracer_Expecter) AddTrace(operation interface{}, message interface{}) *MockTracer_AddTrace_Call {
+	return &MockTracer_AddTrace_Call{Call: _e.mock.On("AddTrace", operation, message)}
+}
+
+func (_c *MockTracer_AddTrace_Call) Run(run func(operation string, message string)) *MockTracer_AddTrace_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(string), args[1].(string))
+	})
+	return _c
+}
+
+func (_c *MockTracer_AddTrace_Call) Return() *MockTracer_AddTrace_Call {
+	_c.Call.Return()
+	return _c
+}
+
+func (_c *MockTracer_AddTrace_Call) RunAndReturn(run func(string, string)) *MockTracer_AddTrace_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// AddTransactionalStartTrace provides a mock function with given fields: operation, message
+func (_m *MockTracer) AddTransactionalStartTrace(operation string, message string) string {
+	ret := _m.Called(operation, message)
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func(string, string) string); ok {
+		r0 = rf(operation, message)
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// MockTracer_AddTransactionalStartTrace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddTransactionalStartTrace'
+type MockTracer_AddTransactionalStartTrace_Call struct {
+	*mock.Call
+}
+
+// AddTransactionalStartTrace is a helper method to define mock.On call
+//   - operation string
+//   - message string
+func (_e *MockTracer_Expecter) AddTransactionalStartTrace(operation interface{}, message interface{}) *MockTracer_AddTransactionalStartTrace_Call {
+	return &MockTracer_AddTransactionalStartTrace_Call{Call: _e.mock.On("AddTransactionalStartTrace", operation, message)}
+}
+
+func (_c *MockTracer_AddTransactionalStartTrace_Call) Run(run func(operation string, message string)) *MockTracer_AddTransactionalStartTrace_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(string), args[1].(string))
+	})
+	return _c
+}
+
+func (_c *MockTracer_AddTransactionalStartTrace_Call) Return(_a0 string) *MockTracer_AddTransactionalStartTrace_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockTracer_AddTransactionalStartTrace_Call) RunAndReturn(run func(string, string) string) *MockTracer_AddTransactionalStartTrace_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// AddTransactionalTrace provides a mock function with given fields: transactionId, operation, message
+func (_m *MockTracer) AddTransactionalTrace(transactionId string, operation string, message string) {
+	_m.Called(transactionId, operation, message)
+}
+
+// MockTracer_AddTransactionalTrace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddTransactionalTrace'
+type MockTracer_AddTransactionalTrace_Call struct {
+	*mock.Call
+}
+
+// AddTransactionalTrace is a helper method to define mock.On call
+//   - transactionId string
+//   - operation string
+//   - message string
+func (_e *MockTracer_Expecter) AddTransactionalTrace(transactionId interface{}, operation interface{}, message interface{}) *MockTracer_AddTransactionalTrace_Call {
+	return &MockTracer_AddTransactionalTrace_Call{Call: _e.mock.On("AddTransactionalTrace", transactionId, operation, message)}
+}
+
+func (_c *MockTracer_AddTransactionalTrace_Call) Run(run func(transactionId string, operation string, message string)) *MockTracer_AddTransactionalTrace_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(string), args[1].(string), args[2].(string))
+	})
+	return _c
+}
+
+func (_c *MockTracer_AddTransactionalTrace_Call) Return() *MockTracer_AddTransactionalTrace_Call {
+	_c.Call.Return()
+	return _c
+}
+
+func (_c *MockTracer_AddTransactionalTrace_Call) RunAndReturn(run func(string, string, string)) *MockTracer_AddTransactionalTrace_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// FilterTraces provides a mock function with given fields: traces, connectionIdFilter, transactionIdFilter, operationFilter, messageFilter
+func (_m *MockTracer) FilterTraces(traces []TraceEntry, connectionIdFilter string, transactionIdFilter string, operationFilter string, messageFilter string) []TraceEntry {
+	ret := _m.Called(traces, connectionIdFilter, transactionIdFilter, operationFilter, messageFilter)
+
+	var r0 []TraceEntry
+	if rf, ok := ret.Get(0).(func([]TraceEntry, string, string, string, string) []TraceEntry); ok {
+		r0 = rf(traces, connectionIdFilter, transactionIdFilter, operationFilter, messageFilter)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]TraceEntry)
+		}
+	}
+
+	return r0
+}
+
+// MockTracer_FilterTraces_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTraces'
+type MockTracer_FilterTraces_Call struct {
+	*mock.Call
+}
+
+// FilterTraces is a helper method to define mock.On call
+//   - traces []TraceEntry
+//   - connectionIdFilter string
+//   - transactionIdFilter string
+//   - operationFilter string
+//   - messageFilter string
+func (_e *MockTracer_Expecter) FilterTraces(traces interface{}, connectionIdFilter interface{}, transactionIdFilter interface{}, operationFilter interface{}, messageFilter interface{}) *MockTracer_FilterTraces_Call {
+	return &MockTracer_FilterTraces_Call{Call: _e.mock.On("FilterTraces", traces, connectionIdFilter, transactionIdFilter, operationFilter, messageFilter)}
+}
+
+func (_c *MockTracer_FilterTraces_Call) Run(run func(traces []TraceEntry, connectionIdFilter string, transactionIdFilter string, operationFilter string, messageFilter string)) *MockTracer_FilterTraces_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].([]TraceEntry), args[1].(string), args[2].(string), args[3].(string), args[4].(string))
+	})
+	return _c
+}
+
+func (_c *MockTracer_FilterTraces_Call) Return(_a0 []TraceEntry) *MockTracer_FilterTraces_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockTracer_FilterTraces_Call) RunAndReturn(run func([]TraceEntry, string, string, string, string) []TraceEntry) *MockTracer_FilterTraces_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// GetConnectionId provides a mock function with given fields:
+func (_m *MockTracer) GetConnectionId() string {
+	ret := _m.Called()
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// MockTracer_GetConnectionId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetConnectionId'
+type MockTracer_GetConnectionId_Call struct {
+	*mock.Call
+}
+
+// GetConnectionId is a helper method to define mock.On call
+func (_e *MockTracer_Expecter) GetConnectionId() *MockTracer_GetConnectionId_Call {
+	return &MockTracer_GetConnectionId_Call{Call: _e.mock.On("GetConnectionId")}
+}
+
+func (_c *MockTracer_GetConnectionId_Call) Run(run func()) *MockTracer_GetConnectionId_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockTracer_GetConnectionId_Call) Return(_a0 string) *MockTracer_GetConnectionId_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockTracer_GetConnectionId_Call) RunAndReturn(run func() string) *MockTracer_GetConnectionId_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// GetTraces provides a mock function with given fields:
+func (_m *MockTracer) GetTraces() []TraceEntry {
+	ret := _m.Called()
+
+	var r0 []TraceEntry
+	if rf, ok := ret.Get(0).(func() []TraceEntry); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]TraceEntry)
+		}
+	}
+
+	return r0
+}
+
+// MockTracer_GetTraces_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTraces'
+type MockTracer_GetTraces_Call struct {
+	*mock.Call
+}
+
+// GetTraces is a helper method to define mock.On call
+func (_e *MockTracer_Expecter) GetTraces() *MockTracer_GetTraces_Call {
+	return &MockTracer_GetTraces_Call{Call: _e.mock.On("GetTraces")}
+}
+
+func (_c *MockTracer_GetTraces_Call) Run(run func()) *MockTracer_GetTraces_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockTracer_GetTraces_Call) Return(_a0 []TraceEntry) *MockTracer_GetTraces_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *MockTracer_GetTraces_Call) RunAndReturn(run func() []TraceEntry) *MockTracer_GetTraces_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// ResetTraces provides a mock function with given fields:
+func (_m *MockTracer) ResetTraces() {
+	_m.Called()
+}
+
+// MockTracer_ResetTraces_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ResetTraces'
+type MockTracer_ResetTraces_Call struct {
+	*mock.Call
+}
+
+// ResetTraces is a helper method to define mock.On call
+func (_e *MockTracer_Expecter) ResetTraces() *MockTracer_ResetTraces_Call {
+	return &MockTracer_ResetTraces_Call{Call: _e.mock.On("ResetTraces")}
+}
+
+func (_c *MockTracer_ResetTraces_Call) Run(run func()) *MockTracer_ResetTraces_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *MockTracer_ResetTraces_Call) Return() *MockTracer_ResetTraces_Call {
+	_c.Call.Return()
+	return _c
+}
+
+func (_c *MockTracer_ResetTraces_Call) RunAndReturn(run func()) *MockTracer_ResetTraces_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// SetConnectionId provides a mock function with given fields: connectionId
+func (_m *MockTracer) SetConnectionId(connectionId string) {
+	_m.Called(connectionId)
+}
+
+// MockTracer_SetConnectionId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetConnectionId'
+type MockTracer_SetConnectionId_Call struct {
+	*mock.Call
+}
+
+// SetConnectionId is a helper method to define mock.On call
+//   - connectionId string
+func (_e *MockTracer_Expecter) SetConnectionId(connectionId interface{}) *MockTracer_SetConnectionId_Call {
+	return &MockTracer_SetConnectionId_Call{Call: _e.mock.On("SetConnectionId", connectionId)}
+}
+
+func (_c *MockTracer_SetConnectionId_Call) Run(run func(connectionId string)) *MockTracer_SetConnectionId_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(string))
+	})
+	return _c
+}
+
+func (_c *MockTracer_SetConnectionId_Call) Return() *MockTracer_SetConnectionId_Call {
+	_c.Call.Return()
+	return _c
+}
+
+func (_c *MockTracer_SetConnectionId_Call) RunAndReturn(run func(string)) *MockTracer_SetConnectionId_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+type mockConstructorTestingTNewMockTracer interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMockTracer creates a new instance of MockTracer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMockTracer(t mockConstructorTestingTNewMockTracer) *MockTracer {
+	mock := &MockTracer{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/plc4go/spi/transactions/RequestTransaction.go b/plc4go/spi/transactions/RequestTransaction.go
index de8c5bed84..c25133a349 100644
--- a/plc4go/spi/transactions/RequestTransaction.go
+++ b/plc4go/spi/transactions/RequestTransaction.go
@@ -51,18 +51,19 @@ type RequestTransaction interface {
 // Internal section
 //
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=requestTransaction
 type requestTransaction struct {
-	parent        *requestTransactionManager
+	parent        *requestTransactionManager `ignore:"true"`
 	transactionId int32
 
 	/** The initial operation to perform to kick off the request */
-	operation        pool.Runnable
+	operation        pool.Runnable `ignore:"true"` // TODO: maybe we can treat this as a function some day if we are able to check the definition in gen
 	completionFuture pool.CompletionFuture
 
 	stateChangeMutex sync.Mutex
 	completed        bool
 
-	transactionLog zerolog.Logger
+	transactionLog zerolog.Logger `ignore:"true"`
 }
 
 //
@@ -142,7 +143,3 @@ func (t *requestTransaction) AwaitCompletion(ctx context.Context) error {
 func (t *requestTransaction) IsCompleted() bool {
 	return t.completed
 }
-
-func (t *requestTransaction) String() string {
-	return fmt.Sprintf("Transaction{tid:%d}", t.transactionId)
-}
diff --git a/plc4go/spi/transactions/RequestTransactionManager.go b/plc4go/spi/transactions/RequestTransactionManager.go
index fe63035ebd..455d3830e5 100644
--- a/plc4go/spi/transactions/RequestTransactionManager.go
+++ b/plc4go/spi/transactions/RequestTransactionManager.go
@@ -22,7 +22,6 @@ package transactions
 import (
 	"container/list"
 	"context"
-	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/options"
 	"github.com/apache/plc4x/plc4go/spi/pool"
 	"io"
@@ -94,6 +93,7 @@ type withCustomExecutor struct {
 	executor pool.Executor
 }
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=requestTransactionManager
 type requestTransactionManager struct {
 	runningRequests []*requestTransaction
 	// How many transactions are allowed to run at the same time?
@@ -102,7 +102,7 @@ type requestTransactionManager struct {
 	currentTransactionId int32
 	transactionMutex     sync.RWMutex
 	// Important, this is a FIFO Queue for Fairness!
-	workLog      list.List
+	workLog      list.List `ignore:"true"` // TODO: no support for list yet
 	workLogMutex sync.RWMutex
 	executor     pool.Executor
 
@@ -112,7 +112,7 @@ type requestTransactionManager struct {
 	// flag set to true if it should trace transactions
 	traceTransactionManagerTransactions bool
 
-	log zerolog.Logger
+	log zerolog.Logger `ignore:"true"`
 }
 
 //
@@ -176,7 +176,7 @@ func (r *requestTransactionManager) StartTransaction() RequestTransaction {
 	}
 	if r.shutdown {
 		transaction.completed = true
-		transaction.completionFuture = completedFuture{errors.New("request transaction manager in shutdown")}
+		transaction.completionFuture = &completedFuture{errors.New("request transaction manager in shutdown")}
 	}
 	return transaction
 }
@@ -247,23 +247,3 @@ func (r *requestTransactionManager) CloseGraceful(timeout time.Duration) error {
 	r.runningRequests = nil
 	return r.executor.Close()
 }
-
-func (r *requestTransactionManager) String() string {
-	return fmt.Sprintf("RequestTransactionManager{\n"+
-		"\trunningRequests: %s,\n"+
-		"\tnumberOfConcurrentRequests: %d,\n"+
-		"\tcurrentTransactionId: %d,\n"+
-		"\tworkLog: %d elements,\n"+
-		"\texecutor: %s,\n"+
-		"\tshutdown: %t,\n"+
-		"\ttraceTransactionManagerTransactions: %t,\n"+
-		"}",
-		r.runningRequests,
-		r.numberOfConcurrentRequests,
-		r.currentTransactionId,
-		r.workLog.Len(),
-		r.executor,
-		r.shutdown,
-		r.traceTransactionManagerTransactions,
-	)
-}
diff --git a/plc4go/spi/transactions/RequestTransactionManager_test.go b/plc4go/spi/transactions/RequestTransactionManager_test.go
index 4925ce7790..77849933b7 100644
--- a/plc4go/spi/transactions/RequestTransactionManager_test.go
+++ b/plc4go/spi/transactions/RequestTransactionManager_test.go
@@ -613,29 +613,30 @@ func Test_requestTransactionManager_String(t *testing.T) {
 				shutdown:                            true,
 				traceTransactionManagerTransactions: true,
 			},
-			want: "RequestTransactionManager{\n" +
-				"\trunningRequests: [Transaction{tid:2}],\n" +
-				"\tnumberOfConcurrentRequests: 3,\n" +
-				"\tcurrentTransactionId: 4,\n" +
-				"\tworkLog: 1 elements,\n" +
-				"\texecutor: executor{\n" +
-				"\trunning: false,\n" +
-				"\tshutdown: false,\n" +
-				"\tworker: [worker{\n" +
-				"\tid: 0,\n" +
-				"\tshutdown: false,\n" +
-				"\tinterrupted: false,\n" +
-				"\thasEnded: false,\n" +
-				"\tlastReceived: 0001-01-01 00:00:00 +0000 UTC,\n" +
-				"}],\n" +
-				"\tqueueDepth: 1,\n" +
-				"\tworkItems: 0 elements,\n" +
-				"\ttraceWorkers: false,\n" +
-				"\n" +
-				"},\n" +
-				"\tshutdown: true,\n" +
-				"\ttraceTransactionManagerTransactions: true,\n" +
-				"}",
+			want: `
+╔═requestTransactionManager════════════════════════════════════════════════════════════════════════════════════════════╗
+║╔═runningRequests/value/requestTransaction╗╔═numberOfConcurrentRequests╗╔═currentTransactionId╗                       ║
+║║      ╔═transactionId╗╔═completed╗       ║║   0x0000000000000003 3    ║║    0x00000004 4     ║                       ║
+║║      ║ 0x00000002 2 ║║ b0 false ║       ║╚═══════════════════════════╝╚═════════════════════╝                       ║
+║║      ╚══════════════╝╚══════════╝       ║                                                                           ║
+║╚═════════════════════════════════════════╝                                                                           ║
+║╔═executor/executor═══════════════════════════════════════════════════════════════════════════════════════╗╔═shutdown╗║
+║║╔═running╗╔═shutdown╗                                                                                    ║║ b1 true ║║
+║║║b0 false║║b0 false ║                                                                                    ║╚═════════╝║
+║║╚════════╝╚═════════╝                                                                                    ║           ║
+║║╔═worker/value/worker═══════════════════════════════════════════════════════════════════════════════════╗║           ║
+║║║╔═id═════════════════╗╔═shutdown╗╔═interrupted╗╔═interrupter╗╔═hasEnded╗╔═lastReceived════════════════╗║║           ║
+║║║║0x0000000000000000 0║║b0 false ║║  b0 false  ║║0 element(s)║║b0 false ║║0001-01-01 00:00:00 +0000 UTC║║║           ║
+║║║╚════════════════════╝╚═════════╝╚════════════╝╚════════════╝╚═════════╝╚═════════════════════════════╝║║           ║
+║║╚═══════════════════════════════════════════════════════════════════════════════════════════════════════╝║           ║
+║║╔═queueDepth═════════╗╔═workItems══╗╔═traceWorkers╗                                                      ║           ║
+║║║0x0000000000000001 1║║0 element(s)║║  b0 false   ║                                                      ║           ║
+║║╚════════════════════╝╚════════════╝╚═════════════╝                                                      ║           ║
+║╚═════════════════════════════════════════════════════════════════════════════════════════════════════════╝           ║
+║╔═traceTransactionManagerTransactions╗                                                                                ║
+║║              b1 true               ║                                                                                ║
+║╚════════════════════════════════════╝                                                                                ║
+╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/transactions/RequestTransaction_test.go b/plc4go/spi/transactions/RequestTransaction_test.go
index 5dad61f345..f18f482d2d 100644
--- a/plc4go/spi/transactions/RequestTransaction_test.go
+++ b/plc4go/spi/transactions/RequestTransaction_test.go
@@ -156,7 +156,12 @@ func Test_requestTransaction_String(t1 *testing.T) {
 	}{
 		{
 			name: "give a string",
-			want: "Transaction{tid:0}",
+			want: `
+╔═requestTransaction═════════╗
+║╔═transactionId╗╔═completed╗║
+║║ 0x00000000 0 ║║ b0 false ║║
+║╚══════════════╝╚══════════╝║
+╚════════════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
@@ -169,7 +174,7 @@ func Test_requestTransaction_String(t1 *testing.T) {
 				transactionLog:   tt.fields.transactionLog,
 			}
 			if got := t.String(); got != tt.want {
-				t1.Errorf("String() = %v, want %v", got, tt.want)
+				t1.Errorf("String() = \n%v, want \n%v", got, tt.want)
 			}
 		})
 	}
diff --git a/plc4go/spi/transactions/completedFuture.go b/plc4go/spi/transactions/completedFuture.go
index 9d5ef8d9ab..08708ba520 100644
--- a/plc4go/spi/transactions/completedFuture.go
+++ b/plc4go/spi/transactions/completedFuture.go
@@ -21,21 +21,17 @@ package transactions
 
 import (
 	"context"
-	"fmt"
 )
 
+//go:generate go run ../../tools/plc4xgenerator/gen.go -type=completedFuture
 type completedFuture struct {
 	err error
 }
 
-func (c completedFuture) AwaitCompletion(_ context.Context) error {
+func (c *completedFuture) AwaitCompletion(_ context.Context) error {
 	return c.err
 }
 
-func (completedFuture) Cancel(_ bool, _ error) {
+func (*completedFuture) Cancel(_ bool, _ error) {
 	// No op
 }
-
-func (c completedFuture) String() string {
-	return fmt.Sprintf("completedFuture{\n\terr: %v,\n}", c.err)
-}
diff --git a/plc4go/spi/transactions/completedFuture_plc4xgen.go b/plc4go/spi/transactions/completedFuture_plc4xgen.go
new file mode 100644
index 0000000000..34d8c9a36c
--- /dev/null
+++ b/plc4go/spi/transactions/completedFuture_plc4xgen.go
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xgenerator -type=completedFuture"; DO NOT EDIT.
+
+package transactions
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *completedFuture) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *completedFuture) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("completedFuture"); err != nil {
+		return err
+	}
+
+	if d.err != nil {
+		_errString := d.err.Error()
+		if err := writeBuffer.WriteString("err", uint32(len(_errString)*8), "UTF-8", _errString); err != nil {
+			return err
+		}
+	}
+	if err := writeBuffer.PopContext("completedFuture"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *completedFuture) String() string {
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/spi/transactions/completedFuture_test.go b/plc4go/spi/transactions/completedFuture_test.go
index c875decec7..8373169945 100644
--- a/plc4go/spi/transactions/completedFuture_test.go
+++ b/plc4go/spi/transactions/completedFuture_test.go
@@ -22,6 +22,7 @@ package transactions
 import (
 	"context"
 	"fmt"
+	"github.com/pkg/errors"
 	"github.com/stretchr/testify/assert"
 	"testing"
 )
@@ -91,8 +92,18 @@ func Test_completedFuture_String(t *testing.T) {
 		want   string
 	}{
 		{
-			name: "gives the error",
-			want: "completedFuture{\n\terr: <nil>,\n}",
+			name: "no error == empty",
+			want: "<nil>",
+		},
+		{
+			name: "with error",
+			fields: fields{
+				err: errors.New("asd"),
+			},
+			want: `
+╔═completedFuture/err═╗
+║         asd         ║
+╚═════════════════════╝`[1:],
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go b/plc4go/spi/transactions/requestTransactionManager_plc4xgen.go
similarity index 58%
copy from plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
copy to plc4go/spi/transactions/requestTransactionManager_plc4xgen.go
index 1a22d3e0dd..9fe567096c 100644
--- a/plc4go/spi/model/DefaultPlcConsumerRegistration_plc4xgen.go
+++ b/plc4go/spi/transactions/requestTransactionManager_plc4xgen.go
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-// Code generated by "plc4xgenerator -type=DefaultPlcConsumerRegistration"; DO NOT EDIT.
+// Code generated by "plc4xgenerator -type=requestTransactionManager"; DO NOT EDIT.
 
-package model
+package transactions
 
 import (
 	"context"
@@ -30,7 +30,7 @@ import (
 
 var _ = fmt.Printf
 
-func (d *DefaultPlcConsumerRegistration) Serialize() ([]byte, error) {
+func (d *requestTransactionManager) Serialize() ([]byte, error) {
 	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
 	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
 		return nil, err
@@ -38,38 +38,14 @@ func (d *DefaultPlcConsumerRegistration) Serialize() ([]byte, error) {
 	return wb.GetBytes(), nil
 }
 
-func (d *DefaultPlcConsumerRegistration) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
-	if err := writeBuffer.PushContext("PlcConsumerRegistration"); err != nil {
+func (d *requestTransactionManager) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("requestTransactionManager"); err != nil {
 		return err
 	}
-	_value := fmt.Sprintf("%v", d.consumerId)
-
-	if err := writeBuffer.WriteString("consumerId", uint32(len(_value)*8), "UTF-8", _value); err != nil {
+	if err := writeBuffer.PushContext("runningRequests", utils.WithRenderAsList(true)); err != nil {
 		return err
 	}
-
-	if d.plcSubscriber != nil {
-		if serializableField, ok := d.plcSubscriber.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("plcSubscriber"); err != nil {
-				return err
-			}
-			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-				return err
-			}
-			if err := writeBuffer.PopContext("plcSubscriber"); err != nil {
-				return err
-			}
-		} else {
-			stringValue := fmt.Sprintf("%v", d.plcSubscriber)
-			if err := writeBuffer.WriteString("plcSubscriber", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
-				return err
-			}
-		}
-	}
-	if err := writeBuffer.PushContext("handles", utils.WithRenderAsList(true)); err != nil {
-		return err
-	}
-	for _, elem := range d.handles {
+	for _, elem := range d.runningRequests {
 		var elem any = elem
 
 		if elem != nil {
@@ -91,16 +67,51 @@ func (d *DefaultPlcConsumerRegistration) SerializeWithWriteBuffer(ctx context.Co
 			}
 		}
 	}
-	if err := writeBuffer.PopContext("handles", utils.WithRenderAsList(true)); err != nil {
+	if err := writeBuffer.PopContext("runningRequests", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteInt64("numberOfConcurrentRequests", 64, int64(d.numberOfConcurrentRequests)); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteInt32("currentTransactionId", 32, int32(d.currentTransactionId)); err != nil {
+		return err
+	}
+
+	if d.executor != nil {
+		if serializableField, ok := d.executor.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("executor"); err != nil {
+				return err
+			}
+			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
+				return err
+			}
+			if err := writeBuffer.PopContext("executor"); err != nil {
+				return err
+			}
+		} else {
+			stringValue := fmt.Sprintf("%v", d.executor)
+			if err := writeBuffer.WriteString("executor", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+				return err
+			}
+		}
+	}
+
+	if err := writeBuffer.WriteBit("shutdown", d.shutdown); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("traceTransactionManagerTransactions", d.traceTransactionManagerTransactions); err != nil {
 		return err
 	}
-	if err := writeBuffer.PopContext("PlcConsumerRegistration"); err != nil {
+	if err := writeBuffer.PopContext("requestTransactionManager"); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (d *DefaultPlcConsumerRegistration) String() string {
+func (d *requestTransactionManager) String() string {
 	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
 	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
 		return err.Error()
diff --git a/plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go b/plc4go/spi/transactions/requestTransaction_plc4xgen.go
similarity index 50%
copy from plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go
copy to plc4go/spi/transactions/requestTransaction_plc4xgen.go
index 7169484d20..d6dd6afa75 100644
--- a/plc4go/spi/model/DefaultPlcReadRequestResult_plc4xgen.go
+++ b/plc4go/spi/transactions/requestTransaction_plc4xgen.go
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-// Code generated by "plc4xgenerator -type=DefaultPlcReadRequestResult"; DO NOT EDIT.
+// Code generated by "plc4xgenerator -type=requestTransaction"; DO NOT EDIT.
 
-package model
+package transactions
 
 import (
 	"context"
@@ -30,7 +30,7 @@ import (
 
 var _ = fmt.Printf
 
-func (d *DefaultPlcReadRequestResult) Serialize() ([]byte, error) {
+func (d *requestTransaction) Serialize() ([]byte, error) {
 	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
 	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
 		return nil, err
@@ -38,61 +38,44 @@ func (d *DefaultPlcReadRequestResult) Serialize() ([]byte, error) {
 	return wb.GetBytes(), nil
 }
 
-func (d *DefaultPlcReadRequestResult) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
-	if err := writeBuffer.PushContext("PlcReadRequestResult"); err != nil {
+func (d *requestTransaction) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("requestTransaction"); err != nil {
 		return err
 	}
 
-	if d.Request != nil {
-		if serializableField, ok := d.Request.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("request"); err != nil {
-				return err
-			}
-			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-				return err
-			}
-			if err := writeBuffer.PopContext("request"); err != nil {
-				return err
-			}
-		} else {
-			stringValue := fmt.Sprintf("%v", d.Request)
-			if err := writeBuffer.WriteString("request", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
-				return err
-			}
-		}
+	if err := writeBuffer.WriteInt32("transactionId", 32, int32(d.transactionId)); err != nil {
+		return err
 	}
 
-	if d.Response != nil {
-		if serializableField, ok := d.Response.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext("response"); err != nil {
+	if d.completionFuture != nil {
+		if serializableField, ok := d.completionFuture.(utils.Serializable); ok {
+			if err := writeBuffer.PushContext("completionFuture"); err != nil {
 				return err
 			}
 			if err := serializableField.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
 				return err
 			}
-			if err := writeBuffer.PopContext("response"); err != nil {
+			if err := writeBuffer.PopContext("completionFuture"); err != nil {
 				return err
 			}
 		} else {
-			stringValue := fmt.Sprintf("%v", d.Response)
-			if err := writeBuffer.WriteString("response", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
+			stringValue := fmt.Sprintf("%v", d.completionFuture)
+			if err := writeBuffer.WriteString("completionFuture", uint32(len(stringValue)*8), "UTF-8", stringValue); err != nil {
 				return err
 			}
 		}
 	}
 
-	if d.Err != nil {
-		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
-			return err
-		}
+	if err := writeBuffer.WriteBit("completed", d.completed); err != nil {
+		return err
 	}
-	if err := writeBuffer.PopContext("PlcReadRequestResult"); err != nil {
+	if err := writeBuffer.PopContext("requestTransaction"); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (d *DefaultPlcReadRequestResult) String() string {
+func (d *requestTransaction) String() string {
 	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
 	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
 		return err.Error()
diff --git a/plc4go/tools/plc4xgenerator/gen.go b/plc4go/tools/plc4xgenerator/gen.go
index 018062490c..ef86047b0f 100644
--- a/plc4go/tools/plc4xgenerator/gen.go
+++ b/plc4go/tools/plc4xgenerator/gen.go
@@ -574,7 +574,8 @@ var stringFieldSerialize = `
 
 var errorFieldSerialize = `
 	if %[1]s != nil {
-		if err := writeBuffer.WriteString(%[2]s, uint32(len(%[1]s.Error())*8), "UTF-8", %[1]s.Error()); err != nil {
+		_errString := %[1]s.Error()
+		if err := writeBuffer.WriteString(%[2]s, uint32(len(_errString)*8), "UTF-8", _errString); err != nil {
 			return err
 		}
 	}