blob: f542c78d7393ea0c227096a8dfb744f2b0b77634 [file] [log] [blame]
/*
* 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 (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
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/testutils"
"github.com/apache/plc4x/plc4go/spi/transactions"
"github.com/apache/plc4x/plc4go/spi/utils"
spiValues "github.com/apache/plc4x/plc4go/spi/values"
)
func TestTagToCBusMessage(t *testing.T) {
type args struct {
tag apiModel.PlcTag
value apiValues.PlcValue
alphaGenerator *AlphaGenerator
messageCodec *MessageCodec
}
cbusOptions := readWriteModel.NewCBusOptions(false, false, false, false, false, false, false, false, true)
requestContext := readWriteModel.NewRequestContext(false)
tests := []struct {
name string
args args
wantCBusMessage readWriteModel.CBusMessage
wantSupportsRead bool
wantSupportsWrite bool
wantSupportsSubscribe bool
wantErr bool
}{
{
name: "direct status binary",
args: args{
tag: NewStatusTag(
nil,
StatusRequestTypeBinaryState,
nil,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
1,
),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(
readWriteModel.PriorityClass_Class4,
false,
0,
readWriteModel.DestinationAddressType_PointToMultiPoint,
),
readWriteModel.NewCBusPointToMultiPointCommandStatus(
58,
readWriteModel.NewStatusRequestBinaryState(
122,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status level",
args: args{
tag: NewStatusTag(nil, StatusRequestTypeLevel, func() *byte {
var b byte = 13
return &b
}(), readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToMultiPoint),
readWriteModel.NewCBusPointToMultiPointCommandStatus(
58,
readWriteModel.NewStatusRequestLevel(
115,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
13,
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status binary bridged one bridge",
args: args{
tag: NewStatusTag([]readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(12)}, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(
readWriteModel.NewBridgeAddress(12),
readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(1, 1), []readWriteModel.BridgeAddress{}),
58,
readWriteModel.NewStatusRequestBinaryState(
122,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status binary bridged two bridges",
args: args{
tag: NewStatusTag([]readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(12), readWriteModel.NewBridgeAddress(13)}, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(
readWriteModel.NewBridgeAddress(12),
readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(2, 2), []readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(13)}),
58,
readWriteModel.NewStatusRequestBinaryState(
122,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status binary bridged 6 bridges",
args: args{
tag: NewStatusTag([]readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(12), readWriteModel.NewBridgeAddress(13), readWriteModel.NewBridgeAddress(14), readWriteModel.NewBridgeAddress(15), readWriteModel.NewBridgeAddress(16), readWriteModel.NewBridgeAddress(17)}, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(
readWriteModel.NewBridgeAddress(12),
readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(6, 6), []readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(13), readWriteModel.NewBridgeAddress(14), readWriteModel.NewBridgeAddress(15), readWriteModel.NewBridgeAddress(16), readWriteModel.NewBridgeAddress(17)}),
58,
readWriteModel.NewStatusRequestBinaryState(
122,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status binary bridged 7 bridges",
args: args{
tag: NewStatusTag([]readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(12), readWriteModel.NewBridgeAddress(13), readWriteModel.NewBridgeAddress(14), readWriteModel.NewBridgeAddress(15), readWriteModel.NewBridgeAddress(16), readWriteModel.NewBridgeAddress(17), readWriteModel.NewBridgeAddress(18)}, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "recall",
args: args{
tag: NewCALRecallTag(readWriteModel.NewUnitAddress(1), nil, readWriteModel.Parameter_BAUD_RATE_SELECTOR, 1, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToPointCommandDirect(
0,
readWriteModel.NewCALDataRecall(
requestContext,
readWriteModel.CALCommandTypeContainer_CALCommandRecall,
nil,
readWriteModel.Parameter_BAUD_RATE_SELECTOR,
1,
),
readWriteModel.NewUnitAddress(1),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: true,
wantSupportsSubscribe: false,
},
{
name: "identify",
args: args{
tag: NewCALIdentifyTag(readWriteModel.NewUnitAddress(1), nil, readWriteModel.Attribute_Manufacturer, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToPointCommandDirect(
0,
readWriteModel.NewCALDataIdentify(
requestContext,
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_Manufacturer,
),
readWriteModel.NewUnitAddress(1),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: true,
wantSupportsSubscribe: false,
},
{
name: "getStatus",
args: args{
tag: NewCALGetStatusTag(readWriteModel.NewUnitAddress(1), nil, readWriteModel.Parameter_BAUD_RATE_SELECTOR, 1, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToPointCommandDirect(
0,
readWriteModel.NewCALDataGetStatus(
requestContext,
readWriteModel.CALCommandTypeContainer_CALCommandGetStatus,
nil,
readWriteModel.Parameter_BAUD_RATE_SELECTOR,
1,
),
readWriteModel.NewUnitAddress(1),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: true,
wantSupportsSubscribe: false,
},
// TODO: test sal free usage
{
name: "sal temperature command not found",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_TEMPERATURE_BROADCAST_19, "asd", 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal temperature command event not enough arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_TEMPERATURE_BROADCAST_19, "BROADCAST_EVENT", 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal temperature command event wrong arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_TEMPERATURE_BROADCAST_19, "BROADCAST_EVENT", 1),
value: spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcSTRING("asd"),
spiValues.NewPlcBYTE(3),
}),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal temperature command event",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_TEMPERATURE_BROADCAST_19, "BROADCAST_EVENT", 1),
value: spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcBYTE(2),
spiValues.NewPlcBYTE(3),
}),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_TEMPERATURE_BROADCAST_19,
readWriteModel.NewSALDataTemperatureBroadcast(
nil,
readWriteModel.NewTemperatureBroadcastData(
readWriteModel.TemperatureBroadcastCommandTypeContainer_TemperatureBroadcastCommandSetBroadcastEvent1_2Bytes,
2,
3,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
// TODO: test sal room control system
{
name: "sal lighting command not found",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "asd", 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal lighting command off not enough arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "OFF", 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal lighting command on not enough arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "ON", 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal lighting command ramp to level not enough arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "RAMP_TO_LEVEL", 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal lighting command terminate ramp not enough arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "TERMINATE_RAMP", 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
// TODO: add support for label
{
name: "sal lighting command off wrong arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "OFF", 1),
value: spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcSTRING("asd"),
spiValues.NewPlcBYTE(3),
}),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal lighting command on wrong arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "ON", 1),
value: spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcSTRING("asd"),
spiValues.NewPlcBYTE(3),
}),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal lighting command ramp to level wrong arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "RAMP_TO_LEVEL", 1),
value: spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcSTRING("asd"),
spiValues.NewPlcBYTE(3),
}),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
{
name: "sal lighting command terminate ramp wrong arguments",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "TERMINATE_RAMP", 1),
value: spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcSTRING("asd"),
spiValues.NewPlcBYTE(3),
}),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
// TODO: implement label support command check
{
name: "sal lighting command on",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "ON", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataOn(
readWriteModel.LightingCommandTypeContainer_LightingCommandOn,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
{
name: "sal lighting command off",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "OFF", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataOff(
readWriteModel.LightingCommandTypeContainer_LightingCommandOff,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
{
name: "sal lighting command ramp to level",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "RAMP_TO_LEVEL", 1),
value: spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcSTRING("4Second"),
spiValues.NewPlcBYTE(2),
spiValues.NewPlcBYTE(3),
}),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataRampToLevel(
readWriteModel.LightingCommandTypeContainer_LightingCommandRampToLevel_4Second,
2,
3,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
{
name: "sal lighting command terminate ramp",
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, "TERMINATE_RAMP", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataTerminateRamp(
readWriteModel.LightingCommandTypeContainer_LightingCommandTerminateRamp,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
// TODO: implement label support command
{
name: "sal ventilation command on", // Note: is based on lighting, so we just test "on" here
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_VENTILATION_70, "ON", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_VENTILATION_70,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataOn(
readWriteModel.LightingCommandTypeContainer_LightingCommandOn,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
{
name: "sal irrigation control command on", // Note: is based on lighting, so we just test "on" here
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_IRRIGATION_CONTROL_71, "ON", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_IRRIGATION_CONTROL_71,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataOn(
readWriteModel.LightingCommandTypeContainer_LightingCommandOn,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
{
name: "sal pools spas ponds fountains control command on", // Note: is based on lighting, so we just test "on" here
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_POOLS_SPAS_PONDS_FOUNTAINS_CONTROL_72, "ON", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_POOLS_SPAS_PONDS_FOUNTAINS_CONTROL_72,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataOn(
readWriteModel.LightingCommandTypeContainer_LightingCommandOn,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
{
name: "sal heating on", // Note: is based on lighting, so we just test "on" here
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_HEATING_88, "ON", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_HEATING_88,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataOn(
readWriteModel.LightingCommandTypeContainer_LightingCommandOn,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
{
name: "sal audio and video on", // Note: is based on lighting, so we just test "on" here
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_AUDIO_AND_VIDEO_CD, "ON", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_AUDIO_AND_VIDEO_CD,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataOn(
readWriteModel.LightingCommandTypeContainer_LightingCommandOn,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
{
name: "sal hvac actuator on", // Note: is based on lighting, so we just test "on" here
args: args{
tag: NewSALTag(nil, readWriteModel.ApplicationIdContainer_HVAC_ACTUATOR_74, "ON", 1),
value: spiValues.NewPlcBYTE(2),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
readWriteModel.ApplicationIdContainer_HVAC_ACTUATOR_74,
readWriteModel.NewSALDataLighting(
nil,
readWriteModel.NewLightingDataOn(
readWriteModel.LightingCommandTypeContainer_LightingCommandOn,
2,
),
),
),
),
nil,
readWriteModel.NewAlpha(0),
),
),
wantSupportsRead: false,
wantSupportsWrite: true,
wantSupportsSubscribe: false,
},
// TODO: implement air conditioning
// TODO: implement trigger control
// TODO: implement enable control
// TODO: implement security
// TODO: implement metering
// TODO: implement access control
// TODO: implement clock and timekeeping
// TODO: implement telephony status and control
// TODO: implement measurement
// TODO: implement testing
// TODO: implement media transport control
// TODO: implement error reporting
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotCBusMessage, gotSupportsRead, gotSupportsWrite, gotSupportsSubscribe, err := TagToCBusMessage(tt.args.tag, tt.args.value, tt.args.alphaGenerator, tt.args.messageCodec)
if (err != nil) != tt.wantErr {
t.Errorf("TagToCBusMessage() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !assert.Equal(t, gotCBusMessage, tt.wantCBusMessage) {
gotBox := utils.BoxAnything(gotCBusMessage, utils.WithAsciiBoxName("got"), utils.WithAsciiBoxCharWidth(120))
wantBox := utils.BoxAnything(tt.wantCBusMessage, utils.WithAsciiBoxName("want"), utils.WithAsciiBoxCharWidth(120))
t.Errorf("TagToCBusMessage():\n%s", utils.NewAsciiBoxWriter().BoxSideBySide(gotBox, wantBox))
}
if gotSupportsRead != tt.wantSupportsRead {
t.Errorf("TagToCBusMessage() gotSupportsRead = %v, want %v", gotSupportsRead, tt.wantSupportsRead)
}
if gotSupportsWrite != tt.wantSupportsWrite {
t.Errorf("TagToCBusMessage() gotSupportsWrite = %v, want %v", gotSupportsWrite, tt.wantSupportsWrite)
}
if gotSupportsSubscribe != tt.wantSupportsSubscribe {
t.Errorf("TagToCBusMessage() got SupportsSubscribe = %v, want %v", gotSupportsSubscribe, tt.wantSupportsSubscribe)
}
})
}
}
func Test_producePointToPointCommand(t *testing.T) {
type args struct {
unitAddress readWriteModel.UnitAddress
bridgeAddresses []readWriteModel.BridgeAddress
calData readWriteModel.CALData
}
tests := []struct {
name string
args args
want readWriteModel.CBusCommand
wantErr assert.ErrorAssertionFunc
}{
{
name: "no bridge",
args: args{
unitAddress: readWriteModel.NewUnitAddress(0),
calData: readWriteModel.NewCALDataReset(readWriteModel.NewRequestContext(false), readWriteModel.CALCommandTypeContainer_CALCommandReset, nil),
},
want: readWriteModel.NewCBusCommandPointToPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToPointCommandDirect(
0,
readWriteModel.NewCALDataReset(readWriteModel.NewRequestContext(false), readWriteModel.CALCommandTypeContainer_CALCommandReset, nil),
readWriteModel.NewUnitAddress(0),
),
),
wantErr: assert.NoError,
},
{
name: "one bridge",
args: args{
unitAddress: readWriteModel.NewUnitAddress(0),
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
},
calData: readWriteModel.NewCALDataReset(readWriteModel.NewRequestContext(false), readWriteModel.CALCommandTypeContainer_CALCommandReset, nil),
},
want: readWriteModel.NewCBusCommandPointToPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToPointCommandIndirect(
0,
readWriteModel.NewCALDataReset(readWriteModel.NewRequestContext(false), readWriteModel.CALCommandTypeContainer_CALCommandReset, nil),
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewNetworkRoute(
readWriteModel.NewNetworkProtocolControlInformation(1, 1),
[]readWriteModel.BridgeAddress{},
),
readWriteModel.NewUnitAddress(0),
),
),
wantErr: assert.NoError,
},
{
name: "6 bridges",
args: args{
unitAddress: readWriteModel.NewUnitAddress(0),
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
},
calData: readWriteModel.NewCALDataReset(readWriteModel.NewRequestContext(false), readWriteModel.CALCommandTypeContainer_CALCommandReset, nil),
},
want: readWriteModel.NewCBusCommandPointToPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToPointCommandIndirect(
0,
readWriteModel.NewCALDataReset(readWriteModel.NewRequestContext(false), readWriteModel.CALCommandTypeContainer_CALCommandReset, nil),
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewNetworkRoute(
readWriteModel.NewNetworkProtocolControlInformation(6, 6),
[]readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
},
),
readWriteModel.NewUnitAddress(0),
),
),
wantErr: assert.NoError,
},
{
name: "7 bridges",
args: args{
unitAddress: readWriteModel.NewUnitAddress(0),
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
readWriteModel.NewBridgeAddress(7),
},
},
wantErr: assert.Error,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := producePointToPointCommand(tt.args.unitAddress, tt.args.bridgeAddresses, tt.args.calData)
if !tt.wantErr(t, err, fmt.Sprintf("producePointToPointCommand(%v, %v, %v)", tt.args.unitAddress, tt.args.bridgeAddresses, tt.args.calData)) {
return
}
assert.Equalf(t, tt.want, got, "producePointToPointCommand(%v, %v, %v)", tt.args.unitAddress, tt.args.bridgeAddresses, tt.args.calData)
})
}
}
func Test_producePointToMultiPointCommandStatus(t *testing.T) {
type args struct {
bridgeAddresses []readWriteModel.BridgeAddress
application readWriteModel.ApplicationIdContainer
statusRequest readWriteModel.StatusRequest
}
tests := []struct {
name string
args args
want readWriteModel.CBusCommand
wantErr assert.ErrorAssertionFunc
}{
{
name: "no bridge",
args: args{
statusRequest: readWriteModel.NewStatusRequestBinaryState(9, readWriteModel.ApplicationIdContainer_RESERVED_00),
},
want: readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToMultiPoint),
readWriteModel.NewCBusPointToMultiPointCommandStatus(
0,
readWriteModel.NewStatusRequestBinaryState(
9,
readWriteModel.ApplicationIdContainer_RESERVED_00,
),
),
),
wantErr: assert.NoError,
},
{
name: "one bridge",
args: args{
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
},
statusRequest: readWriteModel.NewStatusRequestBinaryState(9, readWriteModel.ApplicationIdContainer_RESERVED_00),
},
want: readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewNetworkRoute(
readWriteModel.NewNetworkProtocolControlInformation(1, 1),
[]readWriteModel.BridgeAddress{},
),
0,
readWriteModel.NewStatusRequestBinaryState(9, readWriteModel.ApplicationIdContainer_RESERVED_00),
),
),
wantErr: assert.NoError,
},
{
name: "6 bridges",
args: args{
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
},
statusRequest: readWriteModel.NewStatusRequestBinaryState(9, readWriteModel.ApplicationIdContainer_RESERVED_00),
},
want: readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewNetworkRoute(
readWriteModel.NewNetworkProtocolControlInformation(6, 6),
[]readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
},
),
0,
readWriteModel.NewStatusRequestBinaryState(9, readWriteModel.ApplicationIdContainer_RESERVED_00),
),
),
wantErr: assert.NoError,
},
{
name: "7 bridges",
args: args{
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
readWriteModel.NewBridgeAddress(7),
},
statusRequest: readWriteModel.NewStatusRequestBinaryState(9, readWriteModel.ApplicationIdContainer_RESERVED_00),
},
wantErr: assert.Error,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := producePointToMultiPointCommandStatus(tt.args.bridgeAddresses, tt.args.application, tt.args.statusRequest)
if !tt.wantErr(t, err, fmt.Sprintf("producePointToMultiPointCommandStatus(%v, %v, %v)", tt.args.bridgeAddresses, tt.args.application, tt.args.statusRequest)) {
return
}
assert.Equalf(t, tt.want, got, "producePointToMultiPointCommandStatus(%v, %v, %v)", tt.args.bridgeAddresses, tt.args.application, tt.args.statusRequest)
})
}
}
func Test_producePointToMultiPointCommandNormal(t *testing.T) {
type args struct {
bridgeAddresses []readWriteModel.BridgeAddress
application readWriteModel.ApplicationIdContainer
salData readWriteModel.SALData
cbusOptions readWriteModel.CBusOptions
}
tests := []struct {
name string
args args
want readWriteModel.CBusCommand
wantErr assert.ErrorAssertionFunc
}{
{
name: "no bridge",
args: args{
salData: readWriteModel.NewSALDataFreeUsage(nil),
},
want: readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint),
readWriteModel.NewCBusPointToMultiPointCommandNormal(
0,
0,
readWriteModel.NewSALDataFreeUsage(nil),
),
),
wantErr: assert.NoError,
},
{
name: "one bridge",
args: args{
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
},
salData: readWriteModel.NewSALDataFreeUsage(nil),
},
want: readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
readWriteModel.NewCBusPointToPointToMultiPointCommandNormal(
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewNetworkRoute(
readWriteModel.NewNetworkProtocolControlInformation(1, 1),
[]readWriteModel.BridgeAddress{},
),
0,
0,
readWriteModel.NewSALDataFreeUsage(nil),
),
),
wantErr: assert.NoError,
},
{
name: "6 bridges",
args: args{
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
},
salData: readWriteModel.NewSALDataFreeUsage(nil),
},
want: readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
readWriteModel.NewCBusPointToPointToMultiPointCommandNormal(
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewNetworkRoute(
readWriteModel.NewNetworkProtocolControlInformation(6, 6),
[]readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
},
),
0,
0,
readWriteModel.NewSALDataFreeUsage(nil),
),
),
wantErr: assert.NoError,
},
{
name: "7 bridges",
args: args{
bridgeAddresses: []readWriteModel.BridgeAddress{
readWriteModel.NewBridgeAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewBridgeAddress(3),
readWriteModel.NewBridgeAddress(4),
readWriteModel.NewBridgeAddress(5),
readWriteModel.NewBridgeAddress(6),
readWriteModel.NewBridgeAddress(7),
},
},
wantErr: assert.Error,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := producePointToMultiPointCommandNormal(tt.args.bridgeAddresses, tt.args.application, tt.args.salData, tt.args.cbusOptions)
if !tt.wantErr(t, err, fmt.Sprintf("producePointToMultiPointCommandNormal(%v, %v, %v, %v)", tt.args.bridgeAddresses, tt.args.application, tt.args.salData, tt.args.cbusOptions)) {
return
}
assert.Equalf(t, tt.want, got, "producePointToMultiPointCommandNormal(%v, %v, %v, %v)", tt.args.bridgeAddresses, tt.args.application, tt.args.salData, tt.args.cbusOptions)
})
}
}
func TestMapEncodedReply(t *testing.T) {
type args struct {
transaction transactions.RequestTransaction
encodedReply readWriteModel.EncodedReply
tagName string
addResponseCode func(t *testing.T) func(name string, responseCode apiModel.PlcResponseCode)
addPlcValue func(t *testing.T) func(name string, plcValue apiValues.PlcValue)
}
tests := []struct {
name string
args args
setup func(t *testing.T, args *args)
wantErr bool
}{
{
name: "empty input",
args: args{
encodedReply: nil,
tagName: "",
addResponseCode: func(t *testing.T) func(name string, responseCode apiModel.PlcResponseCode) {
return func(name string, responseCode apiModel.PlcResponseCode) {
// NO-OP
}
},
addPlcValue: func(t *testing.T) func(name string, plcValue apiValues.PlcValue) {
return func(name string, plcValue apiValues.PlcValue) {
// NO-OP
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
t.Logf("Submitting No-Op to transaction\n%v", transaction)
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataStatus",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
statusBytes := []readWriteModel.StatusByte{
readWriteModel.NewStatusByte(readWriteModel.GAVState_ON, readWriteModel.GAVState_ERROR, readWriteModel.GAVState_DOES_NOT_EXIST, readWriteModel.GAVState_OFF),
readWriteModel.NewStatusByte(readWriteModel.GAVState_ON, readWriteModel.GAVState_ERROR, readWriteModel.GAVState_DOES_NOT_EXIST, readWriteModel.GAVState_OFF),
}
calDataStatus := readWriteModel.NewCALDataStatus(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandStatus_0Bytes,
nil,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
0,
statusBytes,
)
calReplyShort := readWriteModel.NewCALReplyShort(0, calDataStatus)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyShort)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcStruct(
map[string]apiValues.PlcValue{
"application": spiValues.NewPlcSTRING("LIGHTING_3A"),
"blockStart": spiValues.NewPlcBYTE(0x0),
"values": spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcSTRING("OFF"),
spiValues.NewPlcSTRING("DOES_NOT_EXIST"),
spiValues.NewPlcSTRING("ERROR"),
spiValues.NewPlcSTRING("ON"),
spiValues.NewPlcSTRING("OFF"),
spiValues.NewPlcSTRING("DOES_NOT_EXIST"),
spiValues.NewPlcSTRING("ERROR"),
spiValues.NewPlcSTRING("ON"),
}),
},
),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
t.Logf("Submitting No-Op to transaction %v", transaction)
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
t.Log("No op-ing")
})
t.Logf("Submitted to transaction %v", transaction)
args.transaction = transaction
},
},
{
name: "CALDataStatusExtended (binary)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
statusBytes := []readWriteModel.StatusByte{
readWriteModel.NewStatusByte(readWriteModel.GAVState_ON, readWriteModel.GAVState_ERROR, readWriteModel.GAVState_DOES_NOT_EXIST, readWriteModel.GAVState_OFF),
readWriteModel.NewStatusByte(readWriteModel.GAVState_ON, readWriteModel.GAVState_ERROR, readWriteModel.GAVState_DOES_NOT_EXIST, readWriteModel.GAVState_OFF),
}
calDataStatus := readWriteModel.NewCALDataStatusExtended(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandStatus_0Bytes,
nil,
readWriteModel.StatusCoding_BINARY_BY_THIS_SERIAL_INTERFACE,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
0,
statusBytes,
nil,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataStatus,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(
readWriteModel.NewRequestContext(false),
0,
calReplyLong,
)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcStruct(
map[string]apiValues.PlcValue{
"application": spiValues.NewPlcSTRING("LIGHTING_3A"),
"blockStart": spiValues.NewPlcBYTE(0x0),
"values": spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcSTRING("OFF"),
spiValues.NewPlcSTRING("DOES_NOT_EXIST"),
spiValues.NewPlcSTRING("ERROR"),
spiValues.NewPlcSTRING("ON"),
spiValues.NewPlcSTRING("OFF"),
spiValues.NewPlcSTRING("DOES_NOT_EXIST"),
spiValues.NewPlcSTRING("ERROR"),
spiValues.NewPlcSTRING("ON"),
}),
},
),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataStatusExtended (level)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
levelInformation := []readWriteModel.LevelInformation{
readWriteModel.NewLevelInformationNormal(
13,
readWriteModel.LevelInformationNibblePair_Value_A,
readWriteModel.LevelInformationNibblePair_Value_F,
),
readWriteModel.NewLevelInformationAbsent(13),
readWriteModel.NewLevelInformationCorrupted(13, 14, 15, 16, 17),
}
calDataStatus := readWriteModel.NewCALDataStatusExtended(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandStatus_0Bytes,
nil,
readWriteModel.StatusCoding_LEVEL_BY_THIS_SERIAL_INTERFACE,
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
0,
nil,
levelInformation,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataStatus,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcList(
[]apiValues.PlcValue{
spiValues.NewPlcUSINT(250),
spiValues.NewPlcSTRING("is absent"),
spiValues.NewPlcSTRING("corrupted"),
},
),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReply (sense levels)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandCurrentSenseLevels([]byte{1, 2, 3, 4})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_CurrentSenseLevels,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReply (delays)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandDelays([]byte{1, 2, 3, 4}, 5)
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_Delays,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
"reStrikeDelay": spiValues.NewPlcUSINT(5),
"terminalLevel": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReply (dsi status)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandDSIStatus(
readWriteModel.ChannelStatus_OK,
readWriteModel.ChannelStatus_LAMP_FAULT,
readWriteModel.ChannelStatus_CURRENT_LIMIT_OR_SHORT,
readWriteModel.ChannelStatus_OK,
readWriteModel.ChannelStatus_OK,
readWriteModel.ChannelStatus_OK,
readWriteModel.ChannelStatus_OK,
readWriteModel.ChannelStatus_OK,
readWriteModel.UnitStatus_OK,
12,
)
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
"channelStatus1": spiValues.NewPlcSTRING("OK"),
"channelStatus2": spiValues.NewPlcSTRING("LAMP_FAULT"),
"channelStatus3": spiValues.NewPlcSTRING("CURRENT_LIMIT_OR_SHORT"),
"channelStatus4": spiValues.NewPlcSTRING("OK"),
"channelStatus5": spiValues.NewPlcSTRING("OK"),
"channelStatus6": spiValues.NewPlcSTRING("OK"),
"channelStatus7": spiValues.NewPlcSTRING("OK"),
"channelStatus8": spiValues.NewPlcSTRING("OK"),
"dimmingUCRevisionNumber": spiValues.NewPlcUSINT(12),
"unitStatus": spiValues.NewPlcSTRING("OK"),
}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReply (extended diagnostic summary)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandExtendedDiagnosticSummary(
readWriteModel.ApplicationIdContainer_LIGHTING_3B,
readWriteModel.ApplicationIdContainer_LIGHTING_3C,
12,
13,
14,
15,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
)
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
"lowApplication": spiValues.NewPlcSTRING("LIGHTING_3B"),
"highApplication": spiValues.NewPlcSTRING("LIGHTING_3C"),
"area": spiValues.NewPlcUSINT(12),
"crc": spiValues.NewPlcUINT(13),
"serialNumber": spiValues.NewPlcUDINT(14),
"networkVoltage": spiValues.NewPlcUSINT(15),
"unitInLearnMode": spiValues.NewPlcBOOL(true),
"networkVoltageLow": spiValues.NewPlcBOOL(true),
"networkVoltageMarginal": spiValues.NewPlcBOOL(true),
"enableChecksumAlarm": spiValues.NewPlcBOOL(true),
"outputUnit": spiValues.NewPlcBOOL(true),
"installationMMIError": spiValues.NewPlcBOOL(true),
"EEWriteError": spiValues.NewPlcBOOL(true),
"EEChecksumError": spiValues.NewPlcBOOL(true),
"EEDataError": spiValues.NewPlcBOOL(true),
"microReset": spiValues.NewPlcBOOL(true),
"commsTxError": spiValues.NewPlcBOOL(true),
"internalStackOverflow": spiValues.NewPlcBOOL(true),
"microPowerReset": spiValues.NewPlcBOOL(true),
}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReply (summary)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandSummary("pineapple", 1, "13")
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
"partName": spiValues.NewPlcSTRING("pineapple"),
"unitServiceType": spiValues.NewPlcUSINT(1),
"version": spiValues.NewPlcSTRING("13"),
}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReply (firmware version)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandFirmwareVersion("13")
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcSTRING("13"),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (GAV physical addresses)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandGAVPhysicalAddresses([]byte{1, 2, 3, 4})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (GAV values current)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandGAVValuesCurrent([]byte{1, 2, 3, 4})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (GAV values stored)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandGAVValuesStored([]byte{1, 2, 3, 4})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (logical assignment)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandLogicalAssignment([]readWriteModel.LogicAssignment{
readWriteModel.NewLogicAssignment(true, true, true, true, true, true),
readWriteModel.NewLogicAssignment(true, true, true, true, true, true),
})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcList([]apiValues.PlcValue{
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
"greaterOfOrLogic": spiValues.NewPlcBOOL(true),
"reStrikeDelay": spiValues.NewPlcBOOL(true),
"assignedToGav16": spiValues.NewPlcBOOL(true),
"assignedToGav15": spiValues.NewPlcBOOL(true),
"assignedToGav14": spiValues.NewPlcBOOL(true),
"assignedToGav13": spiValues.NewPlcBOOL(true),
}),
spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
"greaterOfOrLogic": spiValues.NewPlcBOOL(true),
"reStrikeDelay": spiValues.NewPlcBOOL(true),
"assignedToGav16": spiValues.NewPlcBOOL(true),
"assignedToGav15": spiValues.NewPlcBOOL(true),
"assignedToGav14": spiValues.NewPlcBOOL(true),
"assignedToGav13": spiValues.NewPlcBOOL(true),
}),
}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (manufacturer)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandManufacturer("Apache")
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcSTRING("Apache"),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (maximum levels)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandMaximumLevels([]byte{1, 2, 3, 4})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (minimum levels)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandMinimumLevels([]byte{1, 2, 3, 4})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (network terminal levels)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandNetworkTerminalLevels([]byte{1, 2, 3, 4})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (network voltage)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandNetworkVoltage("13.3", "3")
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcLREAL(13.600000000000001),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (output unit summary)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
gavStoreEnabledByte1 := byte(2)
gavStoreEnabledByte2 := byte(3)
command := readWriteModel.NewIdentifyReplyCommandOutputUnitSummary(readWriteModel.NewIdentifyReplyCommandUnitSummary(true, true, true, true, true, true, true, true), &gavStoreEnabledByte1, &gavStoreEnabledByte2, 13)
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
"unitFlags": spiValues.NewPlcStruct(map[string]apiValues.PlcValue{
"assertingNetworkBurden": spiValues.NewPlcBOOL(true),
"restrikeTimingActive": spiValues.NewPlcBOOL(true),
"remoteOFFInputAsserted": spiValues.NewPlcBOOL(true),
"remoteONInputAsserted": spiValues.NewPlcBOOL(true),
"localToggleEnabled": spiValues.NewPlcBOOL(true),
"localToggleActiveState": spiValues.NewPlcBOOL(true),
"clockGenerationEnabled": spiValues.NewPlcBOOL(true),
"unitGeneratingClock": spiValues.NewPlcBOOL(true),
}),
"timeFromLastRecoverOfMainsInSeconds": spiValues.NewPlcUSINT(13),
"gavStoreEnabledByte1": spiValues.NewPlcUSINT(2),
"gavStoreEnabledByte2": spiValues.NewPlcUSINT(3),
}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (terminal levels)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandTerminalLevels([]byte{1, 2, 3, 4})
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcRawByteArray([]byte{1, 2, 3, 4}),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
{
name: "CALDataIdentifyReplyExactly (type)",
args: args{
encodedReply: func() readWriteModel.EncodedReplyCALReply {
command := readWriteModel.NewIdentifyReplyCommandType("chonkers")
calDataIdentify := readWriteModel.NewCALDataIdentifyReply(
readWriteModel.NewRequestContext(false),
readWriteModel.CALCommandTypeContainer_CALCommandIdentify,
nil,
readWriteModel.Attribute_DSIStatus,
command,
)
calReplyLong := readWriteModel.NewCALReplyLong(
0,
calDataIdentify,
0,
readWriteModel.NewUnitAddress(1),
readWriteModel.NewBridgeAddress(2),
readWriteModel.NewSerialInterfaceAddress(3),
nil,
nil,
)
return readWriteModel.NewEncodedReplyCALReply(readWriteModel.NewRequestContext(false), 0, calReplyLong)
}(),
tagName: "someTag",
addResponseCode: func(t *testing.T) func(string, apiModel.PlcResponseCode) {
codes := map[string]apiModel.PlcResponseCode{
"someTag": apiModel.PlcResponseCode_OK,
}
return func(name string, responseCode apiModel.PlcResponseCode) {
if code, ok := codes[name]; ok {
assert.Equal(t, code, responseCode)
} else {
t.Errorf("code for %s not found", name)
}
}
},
addPlcValue: func(t *testing.T) func(string, apiValues.PlcValue) {
values := map[string]apiValues.PlcValue{
"someTag": spiValues.NewPlcSTRING("chonkers"),
}
return func(name string, plcValue apiValues.PlcValue) {
if value, ok := values[name]; ok {
assert.Equal(t, value, plcValue)
} else {
t.Errorf("value for %s not found", name)
}
}
},
},
setup: func(t *testing.T, args *args) {
_options := testutils.EnrichOptionsWithOptionsForTesting(t)
transactionManager := transactions.NewRequestTransactionManager(
1,
_options...,
)
t.Cleanup(func() {
assert.NoError(t, transactionManager.Close())
})
transaction := transactionManager.StartTransaction()
transaction.Submit(func(context.Context, transactions.RequestTransaction) {
// NO-OP
})
args.transaction = transaction
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
testingLogger := testutils.ProduceTestingLogger(t)
if tt.setup != nil {
tt.setup(t, &tt.args)
}
if err := MapEncodedReply(testingLogger, tt.args.transaction, tt.args.encodedReply, tt.args.tagName, tt.args.addResponseCode(t), tt.args.addPlcValue(t)); (err != nil) != tt.wantErr {
t.Errorf("MapEncodedReply() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}