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/05/15 16:06:15 UTC

[plc4x] 02/02: refactor(plc4go): use constructors when possible for default types

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 e9d689fad485298b3f978f2c313dd15bbda8a95d
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon May 15 18:05:32 2023 +0200

    refactor(plc4go): use constructors when possible for default types
---
 plc4go/internal/ads/Browser.go            | 30 +++++-------
 plc4go/internal/ads/Discoverer.go         | 16 +++----
 plc4go/internal/ads/Reader.go             | 79 ++++++++++++++++---------------
 plc4go/internal/ads/Subscriber.go         | 41 ++++++++--------
 plc4go/internal/ads/Writer.go             | 76 +++++++----------------------
 plc4go/internal/bacnetip/Discoverer.go    | 30 +++++++-----
 plc4go/internal/bacnetip/Reader.go        | 43 ++++++++---------
 plc4go/internal/bacnetip/Subscriber.go    | 12 ++---
 plc4go/internal/cbus/Browser.go           | 18 +++----
 plc4go/internal/cbus/Discoverer.go        | 15 +++---
 plc4go/internal/cbus/Reader.go            | 32 ++++++-------
 plc4go/internal/cbus/Subscriber.go        | 10 ++--
 plc4go/internal/cbus/Writer.go            | 40 +++++++---------
 plc4go/internal/eip/Reader.go             | 37 ++++++++-------
 plc4go/internal/eip/Writer.go             | 24 ++--------
 plc4go/internal/knxnetip/Browser.go       | 47 +++++++++++-------
 plc4go/internal/knxnetip/Discoverer.go    | 15 +++---
 plc4go/internal/knxnetip/Reader.go        | 10 ++--
 plc4go/internal/knxnetip/Subscriber.go    | 10 ++--
 plc4go/internal/knxnetip/Writer.go        | 12 +----
 plc4go/internal/modbus/Reader.go          | 67 +++++++++++++-------------
 plc4go/internal/modbus/Writer.go          | 22 +++------
 plc4go/internal/s7/Reader.go              | 47 +++++++++---------
 plc4go/internal/s7/Writer.go              | 18 ++-----
 plc4go/internal/simulated/Reader.go       | 10 ++--
 plc4go/internal/simulated/Subscriber.go   | 12 ++++-
 plc4go/internal/simulated/Writer.go       |  6 +--
 plc4go/spi/default/DefaultBrowser.go      | 10 ++--
 plc4go/spi/model/DefaultPlcReadRequest.go |  2 +-
 29 files changed, 363 insertions(+), 428 deletions(-)

diff --git a/plc4go/internal/ads/Browser.go b/plc4go/internal/ads/Browser.go
index 20e8fdebfd..aa0aa720e2 100644
--- a/plc4go/internal/ads/Browser.go
+++ b/plc4go/internal/ads/Browser.go
@@ -45,10 +45,7 @@ func (m *Connection) BrowseWithInterceptor(ctx context.Context, browseRequest ap
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
-				result <- &internalModel.DefaultPlcBrowseRequestResult{
-					Request: browseRequest,
-					Err:     errors.Errorf("Recovered from panic: %v", err),
-				}
+				result <- internalModel.NewDefaultPlcBrowseRequestResult(browseRequest, nil, errors.Errorf("Recovered from panic: %v", err))
 			}
 		}()
 		responseCodes := map[string]apiModel.PlcResponseCode{}
@@ -58,11 +55,7 @@ func (m *Connection) BrowseWithInterceptor(ctx context.Context, browseRequest ap
 			responseCodes[queryName], results[queryName] = m.BrowseQuery(ctx, interceptor, queryName, query)
 		}
 		browseResponse := internalModel.NewDefaultPlcBrowseResponse(browseRequest, results, responseCodes)
-		result <- &internalModel.DefaultPlcBrowseRequestResult{
-			Request:  browseRequest,
-			Response: browseResponse,
-			Err:      nil,
-		}
+		result <- internalModel.NewDefaultPlcBrowseRequestResult(browseRequest, browseResponse, nil)
 	}()
 	return result
 }
@@ -122,20 +115,21 @@ func (m *Connection) filterDataTypes(parentName string, currentType driverModel.
 				UpperBound: ai.GetUpperBound(),
 			})
 		}
-		foundTag := &internalModel.DefaultPlcBrowseItem{
-			Tag: model.SymbolicPlcTag{
+		foundTag := internalModel.NewDefaultPlcBrowseItem(
+			model.SymbolicPlcTag{
 				PlcTag: model.PlcTag{
 					ArrayInfo: arrayInfo,
 				},
 				SymbolicAddress: parentName,
 			},
-			Name:         parentName,
-			DataTypeName: currentType.GetDataTypeName(),
-			Readable:     false,
-			Writable:     false,
-			Subscribable: false,
-			Options:      nil,
-		}
+			parentName,
+			currentType.GetDataTypeName(),
+			false,
+			false,
+			false,
+			nil,
+			nil,
+		)
 		return []apiModel.PlcBrowseItem{foundTag}
 	}
 
diff --git a/plc4go/internal/ads/Discoverer.go b/plc4go/internal/ads/Discoverer.go
index f54927fedd..b9d6606202 100644
--- a/plc4go/internal/ads/Discoverer.go
+++ b/plc4go/internal/ads/Discoverer.go
@@ -218,14 +218,14 @@ func (d *Discoverer) Discover(ctx context.Context, callback func(event apiModel.
 					strconv.Itoa(int(remoteAmsNetId.GetOctet4())) + ":" +
 					strconv.Itoa(int(driverModel.AdsConstants_ADSTCPDEFAULTPORT)))
 				if err2 == nil {
-					plcDiscoveryItem := &internalModel.DefaultPlcDiscoveryItem{
-						ProtocolCode:  "ads",
-						TransportCode: "tcp",
-						TransportUrl:  *remoteAddress,
-						Options:       opts,
-						Name:          hostNameBlock.GetHostName().GetText(),
-						Attributes:    attributes,
-					}
+					plcDiscoveryItem := internalModel.NewDefaultPlcDiscoveryItem(
+						"ads",
+						"tcp",
+						*remoteAddress,
+						opts,
+						hostNameBlock.GetHostName().GetText(),
+						attributes,
+					)
 
 					// Pass the event back to the callback
 					callback(plcDiscoveryItem)
diff --git a/plc4go/internal/ads/Reader.go b/plc4go/internal/ads/Reader.go
index 4a820729cb..ce28c0e2f9 100644
--- a/plc4go/internal/ads/Reader.go
+++ b/plc4go/internal/ads/Reader.go
@@ -78,11 +78,11 @@ func (m *Connection) singleRead(ctx context.Context, readRequest apiModel.PlcRea
 		// Replace the symbolic tag with a direct one
 		tag, err = m.resolveSymbolicTag(ctx, adsField)
 		if err != nil {
-			result <- &internalModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "invalid tag item type"),
+			)
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
@@ -102,10 +102,11 @@ func (m *Connection) singleRead(ctx context.Context, readRequest apiModel.PlcRea
 		}()
 		response, err := m.ExecuteAdsReadRequest(ctx, directAdsTag.IndexGroup, directAdsTag.IndexOffset, directAdsTag.DataType.GetSize())
 		if err != nil {
-			result <- &internalModel.DefaultPlcReadRequestResult{
-				Request: readRequest,
-				Err:     errors.Wrap(err, "got error executing the read request"),
-			}
+			result <- internalModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "got error executing the read request"),
+			)
 			return
 		}
 
@@ -129,11 +130,11 @@ func (m *Connection) singleRead(ctx context.Context, readRequest apiModel.PlcRea
 			}
 		}
 		// Return the response to the caller.
-		result <- &internalModel.DefaultPlcReadRequestResult{
-			Request:  readRequest,
-			Response: internalModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues),
-			Err:      nil,
-		}
+		result <- internalModel.NewDefaultPlcReadRequestResult(
+			readRequest,
+			internalModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues),
+			nil,
+		)
 	}()
 }
 
@@ -148,33 +149,33 @@ func (m *Connection) multiRead(ctx context.Context, readRequest apiModel.PlcRead
 		if model.NeedsResolving(tag) {
 			adsField, err := model.CastToSymbolicPlcTagFromPlcTag(tag)
 			if err != nil {
-				result <- &internalModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "invalid tag item type"),
-				}
+				result <- internalModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "invalid tag item type"),
+				)
 				log.Debug().Msgf("Invalid tag item type %T", tag)
 				return
 			}
 			// Replace the symbolic tag with a direct one
 			tag, err = m.resolveSymbolicTag(ctx, adsField)
 			if err != nil {
-				result <- &internalModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "invalid tag item type"),
-				}
+				result <- internalModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "invalid tag item type"),
+				)
 				log.Debug().Msgf("Invalid tag item type %T", tag)
 				return
 			}
 		}
 		directAdsTag, ok := tag.(*model.DirectPlcTag)
 		if !ok {
-			result <- &internalModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.New("invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.New("invalid tag item type"),
+			)
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
@@ -201,11 +202,11 @@ func (m *Connection) multiRead(ctx context.Context, readRequest apiModel.PlcRead
 
 	response, err := m.ExecuteAdsReadWriteRequest(ctx, uint32(driverModel.ReservedIndexGroups_ADSIGRP_MULTIPLE_READ), uint32(len(directAdsTags)), expectedResponseDataSize, requestItems, nil)
 	if err != nil {
-		result <- &internalModel.DefaultPlcReadRequestResult{
-			Request:  readRequest,
-			Response: nil,
-			Err:      errors.Wrap(err, "error executing multi-item read request"),
-		}
+		result <- internalModel.NewDefaultPlcReadRequestResult(
+			readRequest,
+			nil,
+			errors.Wrap(err, "error executing multi-item read request"),
+		)
 		return
 	}
 
@@ -246,11 +247,11 @@ func (m *Connection) multiRead(ctx context.Context, readRequest apiModel.PlcRead
 	}
 
 	// Return the response to the caller.
-	result <- &internalModel.DefaultPlcReadRequestResult{
-		Request:  readRequest,
-		Response: internalModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues),
-		Err:      nil,
-	}
+	result <- internalModel.NewDefaultPlcReadRequestResult(
+		readRequest,
+		internalModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues),
+		nil,
+	)
 }
 
 func (m *Connection) parsePlcValue(dataType driverModel.AdsDataTypeTableEntry, arrayInfo []driverModel.AdsDataTypeArrayInfo, rb utils.ReadBufferByteBased) (values.PlcValue, error) {
diff --git a/plc4go/internal/ads/Subscriber.go b/plc4go/internal/ads/Subscriber.go
index 3a66f23847..df73d2be3d 100644
--- a/plc4go/internal/ads/Subscriber.go
+++ b/plc4go/internal/ads/Subscriber.go
@@ -61,14 +61,12 @@ func (m *Connection) Subscribe(ctx context.Context, subscriptionRequest apiModel
 			symbolicTag := tag.(dirverModel.SymbolicPlcTag)
 			directTagPtr, err := m.driverContext.getDirectTagForSymbolTag(symbolicTag)
 			if err != nil {
-				subResults[tagName] = &internalModel.DefaultPlcSubscriptionRequestResult{
-					Request: nil, Err: errors.Wrap(err, "error resolving symbolic tag")}
+				subResults[tagName] = internalModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, errors.Wrap(err, "error resolving symbolic tag"))
 				continue
 			}
 			directTag = *directTagPtr
 		default:
-			subResults[tagName] = &internalModel.DefaultPlcSubscriptionRequestResult{
-				Request: nil, Err: errors.New("invalid tag type")}
+			subResults[tagName] = internalModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, errors.New("invalid tag type"))
 			continue
 		}
 
@@ -142,23 +140,26 @@ func (m *Connection) subscribe(ctx context.Context, subscriptionRequest apiModel
 
 		response, err := m.ExecuteAdsAddDeviceNotificationRequest(ctx, directTag.IndexGroup, directTag.IndexOffset, directTag.DataType.GetSize(), model.AdsTransMode_ON_CHANGE, 0, 0)
 		if err != nil {
-			respChan <- &internalModel.DefaultPlcSubscriptionRequestResult{
-				Request:  subscriptionRequest,
-				Response: nil,
-				Err:      err,
-			}
+			responseChan <- internalModel.NewDefaultPlcSubscriptionRequestResult(
+				subscriptionRequest,
+				nil,
+				err,
+			)
 		}
 		// Create a new subscription handle.
 		subscriptionHandle := dirverModel.NewAdsSubscriptionHandle(m, tagName, directTag)
-		respChan <- &internalModel.DefaultPlcSubscriptionRequestResult{
-			Request: subscriptionRequest,
-			Response: internalModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest,
+		responseChan <- internalModel.NewDefaultPlcSubscriptionRequestResult(
+			subscriptionRequest,
+			internalModel.NewDefaultPlcSubscriptionResponse(
+				subscriptionRequest,
 				map[string]apiModel.PlcResponseCode{tagName: apiModel.PlcResponseCode_OK},
-				map[string]apiModel.PlcSubscriptionHandle{tagName: subscriptionHandle}),
-		}
+				map[string]apiModel.PlcSubscriptionHandle{tagName: subscriptionHandle},
+			),
+			nil,
+		)
 		// Store it together with the returned ADS handle.
 		m.subscriptions[response.GetNotificationHandle()] = subscriptionHandle
-	}(responseChan)
+	}()
 	return responseChan
 }
 
@@ -199,11 +200,11 @@ func (m *Connection) processSubscriptionResponses(_ context.Context, subscriptio
 			}
 		}
 	}
-	return &internalModel.DefaultPlcSubscriptionRequestResult{
-		Request:  subscriptionRequest,
-		Response: internalModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionHandles),
-		Err:      err,
-	}
+	return internalModel.NewDefaultPlcSubscriptionRequestResult(
+		subscriptionRequest,
+		internalModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionHandles),
+		err,
+	)
 }
 
 func (m *Connection) handleIncomingDeviceNotificationRequest(deviceNotificationRequest model.AdsDeviceNotificationRequest) {
diff --git a/plc4go/internal/ads/Writer.go b/plc4go/internal/ads/Writer.go
index d2330be112..4750aa4f23 100644
--- a/plc4go/internal/ads/Writer.go
+++ b/plc4go/internal/ads/Writer.go
@@ -70,33 +70,25 @@ func (m *Connection) singleWrite(ctx context.Context, writeRequest apiModel.PlcW
 	if model.NeedsResolving(tag) {
 		adsField, err := model.CastToSymbolicPlcTagFromPlcTag(tag)
 		if err != nil {
-			result <- &internalModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcWriteRequestResult(
+				writeRequest,
+				nil,
+				errors.Wrap(err, "invalid tag item type"),
+			)
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
 		// Replace the symbolic tag with a direct one
 		tag, err = m.resolveSymbolicTag(ctx, adsField)
 		if err != nil {
-			result <- &internalModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "invalid tag item type"))
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
 	}
 	directAdsTag, ok := tag.(*model.DirectPlcTag)
 	if !ok {
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: nil,
-			Err:      errors.New("invalid tag item type"),
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("invalid tag item type"))
 		log.Debug().Msgf("Invalid tag item type %T", tag)
 		return
 	}
@@ -106,11 +98,7 @@ func (m *Connection) singleWrite(ctx context.Context, writeRequest apiModel.PlcW
 	io := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.LittleEndian))
 	err := m.serializePlcValue(directAdsTag.DataType, directAdsTag.GetArrayInfo(), value, io)
 	if err != nil {
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: nil,
-			Err:      errors.Wrap(err, "error serializing plc value"),
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "error serializing plc value"))
 		return
 	}
 	data := io.GetBytes()
@@ -139,11 +127,7 @@ func (m *Connection) singleWrite(ctx context.Context, writeRequest apiModel.PlcW
 			responseCodes[tagName] = apiModel.PlcResponseCode_OK
 		}
 		// Return the response to the caller.
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: internalModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes),
-			Err:      nil,
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, internalModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes), nil)
 	}()
 }
 
@@ -159,33 +143,21 @@ func (m *Connection) multiWrite(ctx context.Context, writeRequest apiModel.PlcWr
 		if model.NeedsResolving(tag) {
 			adsField, err := model.CastToSymbolicPlcTagFromPlcTag(tag)
 			if err != nil {
-				result <- &internalModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "invalid tag item type"),
-				}
+				result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "invalid tag item type"))
 				log.Debug().Msgf("Invalid tag item type %T", tag)
 				return
 			}
 			// Replace the symbolic tag with a direct one
 			tag, err = m.resolveSymbolicTag(ctx, adsField)
 			if err != nil {
-				result <- &internalModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "invalid tag item type"),
-				}
+				result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "invalid tag item type"))
 				log.Debug().Msgf("Invalid tag item type %T", tag)
 				return
 			}
 		}
 		directAdsTag, ok := tag.(*model.DirectPlcTag)
 		if !ok {
-			result <- &internalModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("invalid tag item type"))
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
@@ -195,11 +167,7 @@ func (m *Connection) multiWrite(ctx context.Context, writeRequest apiModel.PlcWr
 		// Serialize the plc value
 		err := m.serializePlcValue(directAdsTag.DataType, directAdsTag.GetArrayInfo(), writeRequest.GetValue(tagName), io)
 		if err != nil {
-			result <- &internalModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "error serializing plc value"),
-			}
+			result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "error serializing plc value"))
 			return
 		}
 
@@ -225,20 +193,12 @@ func (m *Connection) multiWrite(ctx context.Context, writeRequest apiModel.PlcWr
 		uint32(driverModel.ReservedIndexGroups_ADSIGRP_MULTIPLE_WRITE), uint32(len(directAdsTags)),
 		expectedResponseDataSize, requestItems, io.GetBytes())
 	if err != nil {
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: nil,
-			Err:      errors.Wrap(err, "error executing multi-item write request"),
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "error executing multi-item write request"))
 		return
 	}
 
 	if response.GetResult() != driverModel.ReturnCode_OK {
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: nil,
-			Err:      fmt.Errorf("got return result %s from remote", response.GetResult().String()),
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, fmt.Errorf("got return result %s from remote", response.GetResult().String()))
 		return
 	}
 
@@ -259,11 +219,7 @@ func (m *Connection) multiWrite(ctx context.Context, writeRequest apiModel.PlcWr
 	}
 
 	// Return the response to the caller.
-	result <- &internalModel.DefaultPlcWriteRequestResult{
-		Request:  writeRequest,
-		Response: internalModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes),
-		Err:      nil,
-	}
+	result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, internalModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes), nil)
 }
 
 func (m *Connection) serializePlcValue(dataType driverModel.AdsDataTypeTableEntry, arrayInfo []apiModel.ArrayInfo, plcValue values.PlcValue, wb utils.WriteBufferByteBased) error {
diff --git a/plc4go/internal/bacnetip/Discoverer.go b/plc4go/internal/bacnetip/Discoverer.go
index a5f3deb9a1..70126d4c1b 100644
--- a/plc4go/internal/bacnetip/Discoverer.go
+++ b/plc4go/internal/bacnetip/Discoverer.go
@@ -157,7 +157,7 @@ func broadcastAndDiscover(ctx context.Context, communicationChannels []communica
 
 		go func(communicationChannelInstance communicationChannel) {
 			for {
-				blockingReadChan := make(chan bool, 0)
+				blockingReadChan := make(chan bool)
 				go func() {
 					buf := make([]byte, 4096)
 					n, addr, err := communicationChannelInstance.unicastConnection.ReadFrom(buf)
@@ -255,12 +255,14 @@ func handleIncomingBVLCs(ctx context.Context, callback func(event apiModel.PlcDi
 				if err != nil {
 					log.Debug().Err(err).Msg("Error parsing url")
 				}
-				discoveryEvent := &internalModel.DefaultPlcDiscoveryItem{
-					ProtocolCode:  "bacnet-ip",
-					TransportCode: "udp",
-					TransportUrl:  *remoteUrl,
-					Name:          fmt.Sprintf("device %v:%v", iAm.GetDeviceIdentifier().GetObjectType(), iAm.GetDeviceIdentifier().GetInstanceNumber()),
-				}
+				discoveryEvent := internalModel.NewDefaultPlcDiscoveryItem(
+					"bacnet-ip",
+					"udp",
+					*remoteUrl,
+					nil,
+					fmt.Sprintf("device %v:%v", iAm.GetDeviceIdentifier().GetObjectType(), iAm.GetDeviceIdentifier().GetInstanceNumber()),
+					nil,
+				)
 
 				// Pass the event back to the callback
 				callback(discoveryEvent)
@@ -270,12 +272,14 @@ func handleIncomingBVLCs(ctx context.Context, callback func(event apiModel.PlcDi
 				if err != nil {
 					log.Debug().Err(err).Msg("Error parsing url")
 				}
-				discoveryEvent := &internalModel.DefaultPlcDiscoveryItem{
-					ProtocolCode:  "bacnet-ip",
-					TransportCode: "udp",
-					TransportUrl:  *remoteUrl,
-					Name:          fmt.Sprintf("device %v:%v with %v:%v and %v", iHave.GetDeviceIdentifier().GetObjectType(), iHave.GetDeviceIdentifier().GetInstanceNumber(), iHave.GetObjectIdentifier().GetObjectType(), iHave.GetObjectIdentifier().GetInstanceNumber(), iHave.GetObjectName().GetValue()),
-				}
+				discoveryEvent := internalModel.NewDefaultPlcDiscoveryItem(
+					"bacnet-ip",
+					"udp",
+					*remoteUrl,
+					nil,
+					fmt.Sprintf("device %v:%v with %v:%v and %v", iHave.GetDeviceIdentifier().GetObjectType(), iHave.GetDeviceIdentifier().GetInstanceNumber(), iHave.GetObjectIdentifier().GetObjectType(), iHave.GetObjectIdentifier().GetInstanceNumber(), iHave.GetObjectName().GetValue()),
+					nil,
+				)
 
 				// Pass the event back to the callback
 				callback(discoveryEvent)
diff --git a/plc4go/internal/bacnetip/Reader.go b/plc4go/internal/bacnetip/Reader.go
index a1c1e7985a..3fdc4961ed 100644
--- a/plc4go/internal/bacnetip/Reader.go
+++ b/plc4go/internal/bacnetip/Reader.go
@@ -60,11 +60,7 @@ func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest)
 	result := make(chan apiModel.PlcReadRequestResult, 1)
 	go func() {
 		if len(readRequest.GetTagNames()) == 0 {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.New("at least one field required"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(readRequest, nil, errors.New("at least one field required"))
 			return
 		}
 		// create the service request
@@ -167,29 +163,32 @@ func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest)
 				readResponse, err := m.ToPlc4xReadResponse(apdu, readRequest)
 
 				if err != nil {
-					result <- &spiModel.DefaultPlcReadRequestResult{
-						Request: readRequest,
-						Err:     errors.Wrap(err, "Error decoding response"),
-					}
+					result <- spiModel.NewDefaultPlcReadRequestResult(
+						readRequest,
+						nil,
+						errors.Wrap(err, "Error decoding response"),
+					)
 					return transaction.EndRequest()
 				}
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: readResponse,
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					readResponse,
+					nil,
+				)
 				return transaction.EndRequest()
 			}, func(err error) error {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request: readRequest,
-					Err:     errors.Wrap(err, "got timeout while waiting for response"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "got timeout while waiting for response"),
+				)
 				return transaction.EndRequest()
 			}, time.Second*1); err != nil {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "error sending message"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "error sending message"),
+				)
 				_ = transaction.EndRequest()
 			}
 		})
diff --git a/plc4go/internal/bacnetip/Subscriber.go b/plc4go/internal/bacnetip/Subscriber.go
index b60ea0b60a..adb088300c 100644
--- a/plc4go/internal/bacnetip/Subscriber.go
+++ b/plc4go/internal/bacnetip/Subscriber.go
@@ -21,9 +21,9 @@ package bacnetip
 
 import (
 	"context"
+	"github.com/pkg/errors"
 
 	apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
-	plc4goModel "github.com/apache/plc4x/plc4go/spi/model"
 	spiModel "github.com/apache/plc4x/plc4go/spi/model"
 )
 
@@ -51,15 +51,15 @@ func (m *Subscriber) Subscribe(ctx context.Context, subscriptionRequest apiModel
 		responseCodes := map[string]apiModel.PlcResponseCode{}
 		subscriptionValues := make(map[string]apiModel.PlcSubscriptionHandle)
 		for _, tagName := range internalPlcSubscriptionRequest.GetTagNames() {
+			if err := ctx.Err(); err != nil {
+				result <- spiModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, err)
+				return
+			}
 			responseCodes[tagName] = apiModel.PlcResponseCode_OK
 			subscriptionValues[tagName] = spiModel.NewDefaultPlcSubscriptionHandle(m)
 		}
 
-		result <- &plc4goModel.DefaultPlcSubscriptionRequestResult{
-			Request:  subscriptionRequest,
-			Response: spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
-			Err:      nil,
-		}
+		result <- spiModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues), nil)
 	}()
 	return result
 }
diff --git a/plc4go/internal/cbus/Browser.go b/plc4go/internal/cbus/Browser.go
index d22e7a12cc..56c4ed7af8 100644
--- a/plc4go/internal/cbus/Browser.go
+++ b/plc4go/internal/cbus/Browser.go
@@ -107,16 +107,18 @@ func (m Browser) BrowseQuery(ctx context.Context, interceptor func(result apiMod
 					event.Msgf("unit %d: error reading tag %s. Code %s", unitAddress, attribute, code)
 					continue unitLoop
 				}
-				queryResult := &spiModel.DefaultPlcBrowseItem{
-					Tag:          NewCALIdentifyTag(unit, nil /*TODO: add bridge support*/, attribute, 1),
-					Name:         queryName,
-					Readable:     true,
-					Writable:     false,
-					Subscribable: false,
-					Options: map[string]values.PlcValue{
+				queryResult := spiModel.NewDefaultPlcBrowseItem(
+					NewCALIdentifyTag(unit, nil /*TODO: add bridge support*/, attribute, 1),
+					queryName,
+					"",
+					true,
+					false,
+					false,
+					nil,
+					map[string]values.PlcValue{
 						"CurrentValue": response.GetValue(readTagName),
 					},
-				}
+				)
 				if interceptor != nil {
 					interceptor(queryResult)
 				}
diff --git a/plc4go/internal/cbus/Discoverer.go b/plc4go/internal/cbus/Discoverer.go
index 00ba336fa5..9313c4592f 100644
--- a/plc4go/internal/cbus/Discoverer.go
+++ b/plc4go/internal/cbus/Discoverer.go
@@ -282,13 +282,14 @@ func (d *Discoverer) createDeviceScanDispatcher(tcpTransportInstance *tcp.Transp
 				}
 				// TODO: manufacturer + type would be good but this means two requests then
 				deviceName := identifyReplyCommand.GetManufacturerName()
-				discoveryEvent := &internalModel.DefaultPlcDiscoveryItem{
-					ProtocolCode:  "c-bus",
-					TransportCode: "tcp",
-					TransportUrl:  remoteUrl,
-					Options:       nil,
-					Name:          deviceName,
-				}
+				discoveryEvent := internalModel.NewDefaultPlcDiscoveryItem(
+					"c-bus",
+					"tcp",
+					remoteUrl,
+					nil,
+					deviceName,
+					nil,
+				)
 				// Pass the event back to the callback
 				callback(discoveryEvent)
 				continue
diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index c6df55f7cf..645595bbdf 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -62,10 +62,7 @@ func (m *Reader) readSync(ctx context.Context, readRequest apiModel.PlcReadReque
 	}()
 	numTags := len(readRequest.GetTagNames())
 	if numTags > 20 { // letters g-z
-		result <- &spiModel.DefaultPlcReadRequestResult{
-			Request: readRequest,
-			Err:     errors.New("Only 20 tags can be handled at once"),
-		}
+		result <- spiModel.NewDefaultPlcReadRequestResult(readRequest, nil, errors.New("Only 20 tags can be handled at once"))
 		return
 	}
 	messages := make(map[string]readWriteModel.CBusMessage)
@@ -74,10 +71,11 @@ func (m *Reader) readSync(ctx context.Context, readRequest apiModel.PlcReadReque
 		message, supportsRead, _, _, err := TagToCBusMessage(tag, nil, m.alphaGenerator, m.messageCodec)
 		switch {
 		case err != nil:
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request: readRequest,
-				Err:     errors.Wrapf(err, "Error encoding cbus message for tag %s", tagName),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrapf(err, "Error encoding cbus message for tag %s", tagName),
+			)
 			return
 		case !supportsRead: // Note this should not be reachable
 			panic("this should not be possible as we always should then get the error above")
@@ -100,19 +98,21 @@ func (m *Reader) readSync(ctx context.Context, readRequest apiModel.PlcReadReque
 	}
 	for tagName, messageToSend := range messages {
 		if err := ctx.Err(); err != nil {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request: readRequest,
-				Err:     err,
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				err,
+			)
 			return
 		}
 		m.createMessageTransactionAndWait(ctx, messageToSend, addResponseCode, tagName, addPlcValue)
 	}
 	readResponse := spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues)
-	result <- &spiModel.DefaultPlcReadRequestResult{
-		Request:  readRequest,
-		Response: readResponse,
-	}
+	result <- spiModel.NewDefaultPlcReadRequestResult(
+		readRequest,
+		readResponse,
+		nil,
+	)
 }
 
 func (m *Reader) createMessageTransactionAndWait(ctx context.Context, messageToSend readWriteModel.CBusMessage, addResponseCode func(name string, responseCode apiModel.PlcResponseCode), tagName string, addPlcValue func(name string, plcValue apiValues.PlcValue)) {
diff --git a/plc4go/internal/cbus/Subscriber.go b/plc4go/internal/cbus/Subscriber.go
index f1c72fa747..c9857a20d1 100644
--- a/plc4go/internal/cbus/Subscriber.go
+++ b/plc4go/internal/cbus/Subscriber.go
@@ -67,11 +67,11 @@ func (m *Subscriber) Subscribe(_ context.Context, subscriptionRequest apiModel.P
 			subscriptionValues[tagName] = NewSubscriptionHandle(m, tagName, internalPlcSubscriptionRequest.GetTag(tagName), internalPlcSubscriptionRequest.GetType(tagName), internalPlcSubscriptionRequest.GetInterval(tagName))
 		}
 
-		result <- &spiModel.DefaultPlcSubscriptionRequestResult{
-			Request:  subscriptionRequest,
-			Response: spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
-			Err:      nil,
-		}
+		result <- spiModel.NewDefaultPlcSubscriptionRequestResult(
+			subscriptionRequest,
+			spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
+			nil,
+		)
 	}()
 	return result
 }
diff --git a/plc4go/internal/cbus/Writer.go b/plc4go/internal/cbus/Writer.go
index 1808d03cf7..2883c0787b 100644
--- a/plc4go/internal/cbus/Writer.go
+++ b/plc4go/internal/cbus/Writer.go
@@ -57,11 +57,11 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
 		}()
 		numTags := len(writeRequest.GetTagNames())
 		if numTags > 20 { // letters g-z
-			result <- &spiModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("Only 20 tags can be handled at once"),
-			}
+			result <- spiModel.NewDefaultPlcWriteRequestResult(
+				writeRequest,
+				nil,
+				errors.New("Only 20 tags can be handled at once"),
+			)
 			return
 		}
 
@@ -71,19 +71,19 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
 			plcValue := writeRequest.GetValue(tagName)
 			message, _, supportsWrite, _, err := TagToCBusMessage(tag, plcValue, m.alphaGenerator, m.messageCodec)
 			if !supportsWrite {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding cbus message for tag %s. Tag is not meant to be written.", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(
+					writeRequest,
+					nil,
+					errors.Wrapf(err, "Error encoding cbus message for tag %s. Tag is not meant to be written.", tagName),
+				)
 				return
 			}
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding cbus message for tag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(
+					writeRequest,
+					nil,
+					errors.Wrapf(err, "Error encoding cbus message for tag %s", tagName),
+				)
 				return
 			}
 			messages[tagName] = message
@@ -97,10 +97,7 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
 		}
 		for tagName, messageToSend := range messages {
 			if err := ctx.Err(); err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request: writeRequest,
-					Err:     err,
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, err)
 				return
 			}
 			tagNameCopy := tagName
@@ -146,10 +143,7 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
 			})
 		}
 		readResponse := spiModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes)
-		result <- &spiModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: readResponse,
-		}
+		result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, readResponse, nil)
 	}()
 	return result
 }
diff --git a/plc4go/internal/eip/Reader.go b/plc4go/internal/eip/Reader.go
index b6f5576310..67dee5b772 100644
--- a/plc4go/internal/eip/Reader.go
+++ b/plc4go/internal/eip/Reader.go
@@ -108,30 +108,33 @@ func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest)
 						log.Trace().Msg("convert response to PLC4X response")
 						readResponse, err := m.ToPlc4xReadResponse(unconnectedDataItem.GetService(), readRequest)
 						if err != nil {
-							result <- &spiModel.DefaultPlcReadRequestResult{
-								Request: readRequest,
-								Err:     errors.Wrap(err, "Error decoding response"),
-							}
+							result <- spiModel.NewDefaultPlcReadRequestResult(
+								readRequest,
+								nil,
+								errors.Wrap(err, "Error decoding response"),
+							)
 							return transaction.EndRequest()
 						}
-						result <- &spiModel.DefaultPlcReadRequestResult{
-							Request:  readRequest,
-							Response: readResponse,
-						}
+						result <- spiModel.NewDefaultPlcReadRequestResult(
+							readRequest,
+							readResponse,
+							nil,
+						)
 						return transaction.EndRequest()
 					},
 					func(err error) error {
-						result <- &spiModel.DefaultPlcReadRequestResult{
-							Request: readRequest,
-							Err:     errors.Wrap(err, "got timeout while waiting for response"),
-						}
+						result <- spiModel.NewDefaultPlcReadRequestResult(
+							readRequest,
+							nil,
+							errors.Wrap(err, "got timeout while waiting for response"),
+						)
 						return transaction.EndRequest()
 					}, time.Second*1); err != nil {
-					result <- &spiModel.DefaultPlcReadRequestResult{
-						Request:  readRequest,
-						Response: nil,
-						Err:      errors.Wrap(err, "error sending message"),
-					}
+					result <- spiModel.NewDefaultPlcReadRequestResult(
+						readRequest,
+						nil,
+						errors.Wrap(err, "error sending message"),
+					)
 					_ = transaction.EndRequest()
 				}
 			})
diff --git a/plc4go/internal/eip/Writer.go b/plc4go/internal/eip/Writer.go
index 8636a8d1d4..6522cec5f3 100644
--- a/plc4go/internal/eip/Writer.go
+++ b/plc4go/internal/eip/Writer.go
@@ -86,20 +86,12 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 			requestPathSize := int8(dataLength / 2)
 			data, err := encodeValue(value, eipTag.GetType(), elements)
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding value for eipTag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding value for eipTag %s", tagName))
 				return
 			}
 			ansi, err := toAnsi(tag)
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding eip ansi for eipTag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding eip ansi for eipTag %s", tagName))
 				return
 			}
 			items[i] = readWriteModel.NewCipWriteRequest(ansi, eipTag.GetType(), elements, data, uint16(requestPathSize))
@@ -174,11 +166,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 							}
 							return transaction.EndRequest()
 						}, time.Second*1); err != nil {
-							result <- &spiModel.DefaultPlcWriteRequestResult{
-								Request:  writeRequest,
-								Response: nil,
-								Err:      errors.Wrap(err, "error sending message"),
-							}
+							result <- spiModel.NewDefaultPlcWriteRequestResult( writeRequest, nil,      errors.Wrap(err, "error sending message"))
 							_ = transaction.EndRequest()
 						}
 					})
@@ -269,11 +257,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 							}
 							return transaction.EndRequest()
 						}, time.Second*1); err != nil {
-							result <- &spiModel.DefaultPlcWriteRequestResult{
-								Request:  writeRequest,
-								Response: nil,
-								Err:      errors.Wrap(err, "error sending message"),
-							}
+							result <- spiModel.NewDefaultPlcWriteRequestResult( writeRequest, nil,      errors.Wrap(err, "error sending message"))
 							_ = transaction.EndRequest()
 						}
 					})
diff --git a/plc4go/internal/knxnetip/Browser.go b/plc4go/internal/knxnetip/Browser.go
index 19d5e84561..88905c36d0 100644
--- a/plc4go/internal/knxnetip/Browser.go
+++ b/plc4go/internal/knxnetip/Browser.go
@@ -103,13 +103,20 @@ func (m Browser) executeDeviceQuery(ctx context.Context, query DeviceQuery, inte
 			// If the request returned a connection, process it,
 			// otherwise just ignore it.
 			if deviceConnection.connection != nil {
-				queryResult := &model.DefaultPlcBrowseItem{
-					Tag: NewDeviceQuery(
+				queryResult := model.NewDefaultPlcBrowseItem(
+					NewDeviceQuery(
 						strconv.Itoa(int(knxAddress.GetMainGroup())),
 						strconv.Itoa(int(knxAddress.GetMiddleGroup())),
 						strconv.Itoa(int(knxAddress.GetSubGroup())),
 					),
-				}
+					"",
+					"",
+					false,
+					false,
+					false,
+					nil,
+					nil,
+				)
 
 				// Pass it to the callback
 				add := true
@@ -398,13 +405,16 @@ func (m Browser) executeCommunicationObjectQuery(ctx context.Context, query Comm
 					&tagType)
 			}
 
-			results = append(results, &model.DefaultPlcBrowseItem{
-				Tag:          tag,
-				Name:         fmt.Sprintf("#%d", comObjectNumber),
-				Readable:     readable,
-				Writable:     writable,
-				Subscribable: subscribable,
-			})
+			results = append(results, model.NewDefaultPlcBrowseItem(
+				tag,
+				fmt.Sprintf("#%d", comObjectNumber),
+				"",
+				readable,
+				writable,
+				subscribable,
+				nil,
+				nil,
+			))
 		}
 	} else if (m.connection.DeviceConnections[knxAddress].deviceDescriptor & 0xFFF0) == uint16(0x0700) /* System7 */ {
 		// For System 7 Devices we unfortunately can't access the information of where the memory address for the
@@ -477,13 +487,16 @@ func (m Browser) executeCommunicationObjectQuery(ctx context.Context, query Comm
 			for _, groupAddress := range groupAddresses {
 				tag := m.getTagForGroupAddress(groupAddress, tagType)
 
-				results = append(results, &model.DefaultPlcBrowseItem{
-					Tag:          tag,
-					Name:         fmt.Sprintf("#%d", comObjectNumber),
-					Readable:     readable,
-					Writable:     writable,
-					Subscribable: subscribable,
-				})
+				results = append(results, model.NewDefaultPlcBrowseItem(
+					tag,
+					fmt.Sprintf("#%d", comObjectNumber),
+					"",
+					readable,
+					writable,
+					subscribable,
+					nil,
+					nil,
+				))
 			}
 		}
 	} else {
diff --git a/plc4go/internal/knxnetip/Discoverer.go b/plc4go/internal/knxnetip/Discoverer.go
index 9bf2841602..2007cdb262 100644
--- a/plc4go/internal/knxnetip/Discoverer.go
+++ b/plc4go/internal/knxnetip/Discoverer.go
@@ -215,13 +215,14 @@ func (d *Discoverer) createDeviceScanDispatcher(udpTransportInstance *udp.Transp
 							continue
 						}
 						deviceName := string(bytes.Trim(searchResponse.GetDibDeviceInfo().GetDeviceFriendlyName(), "\x00"))
-						discoveryEvent := &internalModel.DefaultPlcDiscoveryItem{
-							ProtocolCode:  "knxnet-ip",
-							TransportCode: "udp",
-							TransportUrl:  *remoteUrl,
-							Options:       nil,
-							Name:          deviceName,
-						}
+						discoveryEvent := internalModel.NewDefaultPlcDiscoveryItem(
+							"knxnet-ip",
+							"udp",
+							*remoteUrl,
+							nil,
+							deviceName,
+							nil,
+						)
 						// Pass the event back to the callback
 						callback(discoveryEvent)
 					}
diff --git a/plc4go/internal/knxnetip/Reader.go b/plc4go/internal/knxnetip/Reader.go
index e3f22f7b2d..2fe1a23097 100644
--- a/plc4go/internal/knxnetip/Reader.go
+++ b/plc4go/internal/knxnetip/Reader.go
@@ -163,11 +163,11 @@ func (m Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest) <
 
 		// Assemble the results
 		result := spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues)
-		resultChan <- &spiModel.DefaultPlcReadRequestResult{
-			Request:  readRequest,
-			Response: result,
-			Err:      nil,
-		}
+		resultChan <- spiModel.NewDefaultPlcReadRequestResult(
+			readRequest,
+			result,
+			nil,
+		)
 	}()
 	return resultChan
 }
diff --git a/plc4go/internal/knxnetip/Subscriber.go b/plc4go/internal/knxnetip/Subscriber.go
index 7355e7e544..ae9da83cf2 100644
--- a/plc4go/internal/knxnetip/Subscriber.go
+++ b/plc4go/internal/knxnetip/Subscriber.go
@@ -67,11 +67,11 @@ func (m *Subscriber) Subscribe(ctx context.Context, subscriptionRequest apiModel
 			subscriptionValues[tagName] = NewSubscriptionHandle(m, tagName, internalPlcSubscriptionRequest.GetTag(tagName), tagType, internalPlcSubscriptionRequest.GetInterval(tagName))
 		}
 
-		result <- &spiModel.DefaultPlcSubscriptionRequestResult{
-			Request:  subscriptionRequest,
-			Response: spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
-			Err:      nil,
-		}
+		result <- spiModel.NewDefaultPlcSubscriptionRequestResult(
+			subscriptionRequest,
+			spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
+			nil,
+		)
 	}()
 	return result
 }
diff --git a/plc4go/internal/knxnetip/Writer.go b/plc4go/internal/knxnetip/Writer.go
index 2ee56238e2..7b62ba14d7 100644
--- a/plc4go/internal/knxnetip/Writer.go
+++ b/plc4go/internal/knxnetip/Writer.go
@@ -50,11 +50,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 		tag := writeRequest.GetTag(tagName)
 		groupAddressTag, err := CastToGroupAddressTagFromPlcTag(tag)
 		if err != nil {
-			result <- &plc4goModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("invalid tag item type"),
-			}
+			result <- plc4goModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("invalid tag item type"))
 			return result
 		}
 
@@ -63,11 +59,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 		tagType := groupAddressTag.GetTagType()
 		// TODO: why do we ignore the bytes here?
 		if _, err := readWriteModel.KnxDatapointSerialize(value, *tagType); err != nil {
-			result <- &plc4goModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("error serializing value: " + err.Error()),
-			}
+			result <- plc4goModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("error serializing value: "+err.Error()))
 			return result
 		}
 	}
diff --git a/plc4go/internal/modbus/Reader.go b/plc4go/internal/modbus/Reader.go
index cac63f0b7e..586b840150 100644
--- a/plc4go/internal/modbus/Reader.go
+++ b/plc4go/internal/modbus/Reader.go
@@ -68,11 +68,11 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 		tag := readRequest.GetTag(tagName)
 		modbusTagVar, err := CastToModbusTagFromPlcTag(tag)
 		if err != nil {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "invalid tag item type"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "invalid tag item type"),
+			)
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
@@ -89,18 +89,18 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 		case HoldingRegister:
 			pdu = readWriteModel.NewModbusPDUReadHoldingRegistersRequest(modbusTagVar.Address, numWords)
 		case ExtendedRegister:
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.New("modbus currently doesn't support extended register requests"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.New("modbus currently doesn't support extended register requests"),
+			)
 			return
 		default:
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.Errorf("unsupported tag type %x", modbusTagVar.TagType),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Errorf("unsupported tag type %x", modbusTagVar.TagType),
+			)
 			log.Debug().Msgf("Unsupported tag type %x", modbusTagVar.TagType)
 			return
 		}
@@ -132,30 +132,33 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 			readResponse, err := m.ToPlc4xReadResponse(responseAdu, readRequest)
 
 			if err != nil {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request: readRequest,
-					Err:     errors.Wrap(err, "Error decoding response"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "Error decoding response"),
+				)
 				// TODO: should we return the error here?
 				return nil
 			}
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: readResponse,
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				readResponse,
+				nil,
+			)
 			return nil
 		}, func(err error) error {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request: readRequest,
-				Err:     errors.Wrap(err, "got timeout while waiting for response"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "got timeout while waiting for response"),
+			)
 			return nil
 		}, time.Second*1); err != nil {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "error sending message"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "error sending message"),
+			)
 		}
 	}()
 	return result
diff --git a/plc4go/internal/modbus/Writer.go b/plc4go/internal/modbus/Writer.go
index 73251d2187..a28e718dce 100644
--- a/plc4go/internal/modbus/Writer.go
+++ b/plc4go/internal/modbus/Writer.go
@@ -70,11 +70,11 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 		value := writeRequest.GetValue(tagName)
 		data, err := readWriteModel.DataItemSerialize(value, modbusTag.Datatype, modbusTag.Quantity)
 		if err != nil {
-			result <- &spiModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "error serializing value"),
-			}
+			result <- spiModel.NewDefaultPlcWriteRequestResult(
+				writeRequest,
+				nil,
+				errors.Wrap(err, "error serializing value"),
+			)
 			return
 		}
 
@@ -94,18 +94,10 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 				numWords,
 				data)
 		case ExtendedRegister:
-			result <- &spiModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("modbus currently doesn't support extended register requests"),
-			}
+			result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("modbus currently doesn't support extended register requests"))
 			return
 		default:
-			result <- &spiModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("unsupported tag type"),
-			}
+			result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("unsupported tag type"))
 			return
 		}
 
diff --git a/plc4go/internal/s7/Reader.go b/plc4go/internal/s7/Reader.go
index 8b327f973e..95a50c48e1 100644
--- a/plc4go/internal/s7/Reader.go
+++ b/plc4go/internal/s7/Reader.go
@@ -63,11 +63,11 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 			tag := readRequest.GetTag(tagName)
 			address, err := encodeS7Address(tag)
 			if err != nil {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding s7 address for tag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrapf(err, "Error encoding s7 address for tag %s", tagName),
+				)
 				return
 			}
 			requestItems[i] = readWriteModel.NewS7VarRequestParameterItemAddress(address)
@@ -129,29 +129,32 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 				readResponse, err := m.ToPlc4xReadResponse(payload, readRequest)
 
 				if err != nil {
-					result <- &spiModel.DefaultPlcReadRequestResult{
-						Request: readRequest,
-						Err:     errors.Wrap(err, "Error decoding response"),
-					}
+					result <- spiModel.NewDefaultPlcReadRequestResult(
+						readRequest,
+						nil,
+						errors.Wrap(err, "Error decoding response"),
+					)
 					return transaction.EndRequest()
 				}
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: readResponse,
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					readResponse,
+					nil,
+				)
 				return transaction.EndRequest()
 			}, func(err error) error {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request: readRequest,
-					Err:     errors.Wrap(err, "got timeout while waiting for response"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "got timeout while waiting for response"),
+				)
 				return transaction.EndRequest()
 			}, time.Second*1); err != nil {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "error sending message"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "error sending message"),
+				)
 				_ = transaction.EndRequest()
 			}
 		})
diff --git a/plc4go/internal/s7/Writer.go b/plc4go/internal/s7/Writer.go
index b9a1773c48..870d98f8e1 100644
--- a/plc4go/internal/s7/Writer.go
+++ b/plc4go/internal/s7/Writer.go
@@ -62,21 +62,13 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 			plcValue := writeRequest.GetValue(tagName)
 			s7Address, err := encodeS7Address(tag)
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding s7 address for tag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding s7 address for tag %s", tagName))
 				return
 			}
 			parameterItems[i] = readWriteModel.NewS7VarRequestParameterItemAddress(s7Address)
 			value, err := serializePlcValue(tag, plcValue)
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding value for tag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding value for tag %s", tagName))
 				return
 			}
 			payloadItems[i] = value
@@ -150,11 +142,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 				}
 				return transaction.EndRequest()
 			}, time.Second*1); err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "error sending message"),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "error sending message"))
 				_ = transaction.EndRequest()
 			}
 		})
diff --git a/plc4go/internal/simulated/Reader.go b/plc4go/internal/simulated/Reader.go
index cdb77f7350..11510260a5 100644
--- a/plc4go/internal/simulated/Reader.go
+++ b/plc4go/internal/simulated/Reader.go
@@ -92,11 +92,11 @@ func (r *Reader) Read(_ context.Context, readRequest model.PlcReadRequest) <-cha
 			r.tracer.AddTransactionalTrace(txId, "read", "success")
 		}
 		// Emit the response
-		ch <- &spiModel.DefaultPlcReadRequestResult{
-			Request:  readRequest,
-			Response: spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, responseValues),
-			Err:      nil,
-		}
+		ch <- spiModel.NewDefaultPlcReadRequestResult(
+			readRequest,
+			spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, responseValues),
+			nil,
+		)
 	}()
 	return ch
 }
diff --git a/plc4go/internal/simulated/Subscriber.go b/plc4go/internal/simulated/Subscriber.go
index 4f23a30b69..7bda6bad18 100644
--- a/plc4go/internal/simulated/Subscriber.go
+++ b/plc4go/internal/simulated/Subscriber.go
@@ -23,6 +23,8 @@ import (
 	"context"
 	apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
 	"github.com/apache/plc4x/plc4go/spi"
+	spiModel "github.com/apache/plc4x/plc4go/spi/model"
+	"github.com/pkg/errors"
 )
 
 type Subscriber struct {
@@ -40,13 +42,19 @@ func NewSubscriber(device *Device, options map[string][]string, tracer *spi.Trac
 }
 
 func (r Subscriber) Subscribe(_ context.Context, subscriptionRequest apiModel.PlcSubscriptionRequest) <-chan apiModel.PlcSubscriptionRequestResult {
+	// TODO: handle context
+	result := make(chan apiModel.PlcSubscriptionRequestResult)
+	result <- spiModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, errors.New("Not Implemented"))
 	// TODO: implement me
-	return make(chan apiModel.PlcSubscriptionRequestResult)
+	return result
 }
 
 func (r Subscriber) Unsubscribe(_ context.Context, unsubscriptionRequest apiModel.PlcUnsubscriptionRequest) <-chan apiModel.PlcUnsubscriptionRequestResult {
+	// TODO: handle context
+	result := make(chan apiModel.PlcUnsubscriptionRequestResult, 1)
+	result <- spiModel.NewDefaultPlcUnsubscriptionRequestResult(unsubscriptionRequest, nil, errors.New("Not Implemented"))
 	// TODO: implement me
-	return make(chan apiModel.PlcUnsubscriptionRequestResult)
+	return result
 }
 
 func (r Subscriber) Register(consumer apiModel.PlcSubscriptionEventConsumer, handles []apiModel.PlcSubscriptionHandle) apiModel.PlcConsumerRegistration {
diff --git a/plc4go/internal/simulated/Writer.go b/plc4go/internal/simulated/Writer.go
index 0c2cd25447..9204a7db73 100644
--- a/plc4go/internal/simulated/Writer.go
+++ b/plc4go/internal/simulated/Writer.go
@@ -84,11 +84,7 @@ func (w *Writer) Write(_ context.Context, writeRequest model.PlcWriteRequest) <-
 			w.tracer.AddTransactionalTrace(txId, "write", "success")
 		}
 		// Emit the response
-		ch <- &spiModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: spiModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes),
-			Err:      nil,
-		}
+		ch <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, spiModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes), nil)
 	}()
 	return ch
 }
diff --git a/plc4go/spi/default/DefaultBrowser.go b/plc4go/spi/default/DefaultBrowser.go
index 4688d0aaf1..fc3a7e3e07 100644
--- a/plc4go/spi/default/DefaultBrowser.go
+++ b/plc4go/spi/default/DefaultBrowser.go
@@ -80,11 +80,11 @@ func (m *defaultBrowser) BrowseWithInterceptor(ctx context.Context, browseReques
 			responseCodes[queryName], results[queryName] = m.BrowseQuery(ctx, interceptor, queryName, query)
 		}
 		browseResponse := model.NewDefaultPlcBrowseResponse(browseRequest, results, responseCodes)
-		result <- &model.DefaultPlcBrowseRequestResult{
-			Request:  browseRequest,
-			Response: browseResponse,
-			Err:      nil,
-		}
+		result <- model.NewDefaultPlcBrowseRequestResult(
+			browseRequest,
+			browseResponse,
+			nil,
+		)
 	}()
 	return result
 }
diff --git a/plc4go/spi/model/DefaultPlcReadRequest.go b/plc4go/spi/model/DefaultPlcReadRequest.go
index 23653e5acb..553627e374 100644
--- a/plc4go/spi/model/DefaultPlcReadRequest.go
+++ b/plc4go/spi/model/DefaultPlcReadRequest.go
@@ -148,7 +148,7 @@ func (d *DefaultPlcReadRequest) ExecuteWithContext(ctx context.Context) <-chan a
 		for _, subResultChannel := range subResultChannels {
 			select {
 			case <-ctx.Done():
-				resultChannel <- &DefaultPlcReadRequestResult{Request: d, Err: ctx.Err()}
+				resultChannel <- NewDefaultPlcReadRequestResult(d, nil, ctx.Err())
 				return
 			case subResult := <-subResultChannel:
 				subResults = append(subResults, subResult)