diff --git a/usecases/api/ma_mgcp.go b/usecases/api/ma_mgcp.go index 4387db47..3b491c50 100644 --- a/usecases/api/ma_mgcp.go +++ b/usecases/api/ma_mgcp.go @@ -3,6 +3,7 @@ package api import ( "github.com/enbility/eebus-go/api" spineapi "github.com/enbility/spine-go/api" + "github.com/enbility/spine-go/model" ) // Actor: Monitoring Appliance @@ -66,7 +67,7 @@ type MaMGCPInterface interface { // return values: // - positive values are used for consumption // - negative values are used for production - CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) + CurrentPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) // Scenario 6 @@ -74,7 +75,7 @@ type MaMGCPInterface interface { // // parameters: // - entity: the entity of the device (e.g. SMGW) - VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) + VoltagePerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) // Scenario 7 diff --git a/usecases/api/ma_mpc.go b/usecases/api/ma_mpc.go index 57402cb2..be4b6350 100644 --- a/usecases/api/ma_mpc.go +++ b/usecases/api/ma_mpc.go @@ -3,6 +3,7 @@ package api import ( "github.com/enbility/eebus-go/api" spineapi "github.com/enbility/spine-go/api" + "github.com/enbility/spine-go/model" ) // Actor: Monitoring Appliance @@ -30,7 +31,7 @@ type MaMPCInterface interface { // possible errors: // - ErrDataNotAvailable if no such limit is (yet) available // - and others - PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) + PowerPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) // Scenario 2 @@ -61,7 +62,7 @@ type MaMPCInterface interface { // return values // - positive values are used for consumption // - negative values are used for production - CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) + CurrentPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) // Scenario 4 @@ -69,7 +70,7 @@ type MaMPCInterface interface { // // parameters: // - entity: the entity of the device (e.g. EVSE) - VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) + VoltagePerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) // Scenario 5 diff --git a/usecases/internal/measurement.go b/usecases/internal/measurement.go index 09c72231..81301f6e 100644 --- a/usecases/internal/measurement.go +++ b/usecases/internal/measurement.go @@ -16,7 +16,7 @@ func MeasurementPhaseSpecificDataForFilter( measurementFilter model.MeasurementDescriptionDataType, energyDirection model.EnergyDirectionType, validPhaseNameTypes []model.ElectricalConnectionPhaseNameType, -) ([]float64, error) { +) (map[model.ElectricalConnectionPhaseNameType]float64, error) { measurement, err := client.NewMeasurement(localEntity, remoteEntity) electricalConnection, err1 := client.NewElectricalConnection(localEntity, remoteEntity) if err != nil || err1 != nil { @@ -28,23 +28,37 @@ func MeasurementPhaseSpecificDataForFilter( return nil, api.ErrDataNotAvailable } - var result []float64 + result := make(map[model.ElectricalConnectionPhaseNameType]float64, len(validPhaseNameTypes)) for _, item := range data { if item.Value == nil || item.MeasurementId == nil { continue } - if validPhaseNameTypes != nil { - filter := model.ElectricalConnectionParameterDescriptionDataType{ - MeasurementId: item.MeasurementId, - } - param, err := electricalConnection.GetParameterDescriptionsForFilter(filter) - if err != nil || len(param) == 0 || - param[0].AcMeasuredPhases == nil || - !slices.Contains(validPhaseNameTypes, *param[0].AcMeasuredPhases) { - continue - } + filter := model.ElectricalConnectionParameterDescriptionDataType{ + MeasurementId: item.MeasurementId, + } + param, err := electricalConnection.GetParameterDescriptionsForFilter(filter) + if err != nil || len(param) == 0 { + // error getting parameter description + continue + } + + var phaseName model.ElectricalConnectionPhaseNameType + if param[0].AcMeasuredPhases != nil { + phaseName = *param[0].AcMeasuredPhases + } else if validPhaseNameTypes == nil { + // if we're not filtering by valid phase names, allow acMeasuredPhases to be unset + phaseName = model.ElectricalConnectionPhaseNameTypeNone + } else { + // error getting parameter description + continue + } + + if validPhaseNameTypes != nil && + !slices.Contains(validPhaseNameTypes, phaseName) { + // ignore phase measurements not specified in validPhaseNameTypes + continue } if energyDirection != "" { @@ -70,7 +84,7 @@ func MeasurementPhaseSpecificDataForFilter( value := item.Value.GetValue() - result = append(result, value) + result[phaseName] = value } return result, nil diff --git a/usecases/internal/measurement_test.go b/usecases/internal/measurement_test.go index 05410387..4bcd86eb 100644 --- a/usecases/internal/measurement_test.go +++ b/usecases/internal/measurement_test.go @@ -114,7 +114,7 @@ func (s *InternalSuite) Test_MeasurementPhaseSpecificDataForFilter() { ucapi.PhaseNameMapping, ) assert.Nil(s.T(), err) - assert.Equal(s.T(), 0, len(data)) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{}, data) elParamData := &model.ElectricalConnectionParameterDescriptionListDataType{ ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{ @@ -160,7 +160,7 @@ func (s *InternalSuite) Test_MeasurementPhaseSpecificDataForFilter() { ucapi.PhaseNameMapping, ) assert.Nil(s.T(), err) - assert.Equal(s.T(), []float64{10, 10, 10}, data) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"a": 10, "b": 10, "c": 10}, data) measData = &model.MeasurementListDataType{ MeasurementData: []model.MeasurementDataType{ @@ -196,3 +196,171 @@ func (s *InternalSuite) Test_MeasurementPhaseSpecificDataForFilter() { assert.NotNil(s.T(), err) assert.Nil(s.T(), data) } + +func (s *InternalSuite) Test_MeasurementSinglePhaseSpecificDataForFilter() { + measurementType := model.MeasurementTypeTypePower + commodityType := model.CommodityTypeTypeElectricity + scopeType := model.ScopeTypeTypeACPower + energyDirection := model.EnergyDirectionTypeConsume + + filter := model.MeasurementDescriptionDataType{ + MeasurementType: &measurementType, + CommodityType: &commodityType, + ScopeType: &scopeType, + } + + // set up ElectricalConnection + elDescData := &model.ElectricalConnectionDescriptionListDataType{ + ElectricalConnectionDescriptionData: []model.ElectricalConnectionDescriptionDataType{ + { + ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)), + PositiveEnergyDirection: util.Ptr(model.EnergyDirectionTypeConsume), + }, + }, + } + + elParamData := &model.ElectricalConnectionParameterDescriptionListDataType{ + ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{ + { + ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)), + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeB), + }, + }, + } + + rElFeature := s.remoteDevice.FeatureByEntityTypeAndRole(s.monitoredEntity, model.FeatureTypeTypeElectricalConnection, model.RoleTypeServer) + + _, fErr := rElFeature.UpdateData(true, model.FunctionTypeElectricalConnectionDescriptionListData, elDescData, nil, nil) + assert.Nil(s.T(), fErr) + + _, fErr = rElFeature.UpdateData(true, model.FunctionTypeElectricalConnectionParameterDescriptionListData, elParamData, nil, nil) + assert.Nil(s.T(), fErr) + + descData := &model.MeasurementDescriptionListDataType{ + MeasurementDescriptionData: []model.MeasurementDescriptionDataType{ + { + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + MeasurementType: util.Ptr(model.MeasurementTypeTypePower), + CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), + ScopeType: util.Ptr(model.ScopeTypeTypeACPower), + }, + }, + } + + rFeature := s.remoteDevice.FeatureByEntityTypeAndRole(s.monitoredEntity, model.FeatureTypeTypeMeasurement, model.RoleTypeServer) + _, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementDescriptionListData, descData, nil, nil) + assert.Nil(s.T(), fErr) + + measData := &model.MeasurementListDataType{ + MeasurementData: []model.MeasurementDataType{ + { + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + Value: model.NewScaledNumberType(10), + }, + }, + } + + _, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementListData, measData, nil, nil) + assert.Nil(s.T(), fErr) + + data, err := MeasurementPhaseSpecificDataForFilter( + s.localEntity, + s.monitoredEntity, + filter, + energyDirection, + ucapi.PhaseNameMapping, + ) + assert.Nil(s.T(), err) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"b": 10}, data) + + data, err = MeasurementPhaseSpecificDataForFilter( + s.localEntity, + s.monitoredEntity, + filter, + energyDirection, + nil, + ) + assert.Nil(s.T(), err) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"b": 10}, data) + +} + +func (s *InternalSuite) Test_MeasurementTotalPhaseSpecificDataForFilter() { + measurementType := model.MeasurementTypeTypePower + commodityType := model.CommodityTypeTypeElectricity + scopeType := model.ScopeTypeTypeACPowerTotal + energyDirection := model.EnergyDirectionTypeConsume + + filter := model.MeasurementDescriptionDataType{ + MeasurementType: &measurementType, + CommodityType: &commodityType, + ScopeType: &scopeType, + } + + // set up ElectricalConnection + elDescData := &model.ElectricalConnectionDescriptionListDataType{ + ElectricalConnectionDescriptionData: []model.ElectricalConnectionDescriptionDataType{ + { + ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)), + PositiveEnergyDirection: util.Ptr(model.EnergyDirectionTypeConsume), + }, + }, + } + + elParamData := &model.ElectricalConnectionParameterDescriptionListDataType{ + ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{ + { + ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)), + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeAbc), + }, + }, + } + + rElFeature := s.remoteDevice.FeatureByEntityTypeAndRole(s.monitoredEntity, model.FeatureTypeTypeElectricalConnection, model.RoleTypeServer) + + _, fErr := rElFeature.UpdateData(true, model.FunctionTypeElectricalConnectionDescriptionListData, elDescData, nil, nil) + assert.Nil(s.T(), fErr) + + _, fErr = rElFeature.UpdateData(true, model.FunctionTypeElectricalConnectionParameterDescriptionListData, elParamData, nil, nil) + assert.Nil(s.T(), fErr) + + descData := &model.MeasurementDescriptionListDataType{ + MeasurementDescriptionData: []model.MeasurementDescriptionDataType{ + { + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + MeasurementType: &measurementType, + CommodityType: &commodityType, + ScopeType: &scopeType, + }, + }, + } + + rFeature := s.remoteDevice.FeatureByEntityTypeAndRole(s.monitoredEntity, model.FeatureTypeTypeMeasurement, model.RoleTypeServer) + _, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementDescriptionListData, descData, nil, nil) + assert.Nil(s.T(), fErr) + + measData := &model.MeasurementListDataType{ + MeasurementData: []model.MeasurementDataType{ + { + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + Value: model.NewScaledNumberType(10), + }, + }, + } + + _, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementListData, measData, nil, nil) + assert.Nil(s.T(), fErr) + + data, err := MeasurementPhaseSpecificDataForFilter( + s.localEntity, + s.monitoredEntity, + filter, + energyDirection, + nil, + ) + assert.Nil(s.T(), err) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"abc": 10}, data) + +} diff --git a/usecases/ma/mgcp/public.go b/usecases/ma/mgcp/public.go index 357ad52e..87456b9d 100644 --- a/usecases/ma/mgcp/public.go +++ b/usecases/ma/mgcp/public.go @@ -78,7 +78,13 @@ func (e *MGCP) Power(entity spineapi.EntityRemoteInterface) (float64, error) { return 0, api.ErrDataNotAvailable } - return data[0], nil + for _, k := range data { + // If the Monitored Unit is connected to less than three phases, one of the other combinations like "a" or "ab" are allowed instead of "abc". + // The values "a", "b", and "c" are permitted if and only if only one + return k, nil + } + // unreachable + return 0, api.ErrDataNotAvailable } // Scenario 3 @@ -170,7 +176,7 @@ func (e *MGCP) EnergyConsumed(entity spineapi.EntityRemoteInterface) (float64, e // - ErrDataNotAvailable if no such value is (yet) available // - ErrDataInvalid if the currently available data is invalid and should be ignored // - and others -func (e *MGCP) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) { +func (e *MGCP) CurrentPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) { if !e.IsCompatibleEntityType(entity) { return nil, api.ErrNoCompatibleEntity } @@ -191,7 +197,7 @@ func (e *MGCP) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64 // - ErrDataNotAvailable if no such value is (yet) available // - ErrDataInvalid if the currently available data is invalid and should be ignored // - and others -func (e *MGCP) VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) { +func (e *MGCP) VoltagePerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) { if !e.IsCompatibleEntityType(entity) { return nil, api.ErrNoCompatibleEntity } diff --git a/usecases/ma/mgcp/public_test.go b/usecases/ma/mgcp/public_test.go index 436af816..51a03c49 100644 --- a/usecases/ma/mgcp/public_test.go +++ b/usecases/ma/mgcp/public_test.go @@ -118,6 +118,7 @@ func (s *GcpMGCPSuite) Test_Power() { { ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)), MeasurementId: util.Ptr(model.MeasurementIdType(0)), + AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeA), }, }, } @@ -316,7 +317,7 @@ func (s *GcpMGCPSuite) Test_CurrentPerPhase() { data, err = s.sut.CurrentPerPhase(s.smgwEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), 0, len(data)) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{}, data) elParamData := &model.ElectricalConnectionParameterDescriptionListDataType{ ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{ @@ -356,7 +357,7 @@ func (s *GcpMGCPSuite) Test_CurrentPerPhase() { data, err = s.sut.CurrentPerPhase(s.smgwEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), []float64{10, 10, 10}, data) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"a": 10, "b": 10, "c": 10}, data) } func (s *GcpMGCPSuite) Test_VoltagePerPhase() { @@ -421,7 +422,7 @@ func (s *GcpMGCPSuite) Test_VoltagePerPhase() { data, err = s.sut.VoltagePerPhase(s.smgwEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), 0, len(data)) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{}, data) elParamData := &model.ElectricalConnectionParameterDescriptionListDataType{ ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{ @@ -449,7 +450,7 @@ func (s *GcpMGCPSuite) Test_VoltagePerPhase() { data, err = s.sut.VoltagePerPhase(s.smgwEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), []float64{230, 230, 230}, data) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"a": 230, "b": 230, "c": 230}, data) } func (s *GcpMGCPSuite) Test_Frequency() { diff --git a/usecases/ma/mpc/public.go b/usecases/ma/mpc/public.go index 6df7fbfc..856e9e6b 100644 --- a/usecases/ma/mpc/public.go +++ b/usecases/ma/mpc/public.go @@ -28,6 +28,7 @@ func (e *MPC) Power(entity spineapi.EntityRemoteInterface) (float64, error) { CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), ScopeType: util.Ptr(model.ScopeTypeTypeACPowerTotal), } + // acMeasuredPhases is optional for total active power, therefore we pass nil for validPhaseNameTypes values, err := internal.MeasurementPhaseSpecificDataForFilter(e.LocalEntity, entity, filter, model.EnergyDirectionTypeConsume, nil) if err != nil { return 0, err @@ -36,7 +37,13 @@ func (e *MPC) Power(entity spineapi.EntityRemoteInterface) (float64, error) { return 0, api.ErrDataNotAvailable } - return values[0], nil + for _, k := range values { + // If the Monitored Unit is connected to less than three phases, one of the other combinations like "a" or "ab" are allowed instead of "abc". + // The values "a", "b", and "c" are permitted if and only if only one phase is connected + return k, nil + } + // unreachable + return 0, api.ErrDataNotAvailable } // return the momentary active phase specific power consumption or production per phase @@ -45,7 +52,7 @@ func (e *MPC) Power(entity spineapi.EntityRemoteInterface) (float64, error) { // - ErrDataNotAvailable if no such value is (yet) available // - ErrDataInvalid if the currently available data is invalid and should be ignored // - and others -func (e *MPC) PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) { +func (e *MPC) PowerPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) { if !e.IsCompatibleEntityType(entity) { return nil, api.ErrNoCompatibleEntity } @@ -157,7 +164,7 @@ func (e *MPC) EnergyProduced(entity spineapi.EntityRemoteInterface) (float64, er // - ErrDataNotAvailable if no such value is (yet) available // - ErrDataInvalid if the currently available data is invalid and should be ignored // - and others -func (e *MPC) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) { +func (e *MPC) CurrentPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) { if !e.IsCompatibleEntityType(entity) { return nil, api.ErrNoCompatibleEntity } @@ -178,7 +185,7 @@ func (e *MPC) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, // - ErrDataNotAvailable if no such value is (yet) available // - ErrDataInvalid if the currently available data is invalid and should be ignored // - and others -func (e *MPC) VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) { +func (e *MPC) VoltagePerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) { if !e.IsCompatibleEntityType(entity) { return nil, api.ErrNoCompatibleEntity } diff --git a/usecases/ma/mpc/public_test.go b/usecases/ma/mpc/public_test.go index 45622fe2..ad125958 100644 --- a/usecases/ma/mpc/public_test.go +++ b/usecases/ma/mpc/public_test.go @@ -72,6 +72,7 @@ func (s *MaMPCSuite) Test_Power() { { ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)), MeasurementId: util.Ptr(model.MeasurementIdType(0)), + AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeAbc), }, }, } @@ -146,7 +147,7 @@ func (s *MaMPCSuite) Test_PowerPerPhase() { data, err = s.sut.PowerPerPhase(s.monitoredEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), 0, len(data)) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{}, data) elParamData := &model.ElectricalConnectionParameterDescriptionListDataType{ ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{ @@ -186,7 +187,7 @@ func (s *MaMPCSuite) Test_PowerPerPhase() { data, err = s.sut.PowerPerPhase(s.monitoredEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), []float64{10, 10, 10}, data) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"a": 10, "b": 10, "c": 10}, data) } func (s *MaMPCSuite) Test_EnergyConsumed() { @@ -405,7 +406,7 @@ func (s *MaMPCSuite) Test_CurrentPerPhase() { data, err = s.sut.CurrentPerPhase(s.monitoredEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), 0, len(data)) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{}, data) elParamData := &model.ElectricalConnectionParameterDescriptionListDataType{ ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{ @@ -445,7 +446,7 @@ func (s *MaMPCSuite) Test_CurrentPerPhase() { data, err = s.sut.CurrentPerPhase(s.monitoredEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), []float64{10, 10, 10}, data) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"a": 10, "b": 10, "c": 10}, data) } func (s *MaMPCSuite) Test_VoltagePerPhase() { @@ -510,7 +511,7 @@ func (s *MaMPCSuite) Test_VoltagePerPhase() { data, err = s.sut.VoltagePerPhase(s.monitoredEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), 0, len(data)) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{}, data) elParamData := &model.ElectricalConnectionParameterDescriptionListDataType{ ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{ @@ -538,7 +539,7 @@ func (s *MaMPCSuite) Test_VoltagePerPhase() { data, err = s.sut.VoltagePerPhase(s.monitoredEntity) assert.Nil(s.T(), err) - assert.Equal(s.T(), []float64{230, 230, 230}, data) + assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{"a": 230, "b": 230, "c": 230}, data) } func (s *MaMPCSuite) Test_Frequency() {