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 874e2b9565945d0a01bfbeeb3717df5d2ccfb43c
Author: Sebastian Rühl <[email protected]>
AuthorDate: Fri Mar 24 16:57:33 2023 +0100

    refactor(plc4go/cbus): move map encoded reply to message mapper
---
 plc4go/internal/cbus/CBusMessageFactory.go         | 202 -------------
 .../cbus/{Reader.go => CBusMessageMapper.go}       | 322 ++++++++++-----------
 plc4go/internal/cbus/Reader.go                     | 220 +-------------
 3 files changed, 160 insertions(+), 584 deletions(-)

diff --git a/plc4go/internal/cbus/CBusMessageFactory.go 
b/plc4go/internal/cbus/CBusMessageFactory.go
deleted file mode 100644
index e162c27b28..0000000000
--- a/plc4go/internal/cbus/CBusMessageFactory.go
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package cbus
-
-import (
-       "fmt"
-       "strings"
-
-       "github.com/apache/plc4x/plc4go/pkg/api/model"
-       "github.com/apache/plc4x/plc4go/pkg/api/values"
-       readWriteModel 
"github.com/apache/plc4x/plc4go/protocols/cbus/readwrite/model"
-       "github.com/pkg/errors"
-)
-
-func TagToCBusMessage(tag model.PlcTag, value values.PlcValue, alphaGenerator 
*AlphaGenerator, messageCodec *MessageCodec) (cBusMessage 
readWriteModel.CBusMessage, supportsRead, supportsWrite, supportsSubscribe 
bool, err error) {
-       cbusOptions := messageCodec.cbusOptions
-       requestContext := messageCodec.requestContext
-       switch tagType := tag.(type) {
-       case *statusTag:
-               var statusRequest readWriteModel.StatusRequest
-               switch tagType.statusRequestType {
-               case StatusRequestTypeBinaryState:
-                       statusRequest = 
readWriteModel.NewStatusRequestBinaryState(tagType.application, 0x7A)
-               case StatusRequestTypeLevel:
-                       statusRequest = 
readWriteModel.NewStatusRequestLevel(tagType.application, 
*tagType.startingGroupAddressLabel, 0x73)
-               }
-               //TODO: we need support for bridged commands
-               command := 
readWriteModel.NewCBusPointToMultiPointCommandStatus(statusRequest, 
byte(tagType.application), cbusOptions)
-               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToMultiPoint)
-               cbusCommand := 
readWriteModel.NewCBusCommandPointToMultiPoint(command, header, cbusOptions)
-               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
-
-               cBusMessage, supportsRead, supportsSubscribe = 
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions), 
true, true
-               return
-       case *calRecallTag:
-               calData := readWriteModel.NewCALDataRecall(tagType.parameter, 
tagType.count, readWriteModel.CALCommandTypeContainer_CALCommandRecall, nil, 
requestContext)
-               //TODO: we need support for bridged commands
-               command := 
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000, 
calData, cbusOptions)
-               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToPoint)
-               cbusCommand := 
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
-               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
-
-               cBusMessage, supportsRead = 
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions), 
true
-               return
-       case *calIdentifyTag:
-               calData := readWriteModel.NewCALDataIdentify(tagType.attribute, 
readWriteModel.CALCommandTypeContainer_CALCommandIdentify, nil, requestContext)
-               //TODO: we need support for bridged commands
-               command := 
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000, 
calData, cbusOptions)
-               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToPoint)
-               cbusCommand := 
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
-               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
-
-               cBusMessage, supportsRead = 
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions), 
true
-               return
-       case *calGetstatusTag:
-               calData := 
readWriteModel.NewCALDataGetStatus(tagType.parameter, tagType.count, 
readWriteModel.CALCommandTypeContainer_CALCommandGetStatus, nil, requestContext)
-               //TODO: we need support for bridged commands
-               command := 
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000, 
calData, cbusOptions)
-               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToPoint)
-               cbusCommand := 
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
-               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
-
-               cBusMessage, supportsRead = 
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions), 
true
-               return
-       case *salTag:
-               var salCommand = tagType.salCommand
-               if salCommand == "" {
-                       return nil, false, false, false, errors.New("Empty sal 
command not supported")
-               }
-               var salData readWriteModel.SALData
-               switch tagType.application.ApplicationId() {
-               case readWriteModel.ApplicationId_FREE_USAGE:
-                       panic("Not yet implemented") // TODO: implement
-               case readWriteModel.ApplicationId_TEMPERATURE_BROADCAST:
-                       var temperatureBroadcastData 
readWriteModel.TemperatureBroadcastData
-                       switch salCommand {
-                       case 
readWriteModel.TemperatureBroadcastCommandType_BROADCAST_EVENT.PLC4XEnumName():
-                               if value == nil || !value.IsList() || 
len(value.GetList()) != 2 || !value.GetList()[0].IsByte() || 
!value.GetList()[1].IsByte() {
-                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 2 arguments 
[temperatureGroup,temperatureByte]", salCommand)
-                               }
-                               commandTypeContainer := 
readWriteModel.TemperatureBroadcastCommandTypeContainer_TemperatureBroadcastCommandSetBroadcastEvent1_2Bytes
-                               temperatureGroup := value.GetList()[0].GetByte()
-                               temperatureByte := value.GetList()[1].GetByte()
-                               temperatureBroadcastData = 
readWriteModel.NewTemperatureBroadcastData(commandTypeContainer, 
temperatureGroup, temperatureByte)
-                               supportsWrite = true
-                       default:
-                               return nil, false, false, false, 
errors.Errorf("Unsupported command %s for %s", salCommand, 
tagType.application.ApplicationId())
-                       }
-                       salData = 
readWriteModel.NewSALDataTemperatureBroadcast(temperatureBroadcastData, nil)
-               case readWriteModel.ApplicationId_ROOM_CONTROL_SYSTEM:
-                       panic("Implement me")
-               case
-                       readWriteModel.ApplicationId_LIGHTING,
-                       readWriteModel.ApplicationId_VENTILATION,
-                       readWriteModel.ApplicationId_IRRIGATION_CONTROL,
-                       
readWriteModel.ApplicationId_POOLS_SPAS_PONDS_FOUNTAINS_CONTROL,
-                       readWriteModel.ApplicationId_HEATING,
-                       readWriteModel.ApplicationId_AUDIO_AND_VIDEO,
-                       readWriteModel.ApplicationId_HVAC_ACTUATOR:
-                       var lightingData readWriteModel.LightingData
-                       switch salCommand {
-                       case 
readWriteModel.LightingCommandType_OFF.PLC4XEnumName():
-                               commandTypeContainer := 
readWriteModel.LightingCommandTypeContainer_LightingCommandOff
-                               if value == nil || !value.IsByte() {
-                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 1 arguments [group]", salCommand)
-                               }
-                               group := value.GetByte()
-                               lightingData = 
readWriteModel.NewLightingDataOff(group, commandTypeContainer)
-                               supportsWrite = true
-                       case 
readWriteModel.LightingCommandType_ON.PLC4XEnumName():
-                               commandTypeContainer := 
readWriteModel.LightingCommandTypeContainer_LightingCommandOn
-                               if value == nil || (!value.IsByte() && 
(!value.IsList() || len(value.GetList()) != 1 || value.GetList()[0].IsByte())) {
-                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 1 arguments [group]", salCommand)
-                               }
-                               group := value.GetByte()
-                               lightingData = 
readWriteModel.NewLightingDataOn(group, commandTypeContainer)
-                               supportsWrite = true
-                       case 
readWriteModel.LightingCommandType_RAMP_TO_LEVEL.PLC4XEnumName():
-                               if value == nil || !value.IsList() || 
len(value.GetList()) != 3 || !value.GetList()[0].IsString() || 
!value.GetList()[1].IsByte() || !value.GetList()[2].IsByte() {
-                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 2 arguments [delay,group,level]", salCommand)
-                               }
-                               commandTypeContainer, ok := 
readWriteModel.LightingCommandTypeContainerByName(fmt.Sprintf("LightingCommandRampToLevel_%s",
 value.GetList()[0].GetString()))
-                               if !ok {
-                                       var possibleValues []string
-                                       for _, v := range 
readWriteModel.LightingCommandTypeContainerValues {
-                                               possibleValues = 
append(possibleValues, strings.TrimPrefix(v.String(), 
"LightingCommandRampToLevel_"))
-                                       }
-                                       return nil, false, false, false, 
errors.Errorf("No level found for %s. Possible values %s", 
value.GetList()[0].GetString(), possibleValues)
-                               }
-                               group := value.GetList()[1].GetByte()
-                               level := value.GetList()[2].GetByte()
-                               lightingData = 
readWriteModel.NewLightingDataRampToLevel(group, level, commandTypeContainer)
-                               supportsWrite = true
-                       case 
readWriteModel.LightingCommandType_TERMINATE_RAMP.PLC4XEnumName():
-                               commandTypeContainer := 
readWriteModel.LightingCommandTypeContainer_LightingCommandTerminateRamp
-                               if value == nil || !value.IsByte() {
-                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 1 arguments [group]", salCommand)
-                               }
-                               group := value.GetByte()
-                               lightingData = 
readWriteModel.NewLightingDataTerminateRamp(group, commandTypeContainer)
-                               supportsWrite = true
-                       case 
readWriteModel.LightingCommandType_LABEL.PLC4XEnumName():
-                               panic("Implement me")
-                       default:
-                               return nil, false, false, false, 
errors.Errorf("Unsupported command %s for %s", salCommand, 
tagType.application.ApplicationId())
-                       }
-                       salData = 
readWriteModel.NewSALDataLighting(lightingData, nil)
-               case readWriteModel.ApplicationId_AIR_CONDITIONING:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_TRIGGER_CONTROL:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_ENABLE_CONTROL:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_SECURITY:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_METERING:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_ACCESS_CONTROL:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_CLOCK_AND_TIMEKEEPING:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_TELEPHONY_STATUS_AND_CONTROL:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_MEASUREMENT:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_TESTING:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_MEDIA_TRANSPORT_CONTROL:
-                       panic("Implement me")
-               case readWriteModel.ApplicationId_ERROR_REPORTING:
-                       panic("Implement me")
-               default:
-                       return nil, false, false, false, errors.Errorf("No 
support for %s", tagType.application)
-               }
-               //TODO: we need support for bridged commands
-               command := 
readWriteModel.NewCBusPointToMultiPointCommandNormal(tagType.application, 
salData, 0x00, cbusOptions)
-               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToPoint)
-               cbusCommand := 
readWriteModel.NewCBusCommandPointToMultiPoint(command, header, cbusOptions)
-               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
-               cBusMessage = readWriteModel.NewCBusMessageToServer(request, 
requestContext, cbusOptions)
-               return
-       default:
-               return nil, false, false, false, errors.Errorf("Unsupported 
type %T", tagType)
-       }
-}
diff --git a/plc4go/internal/cbus/Reader.go 
b/plc4go/internal/cbus/CBusMessageMapper.go
similarity index 56%
copy from plc4go/internal/cbus/Reader.go
copy to plc4go/internal/cbus/CBusMessageMapper.go
index 730a433186..6adb4bf4b4 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/CBusMessageMapper.go
@@ -22,195 +22,191 @@ package cbus
 import (
        "context"
        "fmt"
+       "github.com/apache/plc4x/plc4go/spi"
+       spiValues "github.com/apache/plc4x/plc4go/spi/values"
+       "github.com/rs/zerolog/log"
        "strconv"
-       "sync"
-       "time"
+       "strings"
 
        apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
        apiValues "github.com/apache/plc4x/plc4go/pkg/api/values"
        readWriteModel 
"github.com/apache/plc4x/plc4go/protocols/cbus/readwrite/model"
-       "github.com/apache/plc4x/plc4go/spi"
-       spiModel "github.com/apache/plc4x/plc4go/spi/model"
-       spiValues "github.com/apache/plc4x/plc4go/spi/values"
-
        "github.com/pkg/errors"
-       "github.com/rs/zerolog/log"
 )
 
-type Reader struct {
-       alphaGenerator *AlphaGenerator
-       messageCodec   spi.MessageCodec
-       tm             *spi.RequestTransactionManager
-}
+func TagToCBusMessage(tag apiModel.PlcTag, value apiValues.PlcValue, 
alphaGenerator *AlphaGenerator, messageCodec *MessageCodec) (cBusMessage 
readWriteModel.CBusMessage, supportsRead, supportsWrite, supportsSubscribe 
bool, err error) {
+       cbusOptions := messageCodec.cbusOptions
+       requestContext := messageCodec.requestContext
+       switch tagType := tag.(type) {
+       case *statusTag:
+               var statusRequest readWriteModel.StatusRequest
+               switch tagType.statusRequestType {
+               case StatusRequestTypeBinaryState:
+                       statusRequest = 
readWriteModel.NewStatusRequestBinaryState(tagType.application, 0x7A)
+               case StatusRequestTypeLevel:
+                       statusRequest = 
readWriteModel.NewStatusRequestLevel(tagType.application, 
*tagType.startingGroupAddressLabel, 0x73)
+               }
+               //TODO: we need support for bridged commands
+               command := 
readWriteModel.NewCBusPointToMultiPointCommandStatus(statusRequest, 
byte(tagType.application), cbusOptions)
+               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToMultiPoint)
+               cbusCommand := 
readWriteModel.NewCBusCommandPointToMultiPoint(command, header, cbusOptions)
+               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
 
-func NewReader(tpduGenerator *AlphaGenerator, messageCodec spi.MessageCodec, 
tm *spi.RequestTransactionManager) *Reader {
-       return &Reader{
-               alphaGenerator: tpduGenerator,
-               messageCodec:   messageCodec,
-               tm:             tm,
-       }
-}
+               cBusMessage, supportsRead, supportsSubscribe = 
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions), 
true, true
+               return
+       case *calRecallTag:
+               calData := readWriteModel.NewCALDataRecall(tagType.parameter, 
tagType.count, readWriteModel.CALCommandTypeContainer_CALCommandRecall, nil, 
requestContext)
+               //TODO: we need support for bridged commands
+               command := 
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000, 
calData, cbusOptions)
+               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToPoint)
+               cbusCommand := 
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
+               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
 
-func (m *Reader) Read(ctx context.Context, readRequest 
apiModel.PlcReadRequest) <-chan apiModel.PlcReadRequestResult {
-       log.Trace().Msg("Reading")
-       result := make(chan apiModel.PlcReadRequestResult)
-       go m.readSync(ctx, readRequest, result)
-       return result
-}
+               cBusMessage, supportsRead = 
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions), 
true
+               return
+       case *calIdentifyTag:
+               calData := readWriteModel.NewCALDataIdentify(tagType.attribute, 
readWriteModel.CALCommandTypeContainer_CALCommandIdentify, nil, requestContext)
+               //TODO: we need support for bridged commands
+               command := 
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000, 
calData, cbusOptions)
+               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToPoint)
+               cbusCommand := 
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
+               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
 
-func (m *Reader) readSync(ctx context.Context, readRequest 
apiModel.PlcReadRequest, result chan apiModel.PlcReadRequestResult) {
-       numTags := len(readRequest.GetTagNames())
-       if numTags > 20 { // letters g-z
-               result <- &spiModel.DefaultPlcReadRequestResult{
-                       Request:  readRequest,
-                       Response: nil,
-                       Err:      errors.New("Only 20 tags can be handled at 
once"),
-               }
+               cBusMessage, supportsRead = 
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions), 
true
                return
-       }
-       messages := make(map[string]readWriteModel.CBusMessage)
-       for _, tagName := range readRequest.GetTagNames() {
-               tag := readRequest.GetTag(tagName)
-               message, supportsRead, _, _, err := TagToCBusMessage(tag, nil, 
m.alphaGenerator, m.messageCodec.(*MessageCodec))
-               if !supportsRead {
-                       result <- &spiModel.DefaultPlcReadRequestResult{
-                               Request:  readRequest,
-                               Response: nil,
-                               Err:      errors.Wrapf(err, "Error encoding 
cbus message for tag %s. Tag is not meant to be read.", tagName),
-                       }
-                       return
-               }
-               if err != nil {
-                       result <- &spiModel.DefaultPlcReadRequestResult{
-                               Request:  readRequest,
-                               Response: nil,
-                               Err:      errors.Wrapf(err, "Error encoding 
cbus message for tag %s", tagName),
-                       }
-                       return
+       case *calGetstatusTag:
+               calData := 
readWriteModel.NewCALDataGetStatus(tagType.parameter, tagType.count, 
readWriteModel.CALCommandTypeContainer_CALCommandGetStatus, nil, requestContext)
+               //TODO: we need support for bridged commands
+               command := 
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000, 
calData, cbusOptions)
+               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToPoint)
+               cbusCommand := 
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
+               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
+
+               cBusMessage, supportsRead = 
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions), 
true
+               return
+       case *salTag:
+               var salCommand = tagType.salCommand
+               if salCommand == "" {
+                       return nil, false, false, false, errors.New("Empty sal 
command not supported")
                }
-               messages[tagName] = message
-       }
-       responseMu := sync.Mutex{}
-       responseCodes := map[string]apiModel.PlcResponseCode{}
-       addResponseCode := func(name string, responseCode 
apiModel.PlcResponseCode) {
-               responseMu.Lock()
-               defer responseMu.Unlock()
-               responseCodes[name] = responseCode
-       }
-       valueMu := sync.Mutex{}
-       plcValues := map[string]apiValues.PlcValue{}
-       addPlcValue := func(name string, plcValue apiValues.PlcValue) {
-               valueMu.Lock()
-               defer valueMu.Unlock()
-               plcValues[name] = plcValue
-       }
-       for tagName, messageToSend := range messages {
-               if err := ctx.Err(); err != nil {
-                       result <- &spiModel.DefaultPlcReadRequestResult{
-                               Request: readRequest,
-                               Err:     err,
+               var salData readWriteModel.SALData
+               switch tagType.application.ApplicationId() {
+               case readWriteModel.ApplicationId_FREE_USAGE:
+                       panic("Not yet implemented") // TODO: implement
+               case readWriteModel.ApplicationId_TEMPERATURE_BROADCAST:
+                       var temperatureBroadcastData 
readWriteModel.TemperatureBroadcastData
+                       switch salCommand {
+                       case 
readWriteModel.TemperatureBroadcastCommandType_BROADCAST_EVENT.PLC4XEnumName():
+                               if value == nil || !value.IsList() || 
len(value.GetList()) != 2 || !value.GetList()[0].IsByte() || 
!value.GetList()[1].IsByte() {
+                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 2 arguments 
[temperatureGroup,temperatureByte]", salCommand)
+                               }
+                               commandTypeContainer := 
readWriteModel.TemperatureBroadcastCommandTypeContainer_TemperatureBroadcastCommandSetBroadcastEvent1_2Bytes
+                               temperatureGroup := value.GetList()[0].GetByte()
+                               temperatureByte := value.GetList()[1].GetByte()
+                               temperatureBroadcastData = 
readWriteModel.NewTemperatureBroadcastData(commandTypeContainer, 
temperatureGroup, temperatureByte)
+                               supportsWrite = true
+                       default:
+                               return nil, false, false, false, 
errors.Errorf("Unsupported command %s for %s", salCommand, 
tagType.application.ApplicationId())
                        }
-                       return
-               }
-               tagNameCopy := tagName
-               // Start a new request-transaction (Is ended in the 
response-handler)
-               transaction := m.tm.StartTransaction()
-               transaction.Submit(func() {
-                       // Send the  over the wire
-                       log.Trace().Msg("Send ")
-                       if err := m.messageCodec.SendRequest(ctx, 
messageToSend, func(receivedMessage spi.Message) bool {
-                               cbusMessage, ok := 
receivedMessage.(readWriteModel.CBusMessageExactly)
-                               if !ok {
-                                       return false
+                       salData = 
readWriteModel.NewSALDataTemperatureBroadcast(temperatureBroadcastData, nil)
+               case readWriteModel.ApplicationId_ROOM_CONTROL_SYSTEM:
+                       panic("Implement me")
+               case
+                       readWriteModel.ApplicationId_LIGHTING,
+                       readWriteModel.ApplicationId_VENTILATION,
+                       readWriteModel.ApplicationId_IRRIGATION_CONTROL,
+                       
readWriteModel.ApplicationId_POOLS_SPAS_PONDS_FOUNTAINS_CONTROL,
+                       readWriteModel.ApplicationId_HEATING,
+                       readWriteModel.ApplicationId_AUDIO_AND_VIDEO,
+                       readWriteModel.ApplicationId_HVAC_ACTUATOR:
+                       var lightingData readWriteModel.LightingData
+                       switch salCommand {
+                       case 
readWriteModel.LightingCommandType_OFF.PLC4XEnumName():
+                               commandTypeContainer := 
readWriteModel.LightingCommandTypeContainer_LightingCommandOff
+                               if value == nil || !value.IsByte() {
+                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 1 arguments [group]", salCommand)
                                }
-                               messageToClient, ok := 
cbusMessage.(readWriteModel.CBusMessageToClientExactly)
-                               if !ok {
-                                       return false
+                               group := value.GetByte()
+                               lightingData = 
readWriteModel.NewLightingDataOff(group, commandTypeContainer)
+                               supportsWrite = true
+                       case 
readWriteModel.LightingCommandType_ON.PLC4XEnumName():
+                               commandTypeContainer := 
readWriteModel.LightingCommandTypeContainer_LightingCommandOn
+                               if value == nil || (!value.IsByte() && 
(!value.IsList() || len(value.GetList()) != 1 || value.GetList()[0].IsByte())) {
+                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 1 arguments [group]", salCommand)
                                }
-                               // Check if this errored
-                               if _, ok = 
messageToClient.GetReply().(readWriteModel.ServerErrorReplyExactly); ok {
-                                       // This means we must handle this below
-                                       return true
+                               group := value.GetByte()
+                               lightingData = 
readWriteModel.NewLightingDataOn(group, commandTypeContainer)
+                               supportsWrite = true
+                       case 
readWriteModel.LightingCommandType_RAMP_TO_LEVEL.PLC4XEnumName():
+                               if value == nil || !value.IsList() || 
len(value.GetList()) != 3 || !value.GetList()[0].IsString() || 
!value.GetList()[1].IsByte() || !value.GetList()[2].IsByte() {
+                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 2 arguments [delay,group,level]", salCommand)
                                }
-
-                               confirmation, ok := 
messageToClient.GetReply().(readWriteModel.ReplyOrConfirmationConfirmationExactly)
+                               commandTypeContainer, ok := 
readWriteModel.LightingCommandTypeContainerByName(fmt.Sprintf("LightingCommandRampToLevel_%s",
 value.GetList()[0].GetString()))
                                if !ok {
-                                       return false
-                               }
-                               return 
confirmation.GetConfirmation().GetAlpha().GetCharacter() == 
messageToSend.(readWriteModel.CBusMessageToServer).GetRequest().(readWriteModel.RequestCommand).GetAlpha().GetCharacter()
-                       }, func(receivedMessage spi.Message) error {
-                               defer func(transaction *spi.RequestTransaction) 
{
-                                       // This is just to make sure we don't 
forget to close the transaction here
-                                       _ = transaction.EndRequest()
-                               }(transaction)
-                               // Convert the response into an
-                               log.Trace().Msg("convert response to ")
-                               cbusMessage := 
receivedMessage.(readWriteModel.CBusMessage)
-                               messageToClient := 
cbusMessage.(readWriteModel.CBusMessageToClient)
-                               if _, ok := 
messageToClient.GetReply().(readWriteModel.ServerErrorReplyExactly); ok {
-                                       log.Trace().Msg("We got a server 
failure")
-                                       addResponseCode(tagNameCopy, 
apiModel.PlcResponseCode_INVALID_DATA)
-                                       return transaction.EndRequest()
-                               }
-                               replyOrConfirmationConfirmation := 
messageToClient.GetReply().(readWriteModel.ReplyOrConfirmationConfirmationExactly)
-                               if 
!replyOrConfirmationConfirmation.GetConfirmation().GetIsSuccess() {
-                                       var responseCode 
apiModel.PlcResponseCode
-                                       switch 
replyOrConfirmationConfirmation.GetConfirmation().GetConfirmationType() {
-                                       case 
readWriteModel.ConfirmationType_NOT_TRANSMITTED_TO_MANY_RE_TRANSMISSIONS:
-                                               responseCode = 
apiModel.PlcResponseCode_REMOTE_ERROR
-                                       case 
readWriteModel.ConfirmationType_NOT_TRANSMITTED_CORRUPTION:
-                                               responseCode = 
apiModel.PlcResponseCode_INVALID_DATA
-                                       case 
readWriteModel.ConfirmationType_NOT_TRANSMITTED_SYNC_LOSS:
-                                               responseCode = 
apiModel.PlcResponseCode_REMOTE_BUSY
-                                       case 
readWriteModel.ConfirmationType_NOT_TRANSMITTED_TOO_LONG:
-                                               responseCode = 
apiModel.PlcResponseCode_INVALID_DATA
-                                       default:
-                                               return 
transaction.FailRequest(errors.Errorf("Every code should be mapped here: %v", 
replyOrConfirmationConfirmation.GetConfirmation().GetConfirmationType()))
+                                       var possibleValues []string
+                                       for _, v := range 
readWriteModel.LightingCommandTypeContainerValues {
+                                               possibleValues = 
append(possibleValues, strings.TrimPrefix(v.String(), 
"LightingCommandRampToLevel_"))
                                        }
-                                       log.Trace().Msgf("Was no success 
%s:%v", tagNameCopy, responseCode)
-                                       addResponseCode(tagNameCopy, 
responseCode)
-                                       return transaction.EndRequest()
+                                       return nil, false, false, false, 
errors.Errorf("No level found for %s. Possible values %s", 
value.GetList()[0].GetString(), possibleValues)
                                }
-
-                               alpha := 
replyOrConfirmationConfirmation.GetConfirmation().GetAlpha()
-                               // TODO: it could be double confirmed but this 
is not implemented yet
-                               embeddedReply, ok := 
replyOrConfirmationConfirmation.GetEmbeddedReply().(readWriteModel.ReplyOrConfirmationReplyExactly)
-                               if !ok {
-                                       log.Trace().Msgf("Is a confirm only, no 
data. Alpha: %c", alpha.GetCharacter())
-                                       addResponseCode(tagNameCopy, 
apiModel.PlcResponseCode_NOT_FOUND)
-                                       return transaction.EndRequest()
-                               }
-
-                               log.Trace().Msg("Handling confirmed data")
-                               // TODO: check if we can use a 
plcValueSerializer
-                               encodedReply := 
embeddedReply.GetReply().(readWriteModel.ReplyEncodedReply).GetEncodedReply()
-                               if err := m.mapEncodedReply(transaction, 
encodedReply, tagNameCopy, addResponseCode, addPlcValue); err != nil {
-                                       return errors.Wrap(err, "error encoding 
reply")
-                               }
-                               return transaction.EndRequest()
-                       }, func(err error) error {
-                               addResponseCode(tagNameCopy, 
apiModel.PlcResponseCode_REQUEST_TIMEOUT)
-                               return transaction.FailRequest(err)
-                       }, time.Second*1); err != nil {
-                               log.Debug().Err(err).Msgf("Error sending 
message for tag %s", tagNameCopy)
-                               addResponseCode(tagNameCopy, 
apiModel.PlcResponseCode_INTERNAL_ERROR)
-                               if err := 
transaction.FailRequest(errors.Errorf("timeout after %ss", time.Second*1)); err 
!= nil {
-                                       log.Debug().Err(err).Msg("Error failing 
request")
+                               group := value.GetList()[1].GetByte()
+                               level := value.GetList()[2].GetByte()
+                               lightingData = 
readWriteModel.NewLightingDataRampToLevel(group, level, commandTypeContainer)
+                               supportsWrite = true
+                       case 
readWriteModel.LightingCommandType_TERMINATE_RAMP.PLC4XEnumName():
+                               commandTypeContainer := 
readWriteModel.LightingCommandTypeContainer_LightingCommandTerminateRamp
+                               if value == nil || !value.IsByte() {
+                                       return nil, false, false, false, 
errors.Errorf("%s requires exactly 1 arguments [group]", salCommand)
                                }
+                               group := value.GetByte()
+                               lightingData = 
readWriteModel.NewLightingDataTerminateRamp(group, commandTypeContainer)
+                               supportsWrite = true
+                       case 
readWriteModel.LightingCommandType_LABEL.PLC4XEnumName():
+                               panic("Implement me")
+                       default:
+                               return nil, false, false, false, 
errors.Errorf("Unsupported command %s for %s", salCommand, 
tagType.application.ApplicationId())
                        }
-               })
-               if err := transaction.AwaitCompletion(ctx); err != nil {
-                       log.Warn().Err(err).Msg("Error while awaiting 
completion")
+                       salData = 
readWriteModel.NewSALDataLighting(lightingData, nil)
+               case readWriteModel.ApplicationId_AIR_CONDITIONING:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_TRIGGER_CONTROL:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_ENABLE_CONTROL:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_SECURITY:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_METERING:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_ACCESS_CONTROL:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_CLOCK_AND_TIMEKEEPING:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_TELEPHONY_STATUS_AND_CONTROL:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_MEASUREMENT:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_TESTING:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_MEDIA_TRANSPORT_CONTROL:
+                       panic("Implement me")
+               case readWriteModel.ApplicationId_ERROR_REPORTING:
+                       panic("Implement me")
+               default:
+                       return nil, false, false, false, errors.Errorf("No 
support for %s", tagType.application)
                }
-       }
-       readResponse := spiModel.NewDefaultPlcReadResponse(readRequest, 
responseCodes, plcValues)
-       result <- &spiModel.DefaultPlcReadRequestResult{
-               Request:  readRequest,
-               Response: readResponse,
+               //TODO: we need support for bridged commands
+               command := 
readWriteModel.NewCBusPointToMultiPointCommandNormal(tagType.application, 
salData, 0x00, cbusOptions)
+               header := 
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, 
readWriteModel.DestinationAddressType_PointToPoint)
+               cbusCommand := 
readWriteModel.NewCBusCommandPointToMultiPoint(command, header, cbusOptions)
+               request := readWriteModel.NewRequestCommand(cbusCommand, nil, 
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), 
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, 
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), 
cbusOptions)
+               cBusMessage = readWriteModel.NewCBusMessageToServer(request, 
requestContext, cbusOptions)
+               return
+       default:
+               return nil, false, false, false, errors.Errorf("Unsupported 
type %T", tagType)
        }
 }
 
-func (m *Reader) mapEncodedReply(transaction *spi.RequestTransaction, 
encodedReply readWriteModel.EncodedReply, tagName string, addResponseCode 
func(name string, responseCode apiModel.PlcResponseCode), addPlcValue func(name 
string, plcValue apiValues.PlcValue)) error {
+func MapEncodedReply(transaction *spi.RequestTransaction, encodedReply 
readWriteModel.EncodedReply, tagName string, addResponseCode func(name string, 
responseCode apiModel.PlcResponseCode), addPlcValue func(name string, plcValue 
apiValues.PlcValue)) error {
        switch reply := encodedReply.(type) {
        case readWriteModel.EncodedReplyCALReplyExactly:
                calData := reply.GetCalReply().GetCalData()
diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index 730a433186..7b6cf2dfe6 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -21,8 +21,6 @@ package cbus
 
 import (
        "context"
-       "fmt"
-       "strconv"
        "sync"
        "time"
 
@@ -31,8 +29,6 @@ import (
        readWriteModel 
"github.com/apache/plc4x/plc4go/protocols/cbus/readwrite/model"
        "github.com/apache/plc4x/plc4go/spi"
        spiModel "github.com/apache/plc4x/plc4go/spi/model"
-       spiValues "github.com/apache/plc4x/plc4go/spi/values"
-
        "github.com/pkg/errors"
        "github.com/rs/zerolog/log"
 )
@@ -184,7 +180,7 @@ func (m *Reader) readSync(ctx context.Context, readRequest 
apiModel.PlcReadReque
                                log.Trace().Msg("Handling confirmed data")
                                // TODO: check if we can use a 
plcValueSerializer
                                encodedReply := 
embeddedReply.GetReply().(readWriteModel.ReplyEncodedReply).GetEncodedReply()
-                               if err := m.mapEncodedReply(transaction, 
encodedReply, tagNameCopy, addResponseCode, addPlcValue); err != nil {
+                               if err := MapEncodedReply(transaction, 
encodedReply, tagNameCopy, addResponseCode, addPlcValue); err != nil {
                                        return errors.Wrap(err, "error encoding 
reply")
                                }
                                return transaction.EndRequest()
@@ -209,217 +205,3 @@ func (m *Reader) readSync(ctx context.Context, 
readRequest apiModel.PlcReadReque
                Response: readResponse,
        }
 }
-
-func (m *Reader) mapEncodedReply(transaction *spi.RequestTransaction, 
encodedReply readWriteModel.EncodedReply, tagName string, addResponseCode 
func(name string, responseCode apiModel.PlcResponseCode), addPlcValue func(name 
string, plcValue apiValues.PlcValue)) error {
-       switch reply := encodedReply.(type) {
-       case readWriteModel.EncodedReplyCALReplyExactly:
-               calData := reply.GetCalReply().GetCalData()
-               addResponseCode(tagName, apiModel.PlcResponseCode_OK)
-               switch calData := calData.(type) {
-               case readWriteModel.CALDataStatusExactly:
-                       application := calData.GetApplication()
-                       // TODO: verify application... this should be the same
-                       _ = application
-                       blockStart := calData.GetBlockStart()
-                       // TODO: verify application... this should be the same
-                       _ = blockStart
-                       statusBytes := calData.GetStatusBytes()
-                       addResponseCode(tagName, apiModel.PlcResponseCode_OK)
-                       plcListValues := make([]apiValues.PlcValue, 
len(statusBytes)*4)
-                       for i, statusByte := range statusBytes {
-                               plcListValues[i*4+0] = 
spiValues.NewPlcSTRING(statusByte.GetGav0().String())
-                               plcListValues[i*4+1] = 
spiValues.NewPlcSTRING(statusByte.GetGav1().String())
-                               plcListValues[i*4+2] = 
spiValues.NewPlcSTRING(statusByte.GetGav2().String())
-                               plcListValues[i*4+3] = 
spiValues.NewPlcSTRING(statusByte.GetGav3().String())
-                       }
-                       addPlcValue(tagName, 
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
-                               "application": 
spiValues.NewPlcSTRING(application.PLC4XEnumName()),
-                               "blockStart":  spiValues.NewPlcBYTE(blockStart),
-                               "values":      
spiValues.NewPlcList(plcListValues),
-                       }))
-               case readWriteModel.CALDataStatusExtendedExactly:
-                       coding := calData.GetCoding()
-                       // TODO: verify coding... this should be the same
-                       _ = coding
-                       application := calData.GetApplication()
-                       // TODO: verify application... this should be the same
-                       _ = application
-                       blockStart := calData.GetBlockStart()
-                       // TODO: verify application... this should be the same
-                       _ = blockStart
-                       switch coding {
-                       case 
readWriteModel.StatusCoding_BINARY_BY_THIS_SERIAL_INTERFACE:
-                               fallthrough
-                       case readWriteModel.StatusCoding_BINARY_BY_ELSEWHERE:
-                               statusBytes := calData.GetStatusBytes()
-                               addResponseCode(tagName, 
apiModel.PlcResponseCode_OK)
-                               plcListValues := make([]apiValues.PlcValue, 
len(statusBytes)*4)
-                               for i, statusByte := range statusBytes {
-                                       plcListValues[i*4+0] = 
spiValues.NewPlcSTRING(statusByte.GetGav0().String())
-                                       plcListValues[i*4+1] = 
spiValues.NewPlcSTRING(statusByte.GetGav1().String())
-                                       plcListValues[i*4+2] = 
spiValues.NewPlcSTRING(statusByte.GetGav2().String())
-                                       plcListValues[i*4+3] = 
spiValues.NewPlcSTRING(statusByte.GetGav3().String())
-                               }
-                               addPlcValue(tagName, 
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
-                                       "application": 
spiValues.NewPlcSTRING(application.PLC4XEnumName()),
-                                       "blockStart":  
spiValues.NewPlcBYTE(blockStart),
-                                       "values":      
spiValues.NewPlcList(plcListValues),
-                               }))
-                       case 
readWriteModel.StatusCoding_LEVEL_BY_THIS_SERIAL_INTERFACE:
-                               fallthrough
-                       case readWriteModel.StatusCoding_LEVEL_BY_ELSEWHERE:
-                               levelInformation := 
calData.GetLevelInformation()
-                               addResponseCode(tagName, 
apiModel.PlcResponseCode_OK)
-                               plcListValues := make([]apiValues.PlcValue, 
len(levelInformation))
-                               for i, levelInformation := range 
levelInformation {
-                                       switch levelInformation := 
levelInformation.(type) {
-                                       case 
readWriteModel.LevelInformationAbsentExactly:
-                                               plcListValues[i] = 
spiValues.NewPlcSTRING("is absent")
-                                       case 
readWriteModel.LevelInformationCorruptedExactly:
-                                               plcListValues[i] = 
spiValues.NewPlcSTRING("corrupted")
-                                       case 
readWriteModel.LevelInformationNormalExactly:
-                                               plcListValues[i] = 
spiValues.NewPlcUSINT(levelInformation.GetActualLevel())
-                                       default:
-                                               return 
transaction.FailRequest(errors.Errorf("Impossible case %v", levelInformation))
-                                       }
-                               }
-                               addPlcValue(tagName, 
spiValues.NewPlcList(plcListValues))
-                       }
-               case readWriteModel.CALDataIdentifyReplyExactly:
-                       switch identifyReplyCommand := 
calData.GetIdentifyReplyCommand().(type) {
-                       case 
readWriteModel.IdentifyReplyCommandCurrentSenseLevelsExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetCurrentSenseLevels()))
-                       case readWriteModel.IdentifyReplyCommandDelaysExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
-                                       "reStrikeDelay": 
spiValues.NewPlcUSINT(identifyReplyCommand.GetReStrikeDelay()),
-                                       "terminalLevel": 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetTerminalLevels()),
-                               }))
-                       case 
readWriteModel.IdentifyReplyCommandDSIStatusExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
-                                       "channelStatus1":          
spiValues.NewPlcSTRING(identifyReplyCommand.GetChannelStatus1().String()),
-                                       "channelStatus2":          
spiValues.NewPlcSTRING(identifyReplyCommand.GetChannelStatus2().String()),
-                                       "channelStatus3":          
spiValues.NewPlcSTRING(identifyReplyCommand.GetChannelStatus3().String()),
-                                       "channelStatus4":          
spiValues.NewPlcSTRING(identifyReplyCommand.GetChannelStatus4().String()),
-                                       "channelStatus5":          
spiValues.NewPlcSTRING(identifyReplyCommand.GetChannelStatus5().String()),
-                                       "channelStatus6":          
spiValues.NewPlcSTRING(identifyReplyCommand.GetChannelStatus6().String()),
-                                       "channelStatus7":          
spiValues.NewPlcSTRING(identifyReplyCommand.GetChannelStatus7().String()),
-                                       "channelStatus8":          
spiValues.NewPlcSTRING(identifyReplyCommand.GetChannelStatus8().String()),
-                                       "unitStatus":              
spiValues.NewPlcSTRING(identifyReplyCommand.GetUnitStatus().String()),
-                                       "dimmingUCRevisionNumber": 
spiValues.NewPlcUSINT(identifyReplyCommand.GetDimmingUCRevisionNumber()),
-                               }))
-                       case 
readWriteModel.IdentifyReplyCommandExtendedDiagnosticSummaryExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
-                                       "lowApplication":         
spiValues.NewPlcSTRING(identifyReplyCommand.GetLowApplication().String()),
-                                       "highApplication":        
spiValues.NewPlcSTRING(identifyReplyCommand.GetHighApplication().String()),
-                                       "area":                   
spiValues.NewPlcUSINT(identifyReplyCommand.GetArea()),
-                                       "crc":                    
spiValues.NewPlcUINT(identifyReplyCommand.GetCrc()),
-                                       "serialNumber":           
spiValues.NewPlcUDINT(identifyReplyCommand.GetSerialNumber()),
-                                       "networkVoltage":         
spiValues.NewPlcUSINT(identifyReplyCommand.GetNetworkVoltage()),
-                                       "unitInLearnMode":        
spiValues.NewPlcBOOL(identifyReplyCommand.GetUnitInLearnMode()),
-                                       "networkVoltageLow":      
spiValues.NewPlcBOOL(identifyReplyCommand.GetNetworkVoltageLow()),
-                                       "networkVoltageMarginal": 
spiValues.NewPlcBOOL(identifyReplyCommand.GetNetworkVoltageMarginal()),
-                                       "enableChecksumAlarm":    
spiValues.NewPlcBOOL(identifyReplyCommand.GetEnableChecksumAlarm()),
-                                       "outputUnit":             
spiValues.NewPlcBOOL(identifyReplyCommand.GetOutputUnit()),
-                                       "installationMMIError":   
spiValues.NewPlcBOOL(identifyReplyCommand.GetInstallationMMIError()),
-                                       "EEWriteError":           
spiValues.NewPlcBOOL(identifyReplyCommand.GetEEWriteError()),
-                                       "EEChecksumError":        
spiValues.NewPlcBOOL(identifyReplyCommand.GetEEChecksumError()),
-                                       "EEDataError":            
spiValues.NewPlcBOOL(identifyReplyCommand.GetEEDataError()),
-                                       "microReset":             
spiValues.NewPlcBOOL(identifyReplyCommand.GetMicroReset()),
-                                       "commsTxError":           
spiValues.NewPlcBOOL(identifyReplyCommand.GetCommsTxError()),
-                                       "internalStackOverflow":  
spiValues.NewPlcBOOL(identifyReplyCommand.GetInternalStackOverflow()),
-                                       "microPowerReset":        
spiValues.NewPlcBOOL(identifyReplyCommand.GetMicroPowerReset()),
-                               }))
-                       case readWriteModel.IdentifyReplyCommandSummaryExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
-                                       "partName":        
spiValues.NewPlcSTRING(identifyReplyCommand.GetPartName()),
-                                       "unitServiceType": 
spiValues.NewPlcUSINT(identifyReplyCommand.GetUnitServiceType()),
-                                       "version":         
spiValues.NewPlcSTRING(identifyReplyCommand.GetVersion()),
-                               }))
-                       case 
readWriteModel.IdentifyReplyCommandFirmwareVersionExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcSTRING(identifyReplyCommand.GetFirmwareVersion()))
-                       case 
readWriteModel.IdentifyReplyCommandGAVPhysicalAddressesExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetValues()))
-                       case 
readWriteModel.IdentifyReplyCommandGAVValuesCurrentExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetValues()))
-                       case 
readWriteModel.IdentifyReplyCommandGAVValuesStoredExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetValues()))
-                       case 
readWriteModel.IdentifyReplyCommandLogicalAssignmentExactly:
-                               var plcValues []apiValues.PlcValue
-                               for _, logicAssigment := range 
identifyReplyCommand.GetLogicAssigment() {
-                                       plcValues = append(plcValues, 
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
-                                               "greaterOfOrLogic": 
spiValues.NewPlcBOOL(logicAssigment.GetGreaterOfOrLogic()),
-                                               "reStrikeDelay":    
spiValues.NewPlcBOOL(logicAssigment.GetReStrikeDelay()),
-                                               "assignedToGav16":  
spiValues.NewPlcBOOL(logicAssigment.GetAssignedToGav16()),
-                                               "assignedToGav15":  
spiValues.NewPlcBOOL(logicAssigment.GetAssignedToGav15()),
-                                               "assignedToGav14":  
spiValues.NewPlcBOOL(logicAssigment.GetAssignedToGav14()),
-                                               "assignedToGav13":  
spiValues.NewPlcBOOL(logicAssigment.GetAssignedToGav13()),
-                                       }))
-                               }
-                               addPlcValue(tagName, 
spiValues.NewPlcList(plcValues))
-                       case 
readWriteModel.IdentifyReplyCommandManufacturerExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcSTRING(identifyReplyCommand.GetManufacturerName()))
-                       case 
readWriteModel.IdentifyReplyCommandMaximumLevelsExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetMaximumLevels()))
-                       case 
readWriteModel.IdentifyReplyCommandMinimumLevelsExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetMinimumLevels()))
-                       case 
readWriteModel.IdentifyReplyCommandNetworkTerminalLevelsExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetNetworkTerminalLevels()))
-                       case 
readWriteModel.IdentifyReplyCommandNetworkVoltageExactly:
-                               volts := identifyReplyCommand.GetVolts()
-                               voltsFloat, err := strconv.ParseFloat(volts, 0)
-                               if err != nil {
-                                       addResponseCode(tagName, 
apiModel.PlcResponseCode_INTERNAL_ERROR)
-                                       return 
transaction.FailRequest(errors.Wrap(err, "Error parsing volts"))
-                               }
-                               voltsDecimalPlace := 
identifyReplyCommand.GetVoltsDecimalPlace()
-                               voltsDecimalPlaceFloat, err := 
strconv.ParseFloat(voltsDecimalPlace, 0)
-                               if err != nil {
-                                       addResponseCode(tagName, 
apiModel.PlcResponseCode_INTERNAL_ERROR)
-                                       return 
transaction.FailRequest(errors.Wrap(err, "Error parsing volts decimal place"))
-                               }
-                               voltsFloat += voltsDecimalPlaceFloat / 10
-                               addPlcValue(tagName, 
spiValues.NewPlcLREAL(voltsFloat))
-                       case 
readWriteModel.IdentifyReplyCommandOutputUnitSummaryExactly:
-                               unitFlags := identifyReplyCommand.GetUnitFlags()
-                               structContent := map[string]apiValues.PlcValue{
-                                       "unitFlags": 
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
-                                               "assertingNetworkBurden": 
spiValues.NewPlcBOOL(unitFlags.GetAssertingNetworkBurden()),
-                                               "restrikeTimingActive":   
spiValues.NewPlcBOOL(unitFlags.GetRestrikeTimingActive()),
-                                               "remoteOFFInputAsserted": 
spiValues.NewPlcBOOL(unitFlags.GetRemoteOFFInputAsserted()),
-                                               "remoteONInputAsserted":  
spiValues.NewPlcBOOL(unitFlags.GetRemoteONInputAsserted()),
-                                               "localToggleEnabled":     
spiValues.NewPlcBOOL(unitFlags.GetLocalToggleEnabled()),
-                                               "localToggleActiveState": 
spiValues.NewPlcBOOL(unitFlags.GetLocalToggleActiveState()),
-                                               "clockGenerationEnabled": 
spiValues.NewPlcBOOL(unitFlags.GetClockGenerationEnabled()),
-                                               "unitGeneratingClock":    
spiValues.NewPlcBOOL(unitFlags.GetUnitGeneratingClock()),
-                                       }),
-                                       "timeFromLastRecoverOfMainsInSeconds": 
spiValues.NewPlcUSINT(identifyReplyCommand.GetTimeFromLastRecoverOfMainsInSeconds()),
-                               }
-                               if gavStoreEnabledByte1 := 
identifyReplyCommand.GetGavStoreEnabledByte1(); gavStoreEnabledByte1 != nil {
-                                       structContent["gavStoreEnabledByte1"] = 
spiValues.NewPlcUSINT(*gavStoreEnabledByte1)
-                               }
-                               if gavStoreEnabledByte2 := 
identifyReplyCommand.GetGavStoreEnabledByte2(); gavStoreEnabledByte2 != nil {
-                                       structContent["gavStoreEnabledByte2"] = 
spiValues.NewPlcUSINT(*gavStoreEnabledByte2)
-                               }
-                               addPlcValue(tagName, 
spiValues.NewPlcStruct(structContent))
-                       case 
readWriteModel.IdentifyReplyCommandTerminalLevelsExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcRawByteArray(identifyReplyCommand.GetTerminalLevels()))
-                       case readWriteModel.IdentifyReplyCommandTypeExactly:
-                               addPlcValue(tagName, 
spiValues.NewPlcSTRING(identifyReplyCommand.GetUnitType()))
-                       default:
-                               addResponseCode(tagName, 
apiModel.PlcResponseCode_INVALID_DATA)
-                               return 
transaction.FailRequest(errors.Errorf("Unmapped type %T", identifyReplyCommand))
-                       }
-               default:
-                       wbpcb := spiValues.NewWriteBufferPlcValueBased()
-                       if err := 
calData.SerializeWithWriteBuffer(context.Background(), wbpcb); err != nil {
-                               log.Warn().Err(err).Msgf("Unmapped cal data 
type %T. Returning raw to string", calData)
-                               addPlcValue(tagName, 
spiValues.NewPlcSTRING(fmt.Sprintf("%s", calData)))
-                       } else {
-                               addPlcValue(tagName, wbpcb.GetPlcValue())
-                       }
-               }
-       default:
-               return transaction.FailRequest(errors.Errorf("All types should 
be mapped here. Not mapped: %T", reply))
-       }
-       return nil
-}


Reply via email to